fix: declare D601 HWLAB PK01 migration path
This commit is contained in:
@@ -117,6 +117,8 @@ export function hwlabNodeHelp(): Record<string, unknown> {
|
||||
"bun scripts/cli.ts hwlab nodes control-plane refresh --node G14 --lane v03 --confirm",
|
||||
"bun scripts/cli.ts hwlab nodes control-plane sync --node D601 --lane v03 --confirm",
|
||||
"bun scripts/cli.ts hwlab nodes control-plane trigger-current --node G14 --lane v03 --confirm",
|
||||
"bun scripts/cli.ts hwlab nodes control-plane runtime-migration --node D601 --lane v03 --dry-run",
|
||||
"bun scripts/cli.ts hwlab nodes control-plane runtime-migration --node D601 --lane v03 --confirm",
|
||||
"bun scripts/cli.ts hwlab nodes control-plane allow-endpoint-bridge --node G14 --lane v03 --confirm",
|
||||
"bun scripts/cli.ts hwlab nodes git-mirror status --node G14 --lane v03",
|
||||
"bun scripts/cli.ts hwlab nodes secret status --node G14 --lane v03 --name hwlab-v03-openfga",
|
||||
@@ -142,7 +144,7 @@ async function runNodeDelegatedDomain(config: Config, domain: DelegatedNodeDomai
|
||||
}
|
||||
if (domain === "control-plane" && scoped.node !== defaultSpec.nodeId) {
|
||||
if (scoped.action === "status") return nodeRuntimeControlPlaneStatus(scoped);
|
||||
if (scoped.action === "apply" || scoped.action === "trigger-current" || scoped.action === "refresh" || scoped.action === "sync") {
|
||||
if (scoped.action === "apply" || scoped.action === "trigger-current" || scoped.action === "refresh" || scoped.action === "sync" || scoped.action === "runtime-migration") {
|
||||
if (scoped.confirm && !scoped.dryRun && !scoped.wait) return startNodeDelegatedJob(scoped);
|
||||
return nodeRuntimeControlPlaneRun(scoped);
|
||||
}
|
||||
@@ -183,6 +185,7 @@ function parseNodeScopedDelegatedOptions(domain: DelegatedNodeDomain, args: stri
|
||||
dryRun: boolean;
|
||||
wait: boolean;
|
||||
rerun: boolean;
|
||||
allowLiveDbRead: boolean;
|
||||
timeoutSeconds: number;
|
||||
originalArgs: string[];
|
||||
spec: HwlabRuntimeLaneSpec;
|
||||
@@ -206,6 +209,7 @@ function parseNodeScopedDelegatedOptions(domain: DelegatedNodeDomain, args: stri
|
||||
dryRun,
|
||||
wait: args.includes("--wait"),
|
||||
rerun: args.includes("--rerun"),
|
||||
allowLiveDbRead: args.includes("--allow-live-db-read"),
|
||||
timeoutSeconds: positiveIntegerOption(args, "--timeout-seconds", 1800, 3600),
|
||||
originalArgs: [...args],
|
||||
spec,
|
||||
@@ -343,7 +347,7 @@ function nodeRuntimeUnsupportedAction(scoped: ReturnType<typeof parseNodeScopedD
|
||||
lane: scoped.lane,
|
||||
mutation: false,
|
||||
degradedReason: "unsupported-node-scoped-runtime-action",
|
||||
message: "node-scoped runtime currently supports plan/status/apply/refresh/sync/trigger-current",
|
||||
message: "node-scoped runtime currently supports plan/status/apply/refresh/sync/trigger-current/runtime-migration",
|
||||
expected: nodeRuntimeExpected(scoped.spec),
|
||||
};
|
||||
}
|
||||
@@ -558,9 +562,83 @@ function nodeRuntimeControlPlaneRun(scoped: ReturnType<typeof parseNodeScopedDel
|
||||
if (scoped.action === "sync") return nodeRuntimeSync(scoped);
|
||||
if (scoped.action === "apply") return nodeRuntimeApply(scoped);
|
||||
if (scoped.action === "trigger-current") return nodeRuntimeTriggerCurrent(scoped);
|
||||
if (scoped.action === "runtime-migration") return nodeRuntimeMigration(scoped);
|
||||
return nodeRuntimeUnsupportedAction(scoped);
|
||||
}
|
||||
|
||||
function nodeRuntimeMigration(scoped: ReturnType<typeof parseNodeScopedDelegatedOptions>): Record<string, unknown> {
|
||||
const spec = scoped.spec;
|
||||
if (scoped.allowLiveDbRead && scoped.confirm) throw new Error("control-plane runtime-migration accepts --allow-live-db-read only with dry-run/source-check mode, not --confirm");
|
||||
if (!scoped.confirm && !scoped.dryRun) throw new Error("control-plane runtime-migration requires --dry-run or --confirm");
|
||||
const head = resolveNodeRuntimeLaneHead(spec);
|
||||
const sourceCommit = head.sourceCommit;
|
||||
if (sourceCommit === null) {
|
||||
return {
|
||||
ok: false,
|
||||
command: `hwlab nodes control-plane runtime-migration --node ${scoped.node} --lane ${scoped.lane}`,
|
||||
node: scoped.node,
|
||||
lane: scoped.lane,
|
||||
phase: "source-head",
|
||||
mutation: false,
|
||||
degradedReason: "node-runtime-source-head-unresolved",
|
||||
headProbe: compactRuntimeCommand(head.result),
|
||||
};
|
||||
}
|
||||
const reportPath = `/tmp/hwlab-${scoped.node.toLowerCase()}-${scoped.lane}-runtime-migration-${shortSha(sourceCommit)}.json`;
|
||||
const migrationArgs = scoped.dryRun
|
||||
? [
|
||||
...(scoped.allowLiveDbRead ? ["--dry-run", "--allow-live-db-read", "--confirm-dev"] : ["--check"]),
|
||||
"--report",
|
||||
reportPath,
|
||||
]
|
||||
: [
|
||||
"--apply",
|
||||
"--confirm-dev",
|
||||
"--confirmed-non-production",
|
||||
"--report",
|
||||
reportPath,
|
||||
];
|
||||
const result = runNodeK3sArgs(spec, [
|
||||
"kubectl",
|
||||
"exec",
|
||||
"-n",
|
||||
spec.runtimeNamespace,
|
||||
"deployment/hwlab-cloud-api",
|
||||
"-c",
|
||||
"hwlab-cloud-api",
|
||||
"--",
|
||||
"sh",
|
||||
"-lc",
|
||||
`cd /workspace/hwlab-boot/repo && exec bun cmd/hwlab-cloud-api/migrate.ts ${migrationArgs.map(shellQuote).join(" ")}`,
|
||||
], scoped.timeoutSeconds);
|
||||
const ok = isCommandSuccess(result);
|
||||
return {
|
||||
ok,
|
||||
command: `hwlab nodes control-plane runtime-migration --node ${scoped.node} --lane ${scoped.lane}`,
|
||||
node: scoped.node,
|
||||
lane: scoped.lane,
|
||||
mode: scoped.dryRun ? scoped.allowLiveDbRead ? "live-read-dry-run" : "source-check" : "confirmed-apply",
|
||||
sourceCommit,
|
||||
runtimeNamespace: spec.runtimeNamespace,
|
||||
target: "deployment/hwlab-cloud-api -c hwlab-cloud-api",
|
||||
workingDirectory: "/workspace/hwlab-boot/repo",
|
||||
migrationCommand: ["bun", "cmd/hwlab-cloud-api/migrate.ts", ...migrationArgs],
|
||||
reportPath,
|
||||
mutation: !scoped.dryRun && ok,
|
||||
result: compactRuntimeCommand(result),
|
||||
degradedReason: ok ? undefined : "node-runtime-migration-failed",
|
||||
next: scoped.dryRun
|
||||
? {
|
||||
liveReadDryRun: `bun scripts/cli.ts hwlab nodes control-plane runtime-migration --node ${scoped.node} --lane ${scoped.lane} --allow-live-db-read --dry-run`,
|
||||
apply: `bun scripts/cli.ts hwlab nodes control-plane runtime-migration --node ${scoped.node} --lane ${scoped.lane} --confirm`,
|
||||
}
|
||||
: {
|
||||
health: `curl -fsS --max-time 20 ${spec.publicApiUrl}/health/live`,
|
||||
status: `bun scripts/cli.ts hwlab nodes control-plane status --node ${scoped.node} --lane ${scoped.lane}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function nodeRuntimeApply(scoped: ReturnType<typeof parseNodeScopedDelegatedOptions>): Record<string, unknown> {
|
||||
const spec = scoped.spec;
|
||||
const head = resolveNodeRuntimeLaneHead(spec);
|
||||
|
||||
Reference in New Issue
Block a user