hydrojudge: add cgroup v2 check for judge (#642)

Co-authored-by: undefined <i@undefined.moe>
pull/683/head
panda 11 months ago committed by GitHub
parent 867cd069c5
commit 21ff3ce8f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -11,6 +11,7 @@
"mongodb": "^5.9.1", "mongodb": "^5.9.1",
"p-queue": "^7.4.1", "p-queue": "^7.4.1",
"schemastery": "^3.14.0", "schemastery": "^3.14.0",
"semver": "^7.5.4",
"shell-quote": "^1.8.1", "shell-quote": "^1.8.1",
"superagent": "^8.1.2", "superagent": "^8.1.2",
"ws": "^8.14.2" "ws": "^8.14.2"

@ -20,6 +20,7 @@ import { fs } from '@hydrooj/utils';
import { getConfig } from './config'; import { getConfig } from './config';
import HydroHost from './hosts/hydro'; import HydroHost from './hosts/hydro';
import log from './log'; import log from './log';
import { versionCheck } from './sandbox';
const hosts: Record<string, HydroHost> = {}; const hosts: Record<string, HydroHost> = {};
let exit = false; let exit = false;
@ -44,6 +45,8 @@ process.on('unhandledRejection', (reason, p) => {
}); });
async function daemon() { async function daemon() {
const shouldRun = await versionCheck((msg) => log.error(msg));
if (!shouldRun) process.exit(1);
const _hosts = getConfig('hosts'); const _hosts = getConfig('hosts');
const queue = new PQueue({ concurrency: Infinity }); const queue = new PQueue({ concurrency: Infinity });
await fs.ensureDir(getConfig('tmp_dir')); await fs.ensureDir(getConfig('tmp_dir'));

@ -11,6 +11,7 @@ import { getConfig } from '../config';
import { FormatError, SystemError } from '../error'; import { FormatError, SystemError } from '../error';
import { Context } from '../judge/interface'; import { Context } from '../judge/interface';
import logger from '../log'; import logger from '../log';
import { versionCheck } from '../sandbox';
import { JudgeTask } from '../task'; import { JudgeTask } from '../task';
const session = { const session = {
@ -71,8 +72,9 @@ const session = {
}, },
}; };
export async function postInit() { export async function postInit(ctx) {
if (SystemModel.get('hydrojudge.disable')) return; if (SystemModel.get('hydrojudge.disable')) return;
ctx.check.addChecker('Judge', (_ctx, log, warn, error) => versionCheck(warn, error));
await fs.ensureDir(getConfig('tmp_dir')); await fs.ensureDir(getConfig('tmp_dir'));
const handle = async (t) => { const handle = async (t) => {
const rdoc = await RecordModel.get(t.domainId, t.rid); const rdoc = await RecordModel.get(t.domainId, t.rid);

@ -1,7 +1,9 @@
import cac from 'cac'; import cac from 'cac';
import PQueue from 'p-queue'; import PQueue from 'p-queue';
import { gte } from 'semver';
import { ParseEntry } from 'shell-quote'; import { ParseEntry } from 'shell-quote';
import { STATUS } from '@hydrooj/utils/lib/status'; import { STATUS } from '@hydrooj/utils/lib/status';
import * as sysinfo from '@hydrooj/utils/lib/sysinfo';
import { getConfig } from './config'; import { getConfig } from './config';
import { FormatError, SystemError } from './error'; import { FormatError, SystemError } from './error';
import { Logger } from './log'; import { Logger } from './log';
@ -216,4 +218,26 @@ export function runQueued(execute: string, params?: Parameter, priority = 0) {
return queue.add(() => run(execute, params), { priority }) as Promise<SandboxAdaptedResult>; return queue.add(() => run(execute, params), { priority }) as Promise<SandboxAdaptedResult>;
} }
export async function versionCheck(reportWarn: (str: string) => void, reportError = reportWarn) {
let sandboxVersion: string;
let sandboxCgroup: number;
try {
const version = await client.version();
sandboxVersion = version.buildVersion.split('v')[1];
const config = await client.config();
sandboxCgroup = config.runnerConfig?.cgroupType || 0;
} catch (e) {
reportError('Your sandbox version is tooooooo low! Please upgrade!');
return false;
}
const { osinfo } = await sysinfo.get();
if (sandboxCgroup === 2) {
const kernelVersion = osinfo.kernel.split('-')[0];
if (!(gte(kernelVersion, '5.19.0') && gte(sandboxVersion, '1.6.10'))) {
reportWarn('You are using cgroup v2 without kernel 5.19+. This could result in inaccurate memory usage measurements.');
}
}
return true;
}
export * from './sandbox/interface'; export * from './sandbox/interface';

@ -20,6 +20,9 @@ const client = new Proxy({
version(): Promise<SandboxVersion> { version(): Promise<SandboxVersion> {
return superagent.get(`${url}/version`).then((res) => res.body); return superagent.get(`${url}/version`).then((res) => res.body);
}, },
config(): Promise<Record<string, any>> {
return superagent.get(`${url}/config`).then((res) => res.body);
},
}, { }, {
get(self, key) { get(self, key) {
url = getConfig('sandbox_host'); url = getConfig('sandbox_host');

@ -16,5 +16,5 @@ declare module 'hydrooj' {
export function apply(ctx: Context) { export function apply(ctx: Context) {
if (process.env.NODE_APP_INSTANCE !== '0') return; if (process.env.NODE_APP_INSTANCE !== '0') return;
ctx.once('app/started', () => require('./hosts/builtin').postInit()); ctx.once('app/started', () => require('./hosts/builtin').postInit(ctx));
} }

Loading…
Cancel
Save