fix(cutover): support absolute legacy restart executable

This commit is contained in:
chick
2026-07-18 17:34:09 +08:00
parent 4a7e29cf06
commit bad00b67e9
+11 -2
View File
@@ -14,7 +14,7 @@ import {
} from 'node:fs/promises'; } from 'node:fs/promises';
import { createHash } from 'node:crypto'; import { createHash } from 'node:crypto';
import { request } from 'node:http'; import { request } from 'node:http';
import { isAbsolute, join, resolve } from 'node:path'; import { basename, isAbsolute, join, resolve } from 'node:path';
import { GATEWAY_AUTH_HEADER } from './runtime-config.js'; import { GATEWAY_AUTH_HEADER } from './runtime-config.js';
import { PRODUCTION_CUTOVER_ACK } from './canary-runtime.js'; import { PRODUCTION_CUTOVER_ACK } from './canary-runtime.js';
@@ -185,6 +185,15 @@ function exactKeys(
throw new Error(`${label} has an invalid schema`); throw new Error(`${label} has an invalid schema`);
} }
function commandMatchesArgv(command: string, commandArgv: readonly string[]): boolean {
const rendered = commandArgv.join(' ');
if (rendered === command) return true;
const executable = commandArgv[0];
if (executable === undefined) return false;
const args = commandArgv.slice(1);
return [basename(executable), ...args].join(' ') === command;
}
function safeString(value: unknown, label: string): string { function safeString(value: unknown, label: string): string {
if (typeof value !== 'string' || value.length === 0 || value.includes('\0')) if (typeof value !== 'string' || value.length === 0 || value.includes('\0'))
throw new Error(`${label} must be a non-empty string`); throw new Error(`${label} must be a non-empty string`);
@@ -246,7 +255,7 @@ export function parseCutoverPlan(value: unknown): CutoverPlan {
throw new Error('legacyPid must be a safe PID greater than 1'); throw new Error('legacyPid must be a safe PID greater than 1');
if (!DIGEST.test(plan.backupEvidenceSha256) || !DIGEST.test(plan.drillEvidenceSha256)) if (!DIGEST.test(plan.backupEvidenceSha256) || !DIGEST.test(plan.drillEvidenceSha256))
throw new Error('Evidence digests must be lowercase SHA-256'); throw new Error('Evidence digests must be lowercase SHA-256');
if (plan.legacyStart.join(' ') !== plan.legacyCommand) if (!commandMatchesArgv(plan.legacyCommand, plan.legacyStart))
throw new Error('legacyStart must exactly reproduce legacyCommand'); throw new Error('legacyStart must exactly reproduce legacyCommand');
return Object.freeze(plan); return Object.freeze(plan);
} }