feat: initial commit — void-installer multi-profile (stable-cinnamon + mainline-niri)

This commit is contained in:
mozempk
2026-04-22 23:53:16 +02:00
commit a16ac37d20
35 changed files with 3902 additions and 0 deletions

20
tests/boot-niri-interactive.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
# Boot the installed niri disk in an interactive QEMU GUI window.
set -Eeuo pipefail
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
OUT="$PROJECT_DIR/out/niri"
DISK="$OUT/niri-disk.img"
VARS="$OUT/OVMF_VARS.installed.fd"
[[ -r "$DISK" ]] || { echo "no $DISK — run tests/run-niri-install.sh first"; exit 1; }
cp "$OUT/OVMF_VARS.fd" "$VARS"
DISPLAY="${DISPLAY:-:0}" exec qemu-system-x86_64 \
-name void-niri-installed \
-machine q35,accel=kvm:tcg \
-cpu max -m 4096 -smp 4 \
-drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE.fd \
-drive "if=pflash,format=raw,file=$VARS" \
-drive "if=virtio,file=$DISK,format=raw,cache=none" \
-netdev user,id=n0 -device virtio-net-pci,netdev=n0 \
-vga virtio -display gtk

34
tests/interactive-qemu.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/bash
# Launch QEMU with the latest installer ISO for INTERACTIVE testing.
# Use this when you want to drive the TUI yourself.
set -Eeuo pipefail
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
OUT_DIR="$PROJECT_DIR/out"
ISO="${ISO:-$(ls -t "$OUT_DIR"/void-install-*.iso 2>/dev/null | grep -v TEST | head -1 || true)}"
DISK="${DISK:-$OUT_DIR/test-disk.img}"
RAM_MB="${RAM_MB:-4096}"
SMP="${SMP:-4}"
OVMF_CODE="${OVMF_CODE:-/usr/share/OVMF/OVMF_CODE.fd}"
OVMF_VARS_TPL="${OVMF_VARS_TPL:-/usr/share/OVMF/OVMF_VARS.fd}"
[[ -r "$OVMF_CODE" ]] || { echo "no OVMF — install ovmf"; exit 1; }
[[ -r "$ISO" ]] || { echo "no ISO at $ISO — run 'make iso' first"; exit 1; }
if [[ ! -f "$DISK" ]]; then
"$PROJECT_DIR/tests/make-test-disk.sh" "$DISK"
fi
VARS="$OUT_DIR/OVMF_VARS.interactive.fd"
[[ -f "$VARS" ]] || cp "$OVMF_VARS_TPL" "$VARS"
exec qemu-system-x86_64 \
-name void-installer-interactive \
-machine q35,accel=kvm:tcg -cpu max \
-m "$RAM_MB" -smp "$SMP" \
-drive "if=pflash,format=raw,readonly=on,file=$OVMF_CODE" \
-drive "if=pflash,format=raw,file=$VARS" \
-drive "if=virtio,file=$DISK,format=raw,cache=none" \
-cdrom "$ISO" \
-boot menu=on \
-netdev user,id=n0,hostfwd=tcp:127.0.0.1:2222-:22 \
-device virtio-net-pci,netdev=n0 \
-vga virtio -display gtk

107
tests/lib/make-test-overlay.sh Executable file
View File

@@ -0,0 +1,107 @@
#!/bin/bash
# Side-channel overlay used ONLY by the QEMU smoke-test harness.
# Sourced into the live ISO at /usr/local/share/installer/install.conf.d/
# and /etc/profile.d/. Forces unattended + test-mode behaviour and enables
# sshd in the installed system so the harness can ssh in.
set -Eeuo pipefail
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
DEST="${1:?usage: $0 <out-dir>}"
mkdir -p "$DEST/etc/profile.d"
cat > "$DEST/etc/profile.d/99-void-installer-test.sh" <<EOF
# Auto-run installer non-interactively when test ISO boots.
export UNATTENDED=1
export TEST_MODE=1
export PROFILE="${TEST_PROFILE:-stable-cinnamon}"
EOF
chmod 0644 "$DEST/etc/profile.d/99-void-installer-test.sh"
mkdir -p "$DEST/usr/local/share/installer/install.conf.d"
cat > "$DEST/usr/local/share/installer/install.conf.d/99-test.conf" <<'EOF'
# Test overrides (qemu smoke test)
SSHD_ENABLE="yes"
DEFAULT_DISK="/dev/vda"
DEFAULT_ROOT_PART="/dev/vda5"
DEFAULT_EFI_PART="/dev/vda1"
# Use the local xbps proxy on the host (10.0.2.2 inside QEMU's user net).
INSTALL_REPO_URL="http://10.0.2.2:3142/current"
# Quieter zram in tiny VM
ZRAM_SIZE_PCT="25"
EOF
chmod 0644 "$DEST/usr/local/share/installer/install.conf.d/99-test.conf"
# Drop a public key the harness can use to ssh in as moze without a password.
# Generated below (or supplied via TEST_PUBKEY env) and added to authorized_keys
# under /etc/installer-ssh/ so postinstall.sh copies it into ~/.ssh/.
mkdir -p "$DEST/etc/installer-ssh"
if [[ -n "${TEST_PUBKEY:-}" ]]; then
echo "$TEST_PUBKEY" > "$DEST/etc/installer-ssh/authorized_keys"
chmod 0600 "$DEST/etc/installer-ssh/authorized_keys"
fi
# Enable an autostart `sshd` already inside the live env so the harness
# can ssh into the live ISO too if needed (debug).
mkdir -p "$DEST/etc/runit/runsvdir/default"
ln -sf /etc/sv/sshd "$DEST/etc/runit/runsvdir/default/sshd" 2>/dev/null || true
# Autologin root on ttyS0 so the installer's .bash_profile fires under
# QEMU's `-display none -serial file:...` (no tty1 attached).
mkdir -p "$DEST/etc/sv/agetty-ttyS0-autologin"
cat > "$DEST/etc/sv/agetty-ttyS0-autologin/run" <<'EOF'
#!/bin/sh
exec /sbin/agetty --autologin root --noclear -L 115200 ttyS0 vt100
EOF
chmod 0755 "$DEST/etc/sv/agetty-ttyS0-autologin/run"
ln -sf /etc/sv/agetty-ttyS0-autologin "$DEST/etc/runit/runsvdir/default/agetty-ttyS0-autologin"
# Make .bash_profile fire on ttyS0 AND tty1 (interactive GTK QEMU uses tty1).
mkdir -p "$DEST/root"
cat > "$DEST/root/.bash_profile" <<'EOF'
case "$(tty)" in
/dev/ttyS0|/dev/tty1)
# Atomic single-instance lock. mkdir is atomic; only ONE tty wins.
# Previously the check-then-touch race let both tty1 and ttyS0 enter,
# running install-void twice in parallel and corrupting /mnt.
if mkdir /tmp/.installer-lock 2>/dev/null; then
echo "Void Linux Installer (xps9700) — TEST MODE"
# Bring up networking via dhcpcd (live ISO doesn't autostart it).
echo " bringing up network..."
dhcpcd -b 2>/dev/null || true
for i in $(seq 1 20); do
if curl -sf --max-time 1 http://10.0.2.2:3142/ >/dev/null 2>&1; then
echo " network up after ${i}s"
break
fi
sleep 1
done
sleep 1
set -x
/usr/local/sbin/install-void 2>&1 | tee /tmp/installer.log
rc=${PIPESTATUS[0]}
set +x
if [ "$rc" -ne 0 ]; then
echo "===== INSTALLER FAILED rc=$rc ====="
echo "--- ip addr ---"
ip addr 2>&1 | head -20
echo "--- ip route ---"
ip route 2>&1
echo "--- /etc/resolv.conf ---"
cat /etc/resolv.conf 2>/dev/null
echo "--- curl proxy test ---"
curl -sv --max-time 3 http://10.0.2.2:3142/ 2>&1 | head -10
echo "--- /tmp/installer.log (tail) ---"
tail -100 /tmp/installer.log 2>/dev/null
echo "===== END FAIL DUMP ====="
exec /bin/bash
fi
echo "Install complete. Powering off."
poweroff
fi
;;
esac
EOF
chmod 0644 "$DEST/root/.bash_profile"
echo ">>> test overlay staged at $DEST"

53
tests/make-test-disk.sh Executable file
View File

@@ -0,0 +1,53 @@
#!/bin/bash
# Create a fresh test disk image that mimics the XPS 17 layout:
# p1: 150 MiB EFI vfat (with a fake EFI/Microsoft/* tree)
# p2: 128 MiB MSR
# p3: 4 GiB NTFS placeholder ("Windows", must NOT be touched)
# p5: rest btrfs "Mint" (will be wiped by installer)
#
# No root required: uses sgdisk on the raw file + mtools for FAT32.
# The installer reformats p5; p3 carries only a partition-type flag (0700).
#
# Output: a sparse raw image (QEMU format=raw).
set -Eeuo pipefail
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
OUT="${1:-$PROJECT_DIR/out/test-disk.img}"
SIZE="${SIZE:-32G}"
mkdir -p "$(dirname "$OUT")"
command -v sgdisk >/dev/null || { echo "sgdisk missing (gptfdisk)"; exit 1; }
command -v mformat >/dev/null || { echo "mformat missing (mtools)"; exit 1; }
command -v mmd >/dev/null || { echo "mmd missing (mtools)"; exit 1; }
command -v mcopy >/dev/null || { echo "mcopy missing (mtools)"; exit 1; }
echo ">>> creating sparse raw disk ($SIZE) at $OUT"
rm -f "$OUT"
truncate -s "$SIZE" "$OUT"
echo ">>> partitioning"
sgdisk -Z "$OUT" >/dev/null 2>&1 || true
sgdisk \
-n 1:2048:+150M -t 1:ef00 -c 1:"EFI system partition" \
-n 2:0:+128M -t 2:0c01 -c 2:"Microsoft reserved partition" \
-n 3:0:+4G -t 3:0700 -c 3:"Basic data partition" \
-n 5:0:0 -t 5:8300 -c 5:"Mint" \
"$OUT" >/dev/null
# Derive partition-1 byte offset + sector count from GPT metadata.
P1_START=$(sgdisk -i 1 "$OUT" | awk '/First sector:/ {print $3}')
P1_LAST=$(sgdisk -i 1 "$OUT" | awk '/Last sector:/ {print $3}')
P1_SECTORS=$(( P1_LAST - P1_START + 1 ))
P1_OFFSET=$(( P1_START * 512 ))
echo ">>> formatting EFI partition 1 (FAT32) at byte offset $P1_OFFSET"
mformat -i "$OUT@@$P1_OFFSET" -F -T "$P1_SECTORS" -v ESP ::
echo ">>> faking Windows EFI loader on p1"
mmd -i "$OUT@@$P1_OFFSET" ::/EFI ::/EFI/Microsoft ::/EFI/Microsoft/Boot
printf 'FAKE WINDOWS BOOTMGR\n' \
| mcopy -i "$OUT@@$P1_OFFSET" - ::/EFI/Microsoft/Boot/bootmgfw.efi
echo ">>> done: $OUT"

94
tests/run-niri-install.sh Executable file
View File

@@ -0,0 +1,94 @@
#!/bin/bash
# Build the mainline-niri ISO and install it headlessly into a separate
# disk image, isolated from the stable-cinnamon test harness.
#
# Outputs (under out/niri/):
# void-install-niri.iso test ISO with PROFILE=mainline-niri baked in
# niri-disk.img 32G raw disk receiving the install
# OVMF_VARS.fd per-VM EFI nvram
# install.serial.log full installer log
#
# After a successful install, run:
# tests/boot-niri-interactive.sh
# to launch the installed niri VM in a GUI window.
set -Eeuo pipefail
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
OUT="$PROJECT_DIR/out/niri"
mkdir -p "$OUT"
QEMU="${QEMU:-qemu-system-x86_64}"
OVMF_CODE="${OVMF_CODE:-/usr/share/OVMF/OVMF_CODE.fd}"
OVMF_VARS_TPL="${OVMF_VARS_TPL:-/usr/share/OVMF/OVMF_VARS.fd}"
RAM_MB="${RAM_MB:-4096}"
SMP="${SMP:-4}"
TIMEOUT_INSTALL="${TIMEOUT_INSTALL:-3600}"
blue() { printf '\033[34m==> %s\033[0m\n' "$*"; }
# 1) ensure xbps proxy is up (shared with main harness)
"$PROJECT_DIR/tools/start-xbps-proxy.sh"
trap '"$PROJECT_DIR/tools/stop-xbps-proxy.sh" 2>/dev/null || true; \
pkill -f qemu-system.*void-niri-install 2>/dev/null || true' EXIT
# 2) build TEST overlay with PROFILE=mainline-niri
TEST_OVERLAY="$OUT/test-overlay"
TEST_PROFILE=mainline-niri \
"$PROJECT_DIR/tests/lib/make-test-overlay.sh" "$TEST_OVERLAY"
# 3) build ISO
ISO="$OUT/void-install-niri.iso"
if [[ ! -f "$ISO" || -n "${REBUILD_ISO:-}" ]]; then
blue "building niri ISO -> $ISO"
EXTRA_INCLUDE_DIR="$TEST_OVERLAY" \
OUTPUT_ISO="$ISO" \
INSTALL_REPO_URL="http://10.0.2.2:3142/current" \
BOOT_CMDLINE="console=tty0 console=ttyS0,115200" \
"$PROJECT_DIR/iso/build-iso.sh"
fi
# 4) fresh disk
DISK="$OUT/niri-disk.img"
blue "creating fresh disk -> $DISK"
"$PROJECT_DIR/tests/make-test-disk.sh" "$DISK"
# 5) per-VM EFI nvram
VARS="$OUT/OVMF_VARS.fd"
cp "$OVMF_VARS_TPL" "$VARS"
# 6) run installer headless
SERIAL_LOG="$OUT/install.serial.log"
: > "$SERIAL_LOG"
blue "boot ISO + run installer (timeout ${TIMEOUT_INSTALL}s)"
set +e
timeout "$TIMEOUT_INSTALL" "$QEMU" \
-name void-niri-install \
-machine q35,accel=kvm:tcg \
-cpu max -m "$RAM_MB" -smp "$SMP" \
-display none -monitor none \
-serial "file:$SERIAL_LOG" \
-drive "if=pflash,format=raw,readonly=on,file=$OVMF_CODE" \
-drive "if=pflash,format=raw,file=$VARS" \
-drive "if=virtio,file=$DISK,format=raw,cache=none" \
-cdrom "$ISO" \
-boot order=d,menu=off \
-netdev user,id=n0 -device virtio-net-pci,netdev=n0 \
-no-reboot
rc=$?
set -e
if [[ $rc -ne 0 ]]; then
echo "installer QEMU exit $rc — see $SERIAL_LOG"
tail -40 "$SERIAL_LOG"
exit "$rc"
fi
if grep -q "INSTALLATION COMPLETE\|installation complete\|powering off" "$SERIAL_LOG"; then
blue "niri install completed; disk -> $DISK"
blue "run: tests/boot-niri-interactive.sh to boot it in a GUI window"
else
echo "WARNING: no completion marker in $SERIAL_LOG"
tail -30 "$SERIAL_LOG"
exit 1
fi

242
tests/run-qemu-test.sh Executable file
View File

@@ -0,0 +1,242 @@
#!/bin/bash
# Automated headless QEMU smoke test for the Void installer.
#
# Workflow:
# 1. Build (or reuse) a TEST variant of the ISO with UNATTENDED=1 +
# TEST_MODE=1 and our test pubkey baked in for moze@.
# 2. Build a fresh test disk image mimicking the XPS 17 layout.
# 3. Boot the ISO under QEMU/OVMF; installer runs unattended; VM powers off.
# 4. Boot the installed disk; ssh in as moze; run smoke checks.
set -Eeuo pipefail
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
OUT_DIR="$PROJECT_DIR/out"
LOG_DIR="$OUT_DIR/qemu-logs"
mkdir -p "$OUT_DIR" "$LOG_DIR"
QEMU="${QEMU:-qemu-system-x86_64}"
OVMF_CODE="${OVMF_CODE:-}"
OVMF_VARS_TPL="${OVMF_VARS_TPL:-}"
RAM_MB="${RAM_MB:-4096}"
SMP="${SMP:-4}"
SSH_PORT="${SSH_PORT:-2222}"
TIMEOUT_INSTALL="${TIMEOUT_INSTALL:-3600}"
TIMEOUT_BOOT="${TIMEOUT_BOOT:-300}"
ACCEL="${ACCEL:-kvm:tcg}"
# Auto-detect OVMF paths.
for c in /usr/share/OVMF/OVMF_CODE.fd /usr/share/edk2-ovmf/x64/OVMF_CODE.fd \
/usr/share/edk2/x64/OVMF_CODE.fd /usr/share/qemu/OVMF_CODE.fd; do
[[ -z "$OVMF_CODE" && -r "$c" ]] && OVMF_CODE="$c"
done
for v in /usr/share/OVMF/OVMF_VARS.fd /usr/share/edk2-ovmf/x64/OVMF_VARS.fd \
/usr/share/edk2/x64/OVMF_VARS.fd /usr/share/qemu/OVMF_VARS.fd; do
[[ -z "$OVMF_VARS_TPL" && -r "$v" ]] && OVMF_VARS_TPL="$v"
done
[[ -r "$OVMF_CODE" ]] || { echo "OVMF_CODE not found"; exit 1; }
[[ -r "$OVMF_VARS_TPL" ]] || { echo "OVMF_VARS not found"; exit 1; }
red() { printf '\033[31m%s\033[0m\n' "$*" >&2; }
green() { printf '\033[32m%s\033[0m\n' "$*"; }
blue() { printf '\033[34m==> %s\033[0m\n' "$*"; }
# ---------- 0) start xbps caching proxy ----------
blue "starting XBPS caching proxy"
"$PROJECT_DIR/tools/start-xbps-proxy.sh"
PIDFILE="$OUT_DIR/qemu.pid"
cleanup_all() {
# Kill any QEMU started by this run (pidfile + name fallback).
[[ -f "$PIDFILE" ]] && kill "$(cat "$PIDFILE")" 2>/dev/null || true
rm -f "$PIDFILE"
# Defensive: kill any lingering qemu by our unique -name tags.
pkill -f 'qemu-system.*void-install(er-test|ed-test)' 2>/dev/null || true
"$PROJECT_DIR/tools/stop-xbps-proxy.sh" 2>/dev/null || true
}
trap cleanup_all EXIT INT TERM
# ---------- 1) test ssh keypair ----------
TEST_KEY="$OUT_DIR/id_test"
if [[ ! -f "$TEST_KEY" ]]; then
blue "generating test ssh keypair"
ssh-keygen -t ed25519 -N '' -C 'qemu-test' -f "$TEST_KEY" >/dev/null
fi
TEST_PUBKEY=$(cat "${TEST_KEY}.pub")
export TEST_PUBKEY
# ---------- 2) build TEST ISO ----------
TEST_ISO="$OUT_DIR/void-install-TEST.iso"
TEST_OVERLAY_DIR="$OUT_DIR/test-overlay"
"$PROJECT_DIR/tests/lib/make-test-overlay.sh" "$TEST_OVERLAY_DIR"
if [[ ! -f "$TEST_ISO" || -n "${REBUILD_ISO:-}" ]]; then
blue "building test ISO -> $TEST_ISO"
EXTRA_INCLUDE_DIR="$TEST_OVERLAY_DIR" \
OUTPUT_ISO="$TEST_ISO" \
INSTALL_REPO_URL="http://10.0.2.2:3142/current" \
BOOT_CMDLINE="console=tty0 console=ttyS0,115200" \
"$PROJECT_DIR/iso/build-iso.sh"
else
blue "reusing cached test ISO $TEST_ISO (set REBUILD_ISO=1 to rebuild)"
fi
# ---------- 3) test disk ----------
DISK="$OUT_DIR/test-disk.img"
blue "creating fresh test disk -> $DISK"
"$PROJECT_DIR/tests/make-test-disk.sh" "$DISK"
# ---------- 4) OVMF VARS copy ----------
VARS="$OUT_DIR/OVMF_VARS.fd"
cp "$OVMF_VARS_TPL" "$VARS"
# ---------- 5) install phase ----------
blue "boot ISO + run installer (timeout ${TIMEOUT_INSTALL}s)"
SERIAL_LOG="$LOG_DIR/install.serial.log"
: > "$SERIAL_LOG"
set +e
timeout "$TIMEOUT_INSTALL" "$QEMU" \
-name void-installer-test \
-machine q35,accel="$ACCEL" \
-cpu max \
-m "$RAM_MB" \
-smp "$SMP" \
-display none \
-monitor none \
-serial "file:$SERIAL_LOG" \
-drive "if=pflash,format=raw,readonly=on,file=$OVMF_CODE" \
-drive "if=pflash,format=raw,file=$VARS" \
-drive "if=virtio,file=$DISK,format=raw,cache=none" \
-cdrom "$TEST_ISO" \
-boot order=d,menu=off \
-netdev user,id=n0 -device virtio-net-pci,netdev=n0 \
-no-reboot
RC=$?
set -e
blue "install QEMU exited rc=$RC"
if ! grep -q 'Installation complete' "$SERIAL_LOG"; then
echo "------ tail of $SERIAL_LOG ------" >&2
tail -200 "$SERIAL_LOG" >&2 || true
red "installer did not report 'Installation complete'"; exit 1
fi
green "installer reported success"
# ---------- 6) boot installed system ----------
blue "boot installed system, ssh on 127.0.0.1:$SSH_PORT"
BOOT_LOG="$LOG_DIR/boot.serial.log"
: > "$BOOT_LOG"
"$QEMU" \
-name void-installed-test \
-machine q35,accel="$ACCEL" \
-cpu max \
-m "$RAM_MB" \
-smp "$SMP" \
-display none \
-serial "file:$BOOT_LOG" \
-drive "if=pflash,format=raw,readonly=on,file=$OVMF_CODE" \
-drive "if=pflash,format=raw,file=$VARS" \
-drive "if=virtio,file=$DISK,format=raw,cache=none" \
-netdev "user,id=n0,hostfwd=tcp:127.0.0.1:$SSH_PORT-:22" \
-device virtio-net-pci,netdev=n0 \
-daemonize \
-pidfile "$PIDFILE"
blue "waiting for sshd"
SSH_READY=0
for i in $(seq 1 "$TIMEOUT_BOOT"); do
if ssh -i "$TEST_KEY" -o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
-o ConnectTimeout=2 -o BatchMode=yes \
-p "$SSH_PORT" moze@127.0.0.1 true 2>/dev/null; then
SSH_READY=1
green "ssh reachable after ${i}s"
break
fi
sleep 1
done
if [[ $SSH_READY -ne 1 ]]; then
tail -200 "$BOOT_LOG" >&2 || true
red "sshd never came up"
exit 1
fi
# ---------- 7) smoke checks ----------
blue "running smoke tests"
SSHCMD=(ssh -i "$TEST_KEY" -o StrictHostKeyChecking=no
-o UserKnownHostsFile=/dev/null -p "$SSH_PORT" moze@127.0.0.1)
FAILED=0
assert() {
local desc="$1"; shift
if "${SSHCMD[@]}" "$@" >/dev/null 2>&1; then
green " ok $desc"
else
red " FAIL $desc"
FAILED=$((FAILED+1))
fi
}
assert "/ on btrfs subvol=@" "findmnt -no FSTYPE,OPTIONS / | grep -q 'subvol=/@'"
assert "user moze in wheel" "id -nG moze | tr ' ' '\\n' | grep -qx wheel"
assert "user moze in docker" "id -nG moze | tr ' ' '\\n' | grep -qx docker"
assert "sudo via wheel" "sudo -n -l | grep -q 'ALL'"
assert "cinnamon-session present" "command -v cinnamon-session"
assert "lightdm enabled" "test -L /var/service/lightdm"
assert "docker enabled" "test -L /var/service/docker"
assert "vscode (code) installed" "command -v code"
assert "nvidia kmod metadata" "modinfo nvidia"
assert ".ssh dir mode 700" "test \$(stat -c '%a' /home/moze/.ssh) = 700"
assert "id_github private key" "test -f /home/moze/.ssh/id_github"
assert "ssh config copied" "test -f /home/moze/.ssh/config"
assert "EFI vfat mounted" "findmnt -no FSTYPE /boot/efi | grep -q vfat"
assert "EFI/Microsoft preserved" "test -f /boot/efi/EFI/Microsoft/Boot/bootmgfw.efi"
assert "GRUB has Void entry" "sudo -n grep -q -i 'Void' /boot/grub/grub.cfg"
assert "nix-daemon running" "pgrep -x nix-daemon"
assert "zram swap active" "swapon --show=NAME --noheadings | grep -q '^/dev/zram'"
assert "hostname is xps9700" "test \$(hostname) = xps9700"
assert "timezone is Europe/Zurich" "readlink /etc/localtime | grep -q 'Europe/Zurich'"
assert "keymap ch-fr_nodeadkeys" "grep -q 'ch-fr_nodeadkeys' /etc/rc.conf"
assert "alacritty installed" "command -v alacritty"
assert "no firefox installed" "! command -v firefox"
assert "gruvbox theme present" "ls -d /usr/share/themes/Gruvbox* >/dev/null 2>&1"
assert "gruvbox-dark exact" "test -d /usr/share/themes/Gruvbox-Dark"
assert "gruvbox icons present" "ls -d /usr/share/icons/Gruvbox-Plus-Dark >/dev/null 2>&1"
assert "bibata cursor present" "test -d /usr/share/icons/Bibata-Modern-Ice"
assert "dconf cursor=bibata" "grep -q \"cursor-theme='Bibata-Modern-Ice'\" /etc/dconf/db/local.d/00-cinnamon"
assert "dconf gtk=Gruvbox-Dark" "grep -q \"gtk-theme='Gruvbox-Dark'\" /etc/dconf/db/local.d/00-cinnamon"
assert "wallpapers deployed" "test -f /usr/share/backgrounds/void-installer/pxfuel.jpg"
assert "user .bashrc deployed" "grep -q 'NVM_DIR' /home/moze/.bashrc"
assert "vscode settings deployed" "test -f /home/moze/.config/Code/User/settings.json"
assert "X11 keymap pinned ch(fr)" "grep -q 'XkbLayout.*ch' /etc/X11/xorg.conf.d/00-keyboard.conf"
assert "dconf cinnamon defaults" "test -f /etc/dconf/db/local.d/00-cinnamon"
assert "first-login script staged" "test -x /usr/local/libexec/first-login.sh"
assert "first-login autostart" "test -f /etc/xdg/autostart/void-installer-first-login.desktop"
assert "local-bin profile.d" "test -f /etc/profile.d/local-bin.sh"
assert "claude installer used" "grep -q 'claude.ai/install.sh' /usr/local/libexec/first-login.sh"
assert "nix unfree allowed" "grep -q 'NIXPKGS_ALLOW_UNFREE' /usr/local/libexec/first-boot-nix.sh"
assert "vscode-extensions list" "test -f /etc/installer-vscode-extensions.txt"
assert "cups installed" "command -v cupsd"
assert "cups service enabled" "test -L /etc/runit/runsvdir/default/cupsd"
assert "timeshift installed" "command -v timeshift"
assert "flameshot installed" "command -v flameshot"
assert "libinput-gestures present" "command -v libinput-gestures"
assert "gestures default config" "test -f /etc/skel/.config/libinput-gestures.conf"
assert "btrfs snapshot hook" "test -x /usr/local/sbin/xbps-pre-upgrade-snapshot.sh"
assert "xbps-install wrapper" "test -x /usr/local/bin/xbps-install"
assert "void-upgrade GUI" "test -x /usr/local/bin/void-upgrade-gui"
assert "void-upgrade .desktop" "test -f /usr/share/applications/void-upgrade.desktop"
assert "Print Screen -> flameshot" "grep -q 'Print' /etc/dconf/db/local.d/00-cinnamon"
assert "tray applets configured" "grep -q 'systray@cinnamon.org' /etc/dconf/db/local.d/00-cinnamon"
assert "Nemo VS Code action" "test -f /usr/share/nemo/actions/open-vscode.nemo_action"
cleanup_all
echo
if [[ $FAILED -eq 0 ]]; then
green "ALL SMOKE TESTS PASSED"
exit 0
else
red "$FAILED smoke test(s) failed"
exit 1
fi