mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-10 19:07:17 +01:00
Much of testsAndMisc/linux_configuration cannot be tested on the host: 15 files use `chattr +i` (so a bad test is not simply revertable), the shutdown installers write units that power the machine off, and boot_recovery installs pacman hooks. The repo's own CI says as much -- its Ubuntu job runs only the side-effect-free tests, noting the rest "drive pacman, /etc, systemd or adb". vmbox runs them in a throwaway Arch guest and verifies the result from the HOST, which is the part that is not obvious: a successful shutdown kills the connection carrying the report, and ssh returns 255 for a clean poweroff, a crash and a dropped link alike. So the verdict comes from two artefacts that outlive the VM -- a QMP event log written by a recorder attached at launch (attach later and qemu has already exited), and the serial console log. Five outcomes are distinguished: clean poweroff (SHUTDOWN guest:true plus a serial tail reaching "reboot: Power down"), dirty stop, guest-reset (rebooted instead of powering off), GUEST_PANICKED, and hung. A POWERDOWN event proves nothing -- it means the request was delivered, not that anything acted on it. Reset is a qcow2 backing-file trick: the golden image is built once and sealed (chmod 444 plus a sha256 sidecar verified on every launch, since booting the base would silently invalidate every overlay), and each sandbox is a thin overlay, so reset is rm + recreate. No root anywhere -- user-mode networking with per-VM forwarded ssh ports, and a socket multicast segment for VM-to-VM. The guest clock is pinned and re-applied on every launch, because the shutdown installers gate on a 21:00-05:00 window; NTP is masked in the image or it silently undoes the pin. Repos are cloned from a read-only share scoped to an explicit directory, never $HOME, and credentials are sentinel values. `vm build` ends by booting a throwaway sandbox off the sealed image and refusing to ship if ssh does not answer. Several distinct faults produced an identical "boots fine, connection reset" symptom; checks inside the build VM only prove state at seal time, so the gate has to be an end-to-end boot. Tests: 8 bats cases over the verdict table and name/meta/serial handling; shellcheck and ruff clean; every file within the 250-line cap. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdyMBGCrGVGDWtJ9xe48f3
50 lines
2.0 KiB
Bash
50 lines
2.0 KiB
Bash
#!/bin/bash
|
|
# ============================================================================
|
|
# vmbox: post-seal verification.
|
|
#
|
|
# Split out of base.sh to stay under the 250-line cap.
|
|
# ============================================================================
|
|
|
|
# shellcheck source=common.sh
|
|
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
|
|
|
|
# Boot a real overlay off the freshly sealed base and require that ssh answers.
|
|
#
|
|
# This is the gate that matters. Every check inside the build VM only proves
|
|
# state at seal time; the failures that actually shipped all lived in the gap
|
|
# between "correct in the build VM" and "works on a fresh overlay boot". This
|
|
# catches missing host keys, a no-op systemctl enable, a clobbered NIC and
|
|
# whatever the next cause turns out to be, WITHOUT needing to know which.
|
|
base_smoke_test() {
|
|
log "Smoke-testing the sealed image (boots a throwaway sandbox)"
|
|
source "$VMBOX_LIB_DIR/overlay.sh"
|
|
source "$VMBOX_LIB_DIR/launch.sh"
|
|
source "$VMBOX_LIB_DIR/ssh.sh"
|
|
|
|
local smoke="__smoke"
|
|
vm_exists "$smoke" && overlay_rm "$smoke" >/dev/null 2>&1
|
|
overlay_new "$smoke" >/dev/null
|
|
|
|
local failed=0
|
|
launch_vm "$smoke" >/dev/null
|
|
if vm_wait_ssh "$smoke" 180 && vm_ssh_exec "$smoke" true 2>/dev/null; then
|
|
ok "smoke test passed: a fresh sandbox boots and accepts ssh"
|
|
else
|
|
failed=1
|
|
warn "SMOKE TEST FAILED -- the sealed image boots but is unreachable."
|
|
warn "Serial log: $(vm_serial "$smoke" 0)"
|
|
warn "Debug it with the serial console (root autologin is enabled there)."
|
|
fi
|
|
|
|
# On failure KEEP the sandbox: deleting it would destroy the serial log
|
|
# this very message points at, which is the only evidence available when
|
|
# ssh is the thing that is broken.
|
|
if (( failed == 0 )); then
|
|
overlay_rm "$smoke" >/dev/null 2>&1 || true
|
|
else
|
|
warn "keeping sandbox '__smoke' so its logs survive; remove it with: vm rm __smoke"
|
|
die "refusing to ship an unreachable base image"
|
|
fi
|
|
}
|
|
|