mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-10 20:07:18 +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
60 lines
1.9 KiB
Bash
Executable File
60 lines
1.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# ============================================================================
|
|
# vmbox installer: installs host dependencies and links `vm` onto PATH.
|
|
#
|
|
# Deliberately NOT run as root: vmbox is designed to need no root at all
|
|
# (user-mode + multicast networking, qcow2 overlays, no bridge, no libvirt).
|
|
# Only the pacman step escalates, and only when something is missing.
|
|
# ============================================================================
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
readonly SCRIPT_DIR
|
|
readonly LINK_DIR="${LINK_DIR:-$HOME/.local/bin}"
|
|
|
|
# xorriso ships in libisoburn -- there is no package named "xorriso".
|
|
readonly -a PACKAGES=(qemu-base libisoburn openssh python)
|
|
|
|
if [[ $EUID -eq 0 ]]; then
|
|
echo "Do not run install.sh as root: it links into \$HOME and would" >&2
|
|
echo "create root-owned files there. It escalates on its own if needed." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "==> Checking host dependencies ..."
|
|
missing=()
|
|
for pkg in "${PACKAGES[@]}"; do
|
|
pacman -Qq "$pkg" >/dev/null 2>&1 || missing+=("$pkg")
|
|
done
|
|
|
|
if (( ${#missing[@]} )); then
|
|
echo "==> Installing: ${missing[*]}"
|
|
sudo pacman -S --needed --noconfirm "${missing[@]}"
|
|
else
|
|
echo " all present: ${PACKAGES[*]}"
|
|
fi
|
|
|
|
# KVM is what makes this usable rather than glacial; a missing /dev/kvm is a
|
|
# hard stop, not a warning, because the fallback is ~20x slower.
|
|
[[ -c /dev/kvm ]] || {
|
|
echo "error: /dev/kvm missing -- enable virtualization (SVM/VT-x) in firmware" >&2
|
|
exit 1
|
|
}
|
|
[[ -r /dev/kvm && -w /dev/kvm ]] || {
|
|
echo "error: /dev/kvm not read/writable by $USER -- add yourself to the 'kvm' group" >&2
|
|
exit 1
|
|
}
|
|
|
|
echo "==> Linking vm -> $LINK_DIR/vm"
|
|
install -d -m 755 "$LINK_DIR"
|
|
ln -sfn "$SCRIPT_DIR/bin/vm" "$LINK_DIR/vm"
|
|
|
|
case ":$PATH:" in
|
|
*":$LINK_DIR:"*) ;;
|
|
*) echo " note: $LINK_DIR is not on your PATH" ;;
|
|
esac
|
|
|
|
echo
|
|
echo "Installed. Next: vm build (builds the golden image, once)"
|