From b6525a50fabf3aedf41eee70c164519b00d27704 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Fri, 22 May 2026 18:03:40 -0500 Subject: feat(install): add pre-flight environment and disk-target validation archangel went straight from filesystem selection into a destructive install behind only a root check and a ZFS module load. A missing tool, a BIOS boot, a too-small or in-use disk, or a dead network surfaced as a confusing abort partway through, sometimes after partitioning had already run. Two gates now fail fast. validate_environment runs after filesystem selection, before any disk is touched: it confirms UEFI boot mode and that every required command is present, with the list coming from a new required_commands helper built like pacstrap_packages. validate_install_targets runs after disk selection, before the first wipe: it refuses a target that's mounted, holds active swap, or belongs to an imported pool or md array, rejects disks under 20 GB, and confirms a mirror is reachable via DNS plus a TCP probe (no ICMP, since some networks drop it). I folded the install_failure_cleanup hardening into the same change. It now falls back to lazy unmounts, so a pacstrap-interrupted target with busy bind mounts still releases the pool and unmounts the EFI partition. Without that, the disk-in-use guard would block the very retry the cleanup exists to enable. "Re-run to retry" only holds if the disk is genuinely freed first. The 20 GB floor is decimal on purpose. It reads as the natural minimum and clears a 20 GiB disk image with headroom instead of sitting on the boundary. --- tests/unit/test_common.bats | 48 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'tests/unit/test_common.bats') diff --git a/tests/unit/test_common.bats b/tests/unit/test_common.bats index 8ce7280..a639a4e 100644 --- a/tests/unit/test_common.bats +++ b/tests/unit/test_common.bats @@ -520,3 +520,51 @@ Boot0001* ZFSBootMenu" grep -qF 'HOOKS=(base udev)' "$f" rm -f "$f" } + +############################# +# required_commands +############################# + +@test "required_commands zfs includes zpool and zfs" { + run required_commands zfs + [ "$status" -eq 0 ] + [[ "$output" == *"zpool"* ]] + [[ "$output" == *"zfs"* ]] +} + +@test "required_commands btrfs includes mkfs.btrfs and grub-install" { + run required_commands btrfs + [ "$status" -eq 0 ] + [[ "$output" == *"mkfs.btrfs"* ]] + [[ "$output" == *"grub-install"* ]] +} + +@test "required_commands zfs excludes Btrfs-specific commands" { + run required_commands zfs + [ "$status" -eq 0 ] + [[ "$output" != *"mkfs.btrfs"* ]] + [[ "$output" != *"grub-install"* ]] +} + +@test "required_commands btrfs excludes the zpool command" { + run required_commands btrfs + [ "$status" -eq 0 ] + [[ "$output" != *"zpool"* ]] +} + +@test "required_commands includes partitioning + pacstrap commands for both filesystems" { + for fs in zfs btrfs; do + run required_commands "$fs" + [ "$status" -eq 0 ] + [[ "$output" == *"sgdisk"* ]] + [[ "$output" == *"wipefs"* ]] + [[ "$output" == *"partprobe"* ]] + [[ "$output" == *"mkfs.fat"* ]] + [[ "$output" == *"pacstrap"* ]] + done +} + +@test "required_commands unknown filesystem returns 1" { + run required_commands ext4 + [ "$status" -eq 1 ] +} -- cgit v1.2.3