diff --git a/install/install.ts b/install/install.ts index ea696a83f..da802e8ad 100644 --- a/install/install.ts +++ b/install/install.ts @@ -520,6 +520,7 @@ ${nixConfBase}`); skip: () => migration !== 'hustoj', silent: true, operations: [ + 'pm2 restart hydrooj', () => { const dbInc = readFileSync('/home/judge/src/web/include/db_info.inc.php', 'utf-8'); const l = dbInc.split('\n'); diff --git a/packages/migrate/index.ts b/packages/migrate/index.ts index 02bf5ff51..827fad78d 100644 --- a/packages/migrate/index.ts +++ b/packages/migrate/index.ts @@ -1,10 +1,20 @@ import crypto from 'crypto'; import { Context, md5, Schema, sha1, + SystemError, + SystemModel, } from 'hydrooj'; const RE_MD5 = /^[\da-f]{32}$/; +function checkLock(innerCall) { + return async (args) => { + const cur = await SystemModel.get('migrate.lock'); + if (cur) throw new SystemError(`migrate lock already exists: ${cur}, possible another migration is running`); + return innerCall(args); + }; +} + export function apply(ctx: Context) { ctx.addScript( 'migrateHustoj', 'migrate from hustoj', @@ -19,7 +29,7 @@ export function apply(ctx: Context) { dataDir: Schema.string().required(), uploadDir: Schema.string().default('/home/judge/src/web/upload/'), }), - (...args) => require('./scripts/hustoj').run(...args), + checkLock((...args) => require('./scripts/hustoj').run(...args)), ); ctx.addScript( 'migrateSyzoj', 'migrate from syzoj', @@ -33,7 +43,7 @@ export function apply(ctx: Context) { dataDir: Schema.string().default('/opt/syzoj/web/uploads'), randomMail: Schema.union(['never', 'needed', 'always']).default('never'), }), - (...args) => require('./scripts/syzoj').run(...args), + checkLock((...args) => require('./scripts/syzoj').run(...args)), ); ctx.addScript( 'migrateVijos', 'migrate from vijos', @@ -44,7 +54,7 @@ export function apply(ctx: Context) { username: Schema.string().required(), password: Schema.string().required(), }), - (...args) => require('./scripts/vijos').run(...args), + checkLock((...args) => require('./scripts/vijos').run(...args)), ); ctx.addScript( 'migrateUniversaloj', 'migrate from universaloj', @@ -57,7 +67,7 @@ export function apply(ctx: Context) { domainId: Schema.string().default('system'), dataDir: Schema.string().required(), }), - (...args) => require('./scripts/universaloj').run(...args), + checkLock((...args) => require('./scripts/universaloj').run(...args)), ); ctx.addScript( 'migratePoj', 'migrate from poj', @@ -72,14 +82,14 @@ export function apply(ctx: Context) { dataDir: Schema.string().required(), imageDir: Schema.string().required(), }), - (...args) => require('./scripts/poj').run(...args), + checkLock((...args) => require('./scripts/poj').run(...args)), ); ctx.provideModule('hash', 'hust', ($password, $saved) => { $password = md5($password); if (RE_MD5.test($saved)) return $password === $saved; const $svd = Buffer.from($saved, 'base64').toString('hex'); - const $salt = Buffer.from($svd.substr(40), 'hex').toString(); + const $salt = Buffer.from($svd.substring(40), 'hex').toString(); const $hash = Buffer.concat([ Buffer.from(sha1($password + $salt), 'hex'), Buffer.from($salt), diff --git a/packages/migrate/scripts/hustoj.ts b/packages/migrate/scripts/hustoj.ts index 74fa3bd54..a141c1680 100644 --- a/packages/migrate/scripts/hustoj.ts +++ b/packages/migrate/scripts/hustoj.ts @@ -80,6 +80,7 @@ export async function run({ const target = await DomainModel.get(domainId); if (!target) throw new NotFoundError(domainId); report({ message: 'Connected to database' }); + await SystemModel.set('migrate.lock', 'hustoj'); /* user_id varchar 20 N 用户id(主键) email varchar 100 Y 用户E-mail @@ -349,5 +350,6 @@ hydrooj install https://hydro.ac/hydroac-client.zip } await ProblemModel.addTestdata(domainId, pdoc.docId, 'config.yaml', Buffer.from(pdoc.config as string)); } + await SystemModel.set('migrate.lock', 0); return true; }