feat: serial console on test VMs for debugging without SSH
Some checks failed
CI/CD / typecheck (pull_request) Failing after 9s
CI/CD / test (pull_request) Failing after 9s
CI/CD / lint (pull_request) Failing after 21s
CI/CD / build (pull_request) Has been skipped
CI/CD / publish-rpm (pull_request) Has been skipped
CI/CD / publish-deb (pull_request) Has been skipped
Some checks failed
CI/CD / typecheck (pull_request) Failing after 9s
CI/CD / test (pull_request) Failing after 9s
CI/CD / lint (pull_request) Failing after 21s
CI/CD / build (pull_request) Has been skipped
CI/CD / publish-rpm (pull_request) Has been skipped
CI/CD / publish-deb (pull_request) Has been skipped
- VMs get serial console on TCP (PXE: port 4555, ISO: port 4556) - serialExec() helper: runs commands via telnet when SSH/network is down - PXE test: on SSH failure, dumps hostname, IP, NetworkManager, sshd, failed units, and fstab via serial console before failing - Kickstart enables serial-getty@ttyS0 for auto-login on serial Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,7 +24,7 @@ import { join } from "node:path";
|
||||
import { homedir, tmpdir } from "node:os";
|
||||
import { log, waitForSsh } from "./helpers/libvirt.js";
|
||||
import { ensurePxeNetwork, destroyPxeNetwork, PXE_NETWORK_NAME, PXE_GATEWAY, PXE_SUBNET } from "./helpers/pxe-network.js";
|
||||
import { createPxeVm, destroyPxeVm, getVmMac, rebootPxeVm } from "./helpers/pxe-vm.js";
|
||||
import { createPxeVm, destroyPxeVm, getVmMac, rebootPxeVm, serialExec } from "./helpers/pxe-vm.js";
|
||||
import { sshExec } from "./helpers/ssh.js";
|
||||
|
||||
// --- Test constants ---
|
||||
@@ -277,7 +277,29 @@ describe("PXE boot provisioning", () => {
|
||||
// 10. Wait for SSH — VM network-boots, iPXE chains to /dispatch,
|
||||
// bastion returns exit (installed), iPXE falls through to disk boot
|
||||
log("Waiting for SSH access...");
|
||||
await waitForSsh(vmIp, SSH_USER, SSH_TIMEOUT_MS, sshKeyPath);
|
||||
try {
|
||||
await waitForSsh(vmIp, SSH_USER, SSH_TIMEOUT_MS, sshKeyPath);
|
||||
} catch {
|
||||
// SSH failed — use serial console to diagnose
|
||||
log("SSH timed out. Diagnosing via serial console...");
|
||||
try {
|
||||
const hostname = await serialExec(4555, "hostname", 15_000);
|
||||
log(`Serial: hostname = ${hostname}`);
|
||||
const ip = await serialExec(4555, "ip -4 addr show | grep inet", 15_000);
|
||||
log(`Serial: ip = ${ip}`);
|
||||
const nm = await serialExec(4555, "systemctl is-active NetworkManager", 15_000);
|
||||
log(`Serial: NetworkManager = ${nm}`);
|
||||
const sshd = await serialExec(4555, "systemctl is-active sshd", 15_000);
|
||||
log(`Serial: sshd = ${sshd}`);
|
||||
const failed = await serialExec(4555, "systemctl --failed --no-pager", 15_000);
|
||||
log(`Serial: failed units = ${failed}`);
|
||||
const fstab = await serialExec(4555, "grep efi /etc/fstab", 15_000);
|
||||
log(`Serial: fstab efi = ${fstab}`);
|
||||
} catch (serialErr) {
|
||||
log(`Serial console failed: ${serialErr instanceof Error ? serialErr.message : String(serialErr)}`);
|
||||
}
|
||||
throw new Error(`SSH not available on ${vmIp} — check serial console diagnostics above`);
|
||||
}
|
||||
|
||||
log("PXE provision test setup complete.");
|
||||
}, DISCOVERY_TIMEOUT_MS + INSTALL_TIMEOUT_MS + SSH_TIMEOUT_MS + 120_000); // total timeout
|
||||
|
||||
Reference in New Issue
Block a user