From 6a5f23c0f5e932b40bc2ec5a6eea1dd27664f238 Mon Sep 17 00:00:00 2001 From: Michal Date: Mon, 30 Mar 2026 22:59:45 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20reprovision=20workflow=20bugs=20?= =?UTF-8?q?=E2=80=94=20SSH=20host=20key=20warnings,=20log=20following,=20s?= =?UTF-8?q?tatus=20priority?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add UserKnownHostsFile=/dev/null to SSH in debug and reprovision commands - Track install state in log follower so it doesn't exit prematurely on "installed" - Reorder bastion status check to prioritize active queue over stale installed state - Update .gitignore with task file entries Co-Authored-By: Claude Opus 4.6 (1M context) --- .gitignore | 4 ++++ bastion/src/cli/src/commands/debug.ts | 1 + bastion/src/cli/src/commands/logs.ts | 10 +++++++-- bastion/src/cli/src/commands/reprovision.ts | 1 + bastion/src/labd/src/routes/bastions.ts | 23 +++++++++++---------- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index f270674..9dc1e1c 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,7 @@ node_modules/ # OS specific .DS_Store + +# Task files +# tasks.json +# tasks/ diff --git a/bastion/src/cli/src/commands/debug.ts b/bastion/src/cli/src/commands/debug.ts index 2bb4f24..903ca8a 100644 --- a/bastion/src/cli/src/commands/debug.ts +++ b/bastion/src/cli/src/commands/debug.ts @@ -103,6 +103,7 @@ export function registerDebugCommand(parent: Command): void { const sshArgs = [ "-o", "StrictHostKeyChecking=no", + "-o", "UserKnownHostsFile=/dev/null", "-o", "ConnectTimeout=10", ...(sshKey !== undefined ? ["-i", sshKey] : []), `${effectiveUser}@${ip}`, diff --git a/bastion/src/cli/src/commands/logs.ts b/bastion/src/cli/src/commands/logs.ts index 48630a6..3ab8487 100644 --- a/bastion/src/cli/src/commands/logs.ts +++ b/bastion/src/cli/src/commands/logs.ts @@ -103,6 +103,7 @@ async function followLogs( let lastStageCount = 0; let lastStatus = ""; + let sawInstalling = false; while (true) { try { @@ -118,6 +119,10 @@ async function followLogs( lastStatus = status; } + if (status === "installing" || status === "queued") { + sawInstalling = true; + } + // Print new stages if (log && log.length > lastStageCount) { for (let i = lastStageCount; i < log.length; i++) { @@ -130,8 +135,9 @@ async function followLogs( lastStageCount = log.length; } - // Done - if (status === "installed") { + // Only exit on "installed" if we actually saw the install happen + // (avoids exiting immediately when following a reprovision that hasn't started yet) + if (status === "installed" && sawInstalling) { const ip = data["ip"] ?? ""; console.log(""); console.log(` ${GREEN}${BOLD}Install complete!${RESET}${ip ? ` ${DIM}ssh lab@${ip}${RESET}` : ""}`); diff --git a/bastion/src/cli/src/commands/reprovision.ts b/bastion/src/cli/src/commands/reprovision.ts index 7e421fc..9f213f6 100644 --- a/bastion/src/cli/src/commands/reprovision.ts +++ b/bastion/src/cli/src/commands/reprovision.ts @@ -144,6 +144,7 @@ export function registerReprovisionCommand(parent: Command): void { const sshArgs = [ "-o", "StrictHostKeyChecking=no", + "-o", "UserKnownHostsFile=/dev/null", "-o", "ConnectTimeout=10", ...(sshKey !== undefined ? ["-i", sshKey] : []), `${effectiveUser}@${ip}`, diff --git a/bastion/src/labd/src/routes/bastions.ts b/bastion/src/labd/src/routes/bastions.ts index 9c8e181..12267f9 100644 --- a/bastion/src/labd/src/routes/bastions.ts +++ b/bastion/src/labd/src/routes/bastions.ts @@ -257,17 +257,7 @@ export function registerBastionRoutes(app: FastifyInstance, db: DbClient): void const queued = bastion.state.install_queue[mac]; const installed = bastion.state.installed[mac]; - if (installed) { - return { - mac, - hostname: installed.hostname, - status: "installed", - role: installed.role, - ip: installed.ip, - installed_at: installed.installed_at, - }; - } - + // Active install takes priority over old installed state (reprovision case) if (queued) { return { mac, @@ -282,6 +272,17 @@ export function registerBastionRoutes(app: FastifyInstance, db: DbClient): void }; } + if (installed) { + return { + mac, + hostname: installed.hostname, + status: "installed", + role: installed.role, + ip: installed.ip, + installed_at: installed.installed_at, + }; + } + return reply.code(404).send({ error: `MAC ${mac} not found in install queue or installed` }); }); }