mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-19 17:38:19 +08:00
core: support pathStyle setting
This commit is contained in:
1 parent
ed8ae6ba69
commit
57850fd53e
12 files changed
+58
-63
No files matched your search
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hydrooj",
|
"name": "hydrooj",
|
||||||
"version": "2.34.2",
|
"version": "2.34.3",
|
||||||
"bin": "bin/hydrooj.js",
|
"bin": "bin/hydrooj.js",
|
||||||
"main": "src/loader",
|
"main": "src/loader",
|
||||||
"module": "src/loader",
|
"module": "src/loader",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
builtinScript, handler, lib, locale, model, script, service, setting, template, uistatic,
|
builtinScript, handler, lib, locale, model, script, service, setting, template, uistatic,
|
||||||
} from './common';
|
} from './common';
|
||||||
|
|
||||||
const logger = new Logger('loader/worker');
|
const logger = new Logger('worker');
|
||||||
const detail = cac().parse().options.loaderDetail;
|
const detail = cac().parse().options.loaderDetail;
|
||||||
const tmpdir = path.resolve(os.tmpdir(), 'hydro');
|
const tmpdir = path.resolve(os.tmpdir(), 'hydro');
|
||||||
|
|
||||||
@@ -105,5 +105,7 @@ export async function load() {
|
|||||||
await modelSystem.set('db.ver', dbVer);
|
await modelSystem.set('db.ver', dbVer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logger.success('Server started');
|
||||||
|
if (process.send) process.send('ready');
|
||||||
return { active, fail };
|
return { active, fail };
|
||||||
}
|
}
|
||||||
@@ -32,10 +32,9 @@ class BlackListModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function ensureIndexes() {
|
bus.once('app/started', () => db.ensureIndexes(
|
||||||
return await coll.createIndex('expireAt', { expireAfterSeconds: 0 });
|
coll,
|
||||||
}
|
{ key: { expireAt: -1 }, name: 'expire', expireAfterSeconds: 0 },
|
||||||
|
));
|
||||||
bus.once('app/started', ensureIndexes);
|
|
||||||
export default BlackListModel;
|
export default BlackListModel;
|
||||||
global.Hydro.model.blacklist = BlackListModel;
|
global.Hydro.model.blacklist = BlackListModel;
|
||||||
@@ -65,13 +65,10 @@ class MessageModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureIndexes() {
|
bus.once('app/started', () => db.ensureIndexes(
|
||||||
return Promise.all([
|
coll,
|
||||||
coll.createIndex({ to: 1, _id: -1 }),
|
{ key: { to: 1, _id: -1 }, name: 'to' },
|
||||||
coll.createIndex({ from: 1, _id: -1 }),
|
{ key: { from: 1, _id: -1 }, name: 'from' },
|
||||||
]);
|
));
|
||||||
}
|
|
||||||
|
|
||||||
bus.once('app/started', ensureIndexes);
|
|
||||||
export default MessageModel;
|
export default MessageModel;
|
||||||
global.Hydro.model.message = MessageModel;
|
global.Hydro.model.message = MessageModel;
|
||||||
@@ -20,12 +20,9 @@ export async function inc(op: string, ident: string, periodSecs: number, maxOper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureIndexes() {
|
bus.once('app/started', () => db.ensureIndexes(
|
||||||
return Promise.all([
|
coll,
|
||||||
coll.createIndex('expireAt', { expireAfterSeconds: 0 }),
|
{ key: { expireAt: -1 }, name: 'expire', expireAfterSeconds: 0 },
|
||||||
coll.createIndex({ op: 1, ident: 1, expireAt: 1 }, { unique: true }),
|
{ key: { op: 1, ident: 1, expireAt: 1 }, name: 'unique', unique: true },
|
||||||
]);
|
));
|
||||||
}
|
|
||||||
|
|
||||||
bus.once('app/started', ensureIndexes);
|
|
||||||
global.Hydro.model.opcount = { inc };
|
global.Hydro.model.opcount = { inc };
|
||||||
@@ -234,14 +234,12 @@ bus.on('domain/delete', (domainId) => Promise.all([
|
|||||||
RecordModel.coll.updateMany({ pdomain: domainId }, { $set: { docId: -1 } }),
|
RecordModel.coll.updateMany({ pdomain: domainId }, { $set: { docId: -1 } }),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
bus.on('app/started', () => {
|
bus.once('app/started', () => db.ensureIndexes(
|
||||||
return db.ensureIndexes(
|
RecordModel.coll,
|
||||||
RecordModel.coll,
|
{ key: { domainId: 1, 'contest.tid': 1, hidden: 1, _id: -1 }, name: 'basic' },
|
||||||
{ key: { domainId: 1, 'contest.tid': 1, hidden: 1, _id: -1 }, name: 'basic' },
|
{ key: { domainId: 1, 'contest.tid': 1, hidden: 1, uid: 1, _id: -1 }, name: 'withUser' },
|
||||||
{ key: { domainId: 1, 'contest.tid': 1, hidden: 1, uid: 1, _id: -1 }, name: 'withUser' },
|
{ key: { domainId: 1, 'contest.tid': 1, hidden: 1, pid: 1, _id: -1 }, name: 'withProblem' },
|
||||||
{ key: { domainId: 1, 'contest.tid': 1, hidden: 1, pid: 1, _id: -1 }, name: 'withProblem' },
|
));
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
export default RecordModel;
|
export default RecordModel;
|
||||||
global.Hydro.model.record = RecordModel;
|
global.Hydro.model.record = RecordModel;
|
||||||
@@ -163,6 +163,7 @@ SystemSetting(
|
|||||||
Setting('setting_file', 'file.secretKey', null, 'password', 'file.secretKey', 'Storage engine secret', FLAG_SECRET),
|
Setting('setting_file', 'file.secretKey', null, 'password', 'file.secretKey', 'Storage engine secret', FLAG_SECRET),
|
||||||
Setting('setting_file', 'file.bucket', 'hydro', 'text', 'file.bucket', 'Storage engine bucket'),
|
Setting('setting_file', 'file.bucket', 'hydro', 'text', 'file.bucket', 'Storage engine bucket'),
|
||||||
Setting('setting_file', 'file.region', 'us-east-1', 'text', 'file.region', 'Storage engine region'),
|
Setting('setting_file', 'file.region', 'us-east-1', 'text', 'file.region', 'Storage engine region'),
|
||||||
|
Setting('setting_file', 'file.pathStyle', true, 'boolean', 'file.pathStyle', 'pathStyle endpoint'),
|
||||||
Setting('setting_file', 'file.endPointForUser', '/fs/', 'text', 'file.endPointForUser', 'EndPoint for user'),
|
Setting('setting_file', 'file.endPointForUser', '/fs/', 'text', 'file.endPointForUser', 'EndPoint for user'),
|
||||||
Setting('setting_file', 'file.endPointForJudge', '/fs/', 'text', 'file.endPointForJudge', 'EndPoint for judge'),
|
Setting('setting_file', 'file.endPointForJudge', '/fs/', 'text', 'file.endPointForJudge', 'EndPoint for judge'),
|
||||||
Setting('setting_smtp', 'smtp.user', null, 'text', 'smtp.user', 'SMTP Username'),
|
Setting('setting_smtp', 'smtp.user', null, 'text', 'smtp.user', 'SMTP Username'),
|
||||||
|
|||||||
@@ -92,13 +92,10 @@ class TokenModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureIndexes() {
|
bus.once('app/started', () => db.ensureIndexes(
|
||||||
return Promise.all([
|
TokenModel.coll,
|
||||||
TokenModel.coll.createIndex({ uid: 1, tokenType: 1, updateAt: -1 }, { sparse: true }),
|
{ key: { uid: 1, tokenType: 1, updateAt: -1 }, name: 'basic', sparse: true },
|
||||||
TokenModel.coll.createIndex('expireAt', { expireAfterSeconds: 0 }),
|
{ key: { expireAt: -1 }, name: 'expire', expireAfterSeconds: 0 },
|
||||||
]);
|
));
|
||||||
}
|
|
||||||
|
|
||||||
bus.once('app/started', ensureIndexes);
|
|
||||||
export default TokenModel;
|
export default TokenModel;
|
||||||
global.Hydro.model.token = TokenModel;
|
global.Hydro.model.token = TokenModel;
|
||||||
@@ -3,8 +3,9 @@ import LRU from 'lru-cache';
|
|||||||
import { Collection } from 'mongodb';
|
import { Collection } from 'mongodb';
|
||||||
import { LoginError, UserAlreadyExistError, UserNotFoundError } from '../error';
|
import { LoginError, UserAlreadyExistError, UserNotFoundError } from '../error';
|
||||||
import {
|
import {
|
||||||
FileInfo,
|
FileInfo, Udict, Udoc,
|
||||||
Udict, Udoc, User as _User } from '../interface';
|
User as _User,
|
||||||
|
} from '../interface';
|
||||||
import pwhash from '../lib/hash.hydro';
|
import pwhash from '../lib/hash.hydro';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
import * as bus from '../service/bus';
|
import * as bus from '../service/bus';
|
||||||
@@ -338,13 +339,10 @@ class UserModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureIndexes() {
|
bus.once('app/started', () => db.ensureIndexes(
|
||||||
return Promise.all([
|
coll,
|
||||||
coll.createIndex('unameLower', { unique: true }),
|
{ key: { unameLower: 1 }, name: 'uname', unique: true },
|
||||||
coll.createIndex('mailLower', { sparse: true }),
|
{ key: { mailLower: 1 }, name: 'mail', unique: true },
|
||||||
]);
|
));
|
||||||
}
|
|
||||||
|
|
||||||
bus.once('app/started', ensureIndexes);
|
|
||||||
export default UserModel;
|
export default UserModel;
|
||||||
global.Hydro.model.user = UserModel;
|
global.Hydro.model.user = UserModel;
|
||||||
@@ -49,15 +49,16 @@ class MongoService implements BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async ensureIndexes<T>(coll: Collection<T>, ...args: IndexSpecification[]) {
|
public async ensureIndexes<T>(coll: Collection<T>, ...args: IndexSpecification[]) {
|
||||||
|
if (process.env.NODE_APP_INSTANCE !== '0') return;
|
||||||
const existed = await coll.listIndexes().toArray();
|
const existed = await coll.listIndexes().toArray();
|
||||||
for (const index of args) {
|
for (const index of args) {
|
||||||
const i = existed.find(t => t.name == index.name);
|
const i = existed.find(t => t.name == index.name || JSON.stringify(t.key) == JSON.stringify(index.key));
|
||||||
if (!i) {
|
if (!i) {
|
||||||
logger.info('Indexing %s.%s with key %o', coll.collectionName, index.name, index.key);
|
logger.info('Indexing %s.%s with key %o', coll.collectionName, index.name, index.key);
|
||||||
await coll.createIndexes([index]);
|
await coll.createIndexes([index]);
|
||||||
} else if (i.v < 2 || JSON.stringify(i.key) !== JSON.stringify(index.key)) {
|
} else if (i.v < 2 || i.name !== index.name || JSON.stringify(i.key) !== JSON.stringify(index.key)) {
|
||||||
logger.info('Re-Index %s.%s with key %o', coll.collectionName, index.name, index.key);
|
logger.info('Re-Index %s.%s with key %o', coll.collectionName, index.name, index.key);
|
||||||
await coll.dropIndex(index.name);
|
await coll.dropIndex(i.name);
|
||||||
await coll.createIndexes([index]);
|
await coll.createIndexes([index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,18 +13,18 @@ import proxy from 'koa-proxies';
|
|||||||
import Router from 'koa-router';
|
import Router from 'koa-router';
|
||||||
import cache from 'koa-static-cache';
|
import cache from 'koa-static-cache';
|
||||||
import {
|
import {
|
||||||
cloneDeep,
|
cloneDeep, Dictionary, filter, isSafeInteger,
|
||||||
Dictionary, filter, isSafeInteger } from 'lodash';
|
} from 'lodash';
|
||||||
import moment from 'moment-timezone';
|
import moment from 'moment-timezone';
|
||||||
import { ObjectID } from 'mongodb';
|
import { ObjectID } from 'mongodb';
|
||||||
import sockjs from 'sockjs';
|
import sockjs from 'sockjs';
|
||||||
import { parseMemoryMB } from '@hydrooj/utils/lib/utils';
|
import { parseMemoryMB } from '@hydrooj/utils/lib/utils';
|
||||||
import {
|
import {
|
||||||
BlacklistedError, CsrfTokenError, HydroError, InvalidOperationError, MethodNotAllowedError,
|
BlacklistedError, CsrfTokenError, HydroError,
|
||||||
NotFoundError, PermissionError,
|
InvalidOperationError, MethodNotAllowedError, NotFoundError,
|
||||||
PrivilegeError,
|
PermissionError, PrivilegeError, SystemError,
|
||||||
SystemError,
|
UserFacingError, UserNotFoundError, ValidationError,
|
||||||
UserFacingError, UserNotFoundError, ValidationError } from '../error';
|
} from '../error';
|
||||||
import { DomainDoc, User } from '../interface';
|
import { DomainDoc, User } from '../interface';
|
||||||
import avatar from '../lib/avatar';
|
import avatar from '../lib/avatar';
|
||||||
import { isContent, isName, isTitle } from '../lib/validator';
|
import { isContent, isName, isTitle } from '../lib/validator';
|
||||||
@@ -890,7 +890,6 @@ export function start() {
|
|||||||
app.use(router.routes()).use(router.allowedMethods());
|
app.use(router.routes()).use(router.allowedMethods());
|
||||||
server.listen(argv.options.port || port);
|
server.listen(argv.options.port || port);
|
||||||
logger.success('Server listening at: %d', argv.options.port || port);
|
logger.success('Server listening at: %d', argv.options.port || port);
|
||||||
if (process.send) process.send('ready'); // PM2 0-sec-down reload
|
|
||||||
started = true;
|
started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ interface StorageOptions {
|
|||||||
secretKey: string;
|
secretKey: string;
|
||||||
bucket: string;
|
bucket: string;
|
||||||
region?: string;
|
region?: string;
|
||||||
|
pathStyle: boolean;
|
||||||
endPointForUser?: string;
|
endPointForUser?: string;
|
||||||
endPointForJudge?: string;
|
endPointForJudge?: string;
|
||||||
}
|
}
|
||||||
@@ -81,15 +82,20 @@ class StorageService {
|
|||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
try {
|
try {
|
||||||
const [endPoint, accessKey, secretKey, bucket, region, endPointForUser, endPointForJudge] = system.getMany([
|
const [
|
||||||
|
endPoint, accessKey, secretKey, bucket, region,
|
||||||
|
pathStyle, endPointForUser, endPointForJudge,
|
||||||
|
] = system.getMany([
|
||||||
'file.endPoint', 'file.accessKey', 'file.secretKey', 'file.bucket', 'file.region',
|
'file.endPoint', 'file.accessKey', 'file.secretKey', 'file.bucket', 'file.region',
|
||||||
'file.endPointForUser', 'file.endPointForJudge',
|
'file.pathStyle', 'file.endPointForUser', 'file.endPointForJudge',
|
||||||
]);
|
]);
|
||||||
this.opts = {
|
this.opts = {
|
||||||
endPoint, accessKey, secretKey, bucket, region, endPointForUser, endPointForJudge,
|
endPoint, accessKey, secretKey, bucket, region,
|
||||||
|
pathStyle, endPointForUser, endPointForJudge,
|
||||||
};
|
};
|
||||||
this.client = new Client({
|
this.client = new Client({
|
||||||
...parseMainEndpointUrl(this.opts.endPoint),
|
...parseMainEndpointUrl(this.opts.endPoint),
|
||||||
|
pathStyle: this.opts.pathStyle,
|
||||||
accessKey: this.opts.accessKey,
|
accessKey: this.opts.accessKey,
|
||||||
secretKey: this.opts.secretKey,
|
secretKey: this.opts.secretKey,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in new issue
Block a user