fix(cutover): close identity binding races

This commit is contained in:
chick
2026-07-18 18:13:53 +08:00
parent 63d167d720
commit d323370a75
+10 -10
View File
@@ -14,7 +14,7 @@ import {
} from 'node:fs/promises';
import { createHash } from 'node:crypto';
import { request } from 'node:http';
import { basename, isAbsolute, join, resolve } from 'node:path';
import { isAbsolute, join, resolve } from 'node:path';
import { GATEWAY_AUTH_HEADER } from './runtime-config.js';
import { PRODUCTION_CUTOVER_ACK } from './canary-runtime.js';
@@ -197,12 +197,7 @@ function exactKeys(
}
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;
return commandArgv.join(' ') === command;
}
function safeString(value: unknown, label: string): string {
@@ -431,12 +426,12 @@ export async function cutover(
MULTI_SIMADMIN_CUTOVER_ACK: PRODUCTION_CUTOVER_ACK,
MULTI_SIMADMIN_GATEWAY_TOKEN: gatewayToken,
});
gatewayCommand = await system.command(gatewayPid);
gatewayIdentity = await system.identity(gatewayPid);
if (!(await waitForGateway(system, gatewayPid, gatewayToken)))
throw new Error(
'Production gateway failed authenticated ownership verification on port 8788',
);
gatewayCommand = await system.command(gatewayPid);
gatewayIdentity = await system.identity(gatewayPid);
await durableState(plan, {
...preparedState(plan),
phase: 'active',
@@ -450,7 +445,12 @@ export async function cutover(
try {
const actual = await system.command(gatewayPid);
const identity = await system.identity(gatewayPid);
if (actual === gatewayCommand && identity === gatewayIdentity) {
if (
(gatewayCommand === undefined || actual === gatewayCommand) &&
(gatewayIdentity === undefined || identity === gatewayIdentity) &&
actual !== '' &&
identity !== ''
) {
system.signal(gatewayPid, 'SIGTERM');
await system.waitGone(gatewayPid);
}