diff options
| author | Craig Jennings <c@cjennings.net> | 2026-04-26 01:31:38 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-04-26 01:31:38 -0500 |
| commit | 6de9f378cf52b9e9b0e89b396a12b978700241ff (patch) | |
| tree | 9de36ebe2de4686970c8fd2bb4c124b403410bd6 /scripts | |
| parent | 1a261b0c220903c8bb628e7f2b94cf75a843f688 (diff) | |
| download | archangel-6de9f378cf52b9e9b0e89b396a12b978700241ff.tar.gz archangel-6de9f378cf52b9e9b0e89b396a12b978700241ff.zip | |
fix: clean up partial installs via ERR/INT/TERM trap
Failed installs left the system in an inconsistent state: /mnt mounted, the zpool imported, possibly LUKS containers open. The user had to manually unmount, export the pool, and clean up partitions before re-running the installer. The existing trap at the top of archangel was `trap 'error "Installation interrupted!"' INT TERM`. It just printed a message and exited. There was no ERR trap, so `set -e`-aborted commands ran no cleanup either.
I added `install_failure_cleanup` next to the existing `cleanup`. It captures `$?` first, disarms the trap to prevent recursion, clears sensitive variables (ROOT_PASSWORD, ZFS_PASSPHRASE, LUKS_PASSPHRASE), and dispatches on FILESYSTEM:
- ZFS path: unmount /mnt/efi, recursive umount /mnt, export the pool (with `-f` fallback) if it's still imported.
- Btrfs path: unmount /mnt/efi, call the existing btrfs_cleanup and btrfs_close_encryption helpers.
All cleanup steps swallow their own errors with `|| true` since partial state is expected when this fires mid-install.
`install_zfs` and `install_btrfs` now both arm the trap as their first action and disarm it just before the success-path cleanup. The disarm matters because the success cleanup calls `zpool export` (or btrfs_close_encryption) directly, and those can produce non-zero exit codes that we don't want to interpret as "installation failed".
The note in notes.org described this as "install_zfs has no mid-step recovery." The framing was off. Both paths were exposed: install_btrfs's `btrfs_cleanup` only runs on the success path, same as `cleanup` for ZFS. Both paths now have the same recovery shape.
Added 4 bats tests for `install_failure_cleanup` that mock the system tools (umount, zpool, btrfs_cleanup, btrfs_close_encryption) via function override and track invocations through a CALLS array. Array assignment isn't affected by the production code's `>/dev/null 2>&1` redirects on `zpool list`, so we capture the call regardless of where the mock's stdout would have gone.
Verified end-to-end on the dev box: sourced archangel, set FILESYSTEM=zfs, armed the trap, ran `false` to trigger `set -e`. The trap fired with exit code 1, dispatched to the ZFS cleanup path, called `umount /mnt/efi` and `umount -R /mnt`, checked `zpool list` (returned non-zero since no pool exists on the dev box), skipped the export, and exited via `error`.
No behavior change on the success path. The existing `cleanup` and `btrfs_cleanup` stay unchanged.
Diffstat (limited to 'scripts')
0 files changed, 0 insertions, 0 deletions
