From a2edf18737b57e7154bf3e6f332c5cee0c04a87a Mon Sep 17 00:00:00 2001 From: undefined Date: Mon, 12 Apr 2021 23:02:53 +0800 Subject: [PATCH] core: allow run script via cli --- packages/hydrooj/src/entry/cli.ts | 34 +++++++++++++++++-------- packages/hydrooj/src/entry/master.ts | 9 +------ packages/hydrooj/src/entry/worker.ts | 9 +------ packages/hydrooj/src/model/system.ts | 2 +- packages/hydrooj/src/service/bus.ts | 2 +- packages/hydrooj/src/service/storage.ts | 19 +++++++------- 6 files changed, 36 insertions(+), 39 deletions(-) diff --git a/packages/hydrooj/src/entry/cli.ts b/packages/hydrooj/src/entry/cli.ts index d93cde2f9..1a4d7d806 100644 --- a/packages/hydrooj/src/entry/cli.ts +++ b/packages/hydrooj/src/entry/cli.ts @@ -3,10 +3,11 @@ import { argv } from 'yargs'; import { ObjectID } from 'mongodb'; import { - lib, service, model, - builtinLib, builtinModel, + lib, service, model, script, + builtinLib, builtinModel, builtinScript, } from './common'; import options from '../options'; +import { validate } from '../lib/validator'; import * as bus from '../service/bus'; import db from '../service/db'; @@ -21,8 +22,23 @@ function parseParameters(fn: Function) { return result === null ? [] : result; } +async function runScript(name: string, arg: any) { + if (!global.Hydro.script[name]) return console.error('Script %s not found.', name); + validate(global.Hydro.script[name].validate, arg); + return await global.Hydro.script[name].run(arg, console.info); +} + async function cli() { const [, modelName, func, ...args] = argv._ as [string, string, string, ...any[]]; + if (modelName === 'script') { + let arg: any; + try { + arg = JSON.parse(args.join(' ')); + } catch (e) { + return console.error('Invalid argument'); + } + return await runScript(func, arg); + } if (!global.Hydro.model[modelName]) { return console.error(`Model ${modelName} doesn't exist.`); } @@ -65,22 +81,18 @@ export async function load() { require('../options'); const opts = options(); await db.start(opts); - const modelSystem = require('../model/system'); - const [endPoint, accessKey, secretKey, bucket, region, endPointForUser, endPointForJudge] = modelSystem.getMany([ - 'file.endPoint', 'file.accessKey', 'file.secretKey', 'file.bucket', 'file.region', - 'file.endPointForUser', 'file.endPointForJudge', - ]); - const sopts = { - endPoint, accessKey, secretKey, bucket, region, endPointForUser, endPointForJudge, - }; const storage = require('../service/storage'); - await storage.start(sopts); + await storage.start(); for (const i of builtinLib) require(`../lib/${i}`); await lib(pending, fail); + const systemModel = require('../model/system'); + await systemModel.runConfig(); require('../service/gridfs'); await service(pending, fail); for (const i of builtinModel) require(`../model/${i}`); await model(pending, fail); + for (const i of builtinScript) require(`../script/${i}`); + await script(pending, fail, []); await bus.parallel('app/started'); await cli(); } diff --git a/packages/hydrooj/src/entry/master.ts b/packages/hydrooj/src/entry/master.ts index 6bca3532a..b6b19b252 100644 --- a/packages/hydrooj/src/entry/master.ts +++ b/packages/hydrooj/src/entry/master.ts @@ -57,15 +57,8 @@ export async function load(call: Entry) { await modelSystem.set('file.secretKey', process.env.MINIO_SECRET_KEY); await modelSystem.set('file.endPoint', 'http://localhost:9000/'); } - const [endPoint, accessKey, secretKey, bucket, region, endPointForUser, endPointForJudge] = modelSystem.getMany([ - 'file.endPoint', 'file.accessKey', 'file.secretKey', 'file.bucket', 'file.region', - 'file.endPointForUser', 'file.endPointForJudge', - ]); - const sopts = { - endPoint, accessKey, secretKey, bucket, region, endPointForUser, endPointForJudge, - }; const storage = require('../service/storage'); - await storage.start(sopts); + await storage.start(); require('../service/monitor'); for (const i of builtinModel) require(`../model/${i}`); const scripts = require('../upgrade').default; diff --git a/packages/hydrooj/src/entry/worker.ts b/packages/hydrooj/src/entry/worker.ts index 6b690c38d..2f4e5caf3 100644 --- a/packages/hydrooj/src/entry/worker.ts +++ b/packages/hydrooj/src/entry/worker.ts @@ -34,15 +34,8 @@ export async function load() { const modelSystem = require('../model/system'); await modelSystem.runConfig(); if (argv.loaderDetail) logger.info('finish: config'); - const [endPoint, accessKey, secretKey, bucket, region, endPointForUser, endPointForJudge] = modelSystem.getMany([ - 'file.endPoint', 'file.accessKey', 'file.secretKey', 'file.bucket', 'file.region', - 'file.endPointForUser', 'file.endPointForJudge', - ]); - const sopts = { - endPoint, accessKey, secretKey, bucket, region, endPointForUser, endPointForJudge, - }; const storage = require('../service/storage'); - storage.start(sopts); + await storage.start(); if (argv.loaderDetail) logger.info('finish: storage.connect'); for (const i of builtinLib) { let t; diff --git a/packages/hydrooj/src/model/system.ts b/packages/hydrooj/src/model/system.ts index 077b8eab8..9c1a41327 100644 --- a/packages/hydrooj/src/model/system.ts +++ b/packages/hydrooj/src/model/system.ts @@ -67,7 +67,7 @@ export async function runConfig() { } const config = await coll.find().toArray(); for (const i of config) cache[i._id] = i.value; - bus.emit('database/config'); + await bus.emit('database/config'); } bus.on('system/setting', (args) => { diff --git a/packages/hydrooj/src/service/bus.ts b/packages/hydrooj/src/service/bus.ts index 9aa051167..902b3cb3f 100644 --- a/packages/hydrooj/src/service/bus.ts +++ b/packages/hydrooj/src/service/bus.ts @@ -38,7 +38,7 @@ export interface EventMap extends Record { 'message/run': (command: string) => VoidReturn 'database/connect': (db: Db) => void - 'database/config': () => void + 'database/config': () => VoidReturn 'system/setting': (args: Record) => VoidReturn diff --git a/packages/hydrooj/src/service/storage.ts b/packages/hydrooj/src/service/storage.ts index 318ce3693..80d2cda9c 100644 --- a/packages/hydrooj/src/service/storage.ts +++ b/packages/hydrooj/src/service/storage.ts @@ -79,9 +79,15 @@ class StorageService { private opts: StorageOptions; private replaceWithAlternativeUrlFor: Record<'user' | 'judge', (originalUrl: string) => string>; - async start(opts: StorageOptions) { + async start() { try { - this.opts = opts; + const [endPoint, accessKey, secretKey, bucket, region, endPointForUser, endPointForJudge] = system.getMany([ + 'file.endPoint', 'file.accessKey', 'file.secretKey', 'file.bucket', 'file.region', + 'file.endPointForUser', 'file.endPointForJudge', + ]); + this.opts = { + endPoint, accessKey, secretKey, bucket, region, endPointForUser, endPointForJudge, + }; this.client = new Client({ ...parseMainEndpointUrl(this.opts.endPoint), accessKey: this.opts.accessKey, @@ -103,14 +109,7 @@ class StorageService { logger.warn('Storage init fail. will retry later.'); this.error = e.toString(); setTimeout(async () => { - const [endPoint, accessKey, secretKey, bucket, region, endPointForUser, endPointForJudge] = system.getMany([ - 'file.endPoint', 'file.accessKey', 'file.secretKey', 'file.bucket', 'file.region', - 'file.endPointForUser', 'file.endPointForJudge', - ]); - const sopts = { - endPoint, accessKey, secretKey, bucket, region, endPointForUser, endPointForJudge, - }; - await this.start(sopts); + await this.start(); }, 10000); } }