core: support pathStyle setting

This commit is contained in:
undefined committed 2021-09-11 01:16:23 +08:00
1 parent ed8ae6ba69
commit 57850fd53e
12 files changed
+54 -59

No files matched your search

+1 -1
View File
@@ -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",
+3 -1
View File
@@ -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 };
} }
+4 -5
View File
@@ -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;
+5 -8
View File
@@ -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;
+5 -8
View File
@@ -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 };
+2 -4
View File
@@ -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;
+1
View File
@@ -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'),
+5 -8
View File
@@ -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;
+8 -10
View File
@@ -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;
+4 -3
View File
@@ -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]);
} }
} }
+7 -8
View File
@@ -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;
} }
+9 -3
View File
@@ -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,
}); });