aboutsummaryrefslogtreecommitdiff
path: root/tests/installer-steps
Commit message (Collapse)AuthorAgeFilesLines
* fix(installer): guard the cp and chmod that install helper scriptsCraig Jennings3 days1-0/+66
| | | | | | With `set -e` off, the installer copied its zfs-replicate, zfs-pre-snapshot, and hypr-live-update-guard scripts into place with bare cp/chmod. A missing or partial source failed silently, leaving a systemd service with a dead ExecStart or a pacman hook pointing at a script that never landed. The two zfs scripts now install through install_executable, which guards the copy, warns on failure, and skips the chmod when the copy did not land. The two live-update-guard chmods (the guard binary and its hook) are guarded inline with error_warn.
* fix(installer): make three resume-fragile steps idempotent and correctCraig Jennings3 days1-0/+119
| | | | | | | | | | Each of these steps misbehaves on a resume re-run or under unexpected system state, so I pulled the logic into small testable helpers and fixed the behavior. The log-cleanup cron line was appended unconditionally. essential_services is one resume step, so a failure past that point plus a re-run stacked a second identical cron line every time. crontab_append_once now appends only when no existing line matches. The weekly ZFS scrub timer used `zpool list | head -1`, which picks an arbitrary pool when several exist and builds the malformed unit `zfs-scrub-weekly@.timer` when none do. zfs_scrub_timer_units emits one timer per pool and nothing for no pools, so every pool is scrubbed and an absent pool warns instead of enabling a broken unit. gamemode was enabled through `systemctl --user enable`, which the script itself documents fails at install time with no user session bus -- so gamemoded was likely left un-enabled behind a silent warning. It now wires the wants symlink by hand through enable_user_service, the same helper syncthing's block folds into.
* fix(installer): validate sudoers.pacnew with visudo before copyingCraig Jennings3 days1-0/+76
| | | | | | The installer copied /etc/sudoers.pacnew over /etc/sudoers with no validation. A malformed pacnew that sudo refuses to parse would replace a working sudoers with an unparseable one, locking out privilege escalation right before the NOPASSWD rule gets appended. replace_sudoers_pacnew now runs `visudo -cf` on the pacnew first and only copies a file that validates; a failure warns and leaves the current sudoers in place. Extracted the logic into a function taking the pacnew and target as positional args defaulting to the system paths, so the guard can run against fixtures.
* fix(installer): record the state marker on non-fatal step warningsCraig Jennings3 days1-0/+92
| | | | | | run_step marked a step complete only when its function returned 0. But error_fatal exits the script outright, so a step function that returns at all has already cleared every fatal check -- a non-zero return can only be a trailing non-fatal warning, since error_warn returns 1. The old code read that as a failure and withheld the state marker, so the step re-ran on every resume even though its body had finished. run_step now records the marker whenever the function returns and logs a warning line when the return was non-zero. Two smaller fixes alongside it. run_step's step_name/step_func and show_status's step/timestamp now use local so they stop leaking to global scope. The package-cache refresh loop captures pacman's real exit code instead of reading `$?` off the `$refresh_ok` test, which always read 1 and made error_fatal report "error code: 0" -- the same trap retry_install already documents.
* fix(installer): harden the disk-space pre-flight gateCraig Jennings3 days1-0/+94
| | | | | | | | `df /` wraps to two lines when the root device name is long -- a device-mapper or live-ISO root -- so `awk 'NR==2 {print $4}'` read the wrapped device line, found an empty Available field, and aborted a valid install with "Insufficient disk space." `df -P` forces POSIX single-line output. The gate now compares available KB against the minimum in KB rather than truncating to GB first, which rejected a disk sitting just under a whole-GB boundary. Non-numeric df output falls back to zero so a malformed read aborts loudly instead of crashing the arithmetic test. Extracted the logic into check_disk_space so it can be exercised directly.
* fix(installer): guard the user-password chpasswdCraig Jennings3 days1-0/+56
| | | | set -e is off, so a chpasswd failure silently left the primary user with no password and no log entry, leaving an unloggable account on a fresh install. I extracted set_user_password, which aborts via error_fatal on a chpasswd failure. A fake-chpasswd test pins that the guard fires.
* feat: add inetutils to the install baseCraig Jennings3 days1-0/+58
| | | | TRAMP's /ftp: method shells out to a command-line ftp client, and Arch ships none by default. inetutils provides /usr/bin/ftp, so I added it to install_required_software. A static test asserts it stays in the base set.
* fix: order pacman safety hooksCraig Jennings5 days1-0/+27
| | | | Install snapshot and live-update hooks before mkinitcpio removal, migrate legacy paths, and cover the ordering invariant.
* fix(install): mark pacman packages explicit after --needed installCraig Jennings2026-07-081-0/+95
| | | | | | pacman --needed skips a package that is already on the system as a dependency and leaves its install reason alone. A declared package can then sit as asdeps, surface as an orphan once its accidental dependent leaves, and get swept away by an orphan cleanup. expac and lm_sensors, both maintenance-console runtime deps, nearly went this way: they were asdeps on both hosts and only survived today's orphan sweep because something still depended on them. pacman_install now marks the package explicit after a successful install. The mark never runs on a failed install, and a mark failure never fails the install. I flipped expac and lm_sensors to explicit on ratio and velox by hand since the installer only runs on fresh systems.
* feat(install): install maintenance thresholds and enable maint timersCraig Jennings2026-07-081-1/+32
| | | | | | | | The maint console and the system-health-check workflow grade against ~/.config/archsetup/maintenance-thresholds.toml, but nothing installed it. A fresh install got a working maint CLI and no thresholds file. user_customizations now installs the shipped TOML from the cloned repo. A re-run refreshes it, and the user layer in ~/.config/maint/ is never touched, so a reinstall can't eat curation. It also enables maint-scan.timer and maint-net-scan.timer through wants-symlinks (systemctl --user has no session bus during install, the syncthing idiom). Timer enablement is hyprland-only because the units live in that stow tier. The install lists gain the runtime tools the probes call but nothing carried: expac, lm_sensors, fwupd.
* feat: install pre-pacman ZFS snapshot hook on ZFS-root systemsCraig Jennings2026-06-301-0/+1
| | | | | | archsetup took sanoid from install-archzfs but never ported the pre-pacman snapshot hook, so a ZFS-root install had no transaction-triggered rollback point — the working setup only existed as a hand-placed script on velox, lost on reinstall. Add configure_pre_pacman_snapshots(): a PreTransaction pacman hook plus a self-pruning script that keeps the 10 most recent pre-pacman snapshots (sanoid ignores them — they aren't autosnap_ names). It's gated to ZFS-root and runs late in boot_ux, so the hook doesn't fire during the install's own package operations and the first snapshot is the fresh system. The script ships as scripts/zfs-pre-snapshot, made ZFS_PRE_* env-overridable so the pruning logic is unit-testable. Unit tests drive it against a fake zfs (creates a snapshot, prunes the oldest past KEEP, ignores non-pre-pacman snapshots, honors the lockfile interval, warns on failure); a Testinfra test asserts the hook and script land on a ZFS install; the orchestrator test pins the new boot_ux substep.
* test: pin installer orchestrator call sequencesCraig Jennings2026-06-271-0/+117
The decomposition left each big step function as a thin list of sub-step calls with no runtime coverage. These tests sed-extract each orchestrator, stub its sub-functions as recorders, and assert the exact call order, so a dropped or reordered step fails the suite. configure_snapshots also gets a per-filesystem dispatch check (zfs / btrfs / other).