aboutsummaryrefslogtreecommitdiff
path: root/scripts
Commit message (Collapse)AuthorAgeFilesLines
* test(vm): assert the live-update guard + hook are installedCraig Jennings12 hours1-0/+13
|
* feat(hyprland): guard against live GPU/compositor library upgradesCraig Jennings12 hours1-0/+70
| | | | | | | | | | | | | | | | | | | | | | A pacman -Syu that swaps mesa/hyprland/wayland runtime libs out from under a running Hyprland session crashes the compositor: the next GPU-lib call hits a now-"(deleted)" library and SIGABRTs, taking the Wayland clients with it (hit ratio 2026-06-07, mesa + hyprland upgraded live). It's a likely driver of ratio's high unsafe-shutdown ratio. I added a pacman PreTransaction hook (hypr-live-update-guard) on the GPU/compositor runtime set. When such an upgrade is pending and Hyprland is running, it aborts before any package is swapped and tells the user to re-run from a TTY with the session stopped. Aborting at PreTransaction is safe: nothing is replaced yet, so the live session is untouched. With no Hyprland running (the from-a-TTY path) the guard stays quiet and the upgrade proceeds. Override with HYPR_ALLOW_LIVE_UPDATE=1 or by touching the sentinel file named in the abort message. archsetup installs the guard and hook in the hyprland path. The decision logic is covered by tests/hypr-live-update-guard (running/not, override, multi-package, empty-target). The hook firing against a real pacman transaction needs a live Hyprland session, filed as a manual test.
* fix(test): bump default VM RAM to 8 GiB to stop AUR-build OOM killsCraig Jennings16 hours1-1/+3
| | | | | | | | The zfs green run OOM-killed cc1plus three times during AUR C++ builds: makepkg runs -j$VM_CPUS (4), and parallel compiles at ~700 MB each overran the 4 GiB default. The install still passed (yay retries), but the kills showed up as attributed issues. 8 GiB gives the four jobs headroom. Overridable via VM_RAM as before.
* fix(test): give each filesystem profile its own OVMF NVRAM fileCraig Jennings20 hours1-1/+5
| | | | | | | | | | | | | init_vm_paths suffixed the disk image per profile but shared one OVMF_VARS.fd across btrfs and zfs. NVRAM holds the UEFI boot entries and lives outside the qcow2, so a disk-snapshot revert can't restore it. A zfs run's ZFSBootMenu entries clobbered the btrfs GRUB entry, and with no removable ESP fallback the btrfs base then booted to "no bootable device" and timed out before archsetup ran. NVRAM now carries the same per-profile suffix as the disk image, so the two profiles keep separate boot state. Validated by a full green zfs run (ArchSetup exit 0, Testinfra 96 passed / 0 failed).
* refactor(testing): delete the dead validation.sh shell sweepCraig Jennings3 days1-842/+0
| | | | | | Both runners now validate through run_testinfra_validation, so the shell sweep validation.sh ran is dead. Delete run_all_validations, validate_all_services, run_full_validation, the ~35 validate_* checks, and validation_pass/fail/warn/skip (called only by those checks). Keep the live helpers the runners and testinfra.sh still use: ssh_cmd, attribute_issue, capture_pre/post_install_state, analyze_log_diff, categorize_errors, generate_issue_report, and the VALIDATION_* counters plus issue arrays. The file drops from 1156 lines to 314. Closes the P5 follow-up from the Testinfra cutover.
* fix(testing): keep the bare-metal runner past a failing Testinfra sweepCraig Jennings3 days1-4/+7
| | | | run-test-baremetal.sh runs under set -e, and the P-D migration left run_testinfra_validation called bare. It returns pytest's rc, so a failing sweep aborted the script before it wrote the report or the TEST FAILED summary. The old run_all_validations returned 0 and never tripped set -e. Mirror the VM runner: set +e around the call, capture the rc, and derive TEST_PASSED from it so the report and summary always run.
* test(archsetup): migrate bare-metal runner to key auth + TestinfraCraig Jennings3 days2-16/+40
| | | | | | | | | | run-test-baremetal.sh SSHed to the target as root by password throughout, which archsetup's sshd hardening (PermitRootLogin prohibit-password) kills mid-install, the same break the VM runner already fixed. It also still called the validation.sh shell sweep (run_all_validations, validate_all_services, validate_zfs_services), the last caller keeping those functions alive. It now mirrors the VM runner. After the first SSH, and after any genesis rollback so the key survives it, inject_root_key authorizes a throwaway root key, and every later ssh_cmd plus the raw scp transfers and log-copies thread SSH_KEY_OPT to survive the hardening. The shell sweep is replaced with run_testinfra_validation, now the authoritative validator on both runners. A --port option, threaded through every SSH and scp, lets the runner target a test VM on 2222 instead of only real hardware on 22. inject_root_key now authorizes root@$VM_IP instead of root@localhost, so one helper serves both runners (the VM runner sets VM_IP=localhost). Validated against the ZFS VM (--validate-only, localhost:2222): connectivity, the ZFS check, key authorization, and the Testinfra sweep all connect and run over the key-based ssh-config. A green bare-metal install still needs real ZFS hardware.
* test(archsetup): branch boot/backup checks on the ZFS boot pathCraig Jennings3 days2-7/+37
| | | | | | The Testinfra boot and backup checks asserted btrfs behavior unconditionally, so they failed on a ZFS root once the ZFS VM path started running them. ZFS boots via ZFSBootMenu, not GRUB. archsetup skips the systemd-hook switch and the mkinitcpio rebuild on ZFS, and on a ZFS+virtio VM it never edits mkinitcpio.conf at all. Branch each check on the existing zfs_root/has_nvme fixtures: assert the ZFSBootMenu EFI binary on ZFS (GRUB on btrfs), gate the mkinitcpio.conf backup on archsetup actually editing the file, and check the console font in /etc/vconsole.conf on ZFS (the initramfs on non-ZFS). Surfaced by the first full ZFS VM run, which completed archsetup cleanly (exit 0). These were the only 3 failures.
* test(archsetup): add FS_PROFILE selector for ZFS VM coverageCraig Jennings3 days4-3/+56
| | | | | | | | | | The VM harness only built one btrfs base image, so every ZFS-conditional check in the Testinfra suite skipped and the ZFS install path went untested in automation. I added an FS_PROFILE selector (btrfs default, zfs) so `make test FS_PROFILE=zfs` can target a ZFS root. init_vm_paths derives the image name from FS_PROFILE and validates it. btrfs keeps the legacy unsuffixed archsetup-base.qcow2 so existing images and invocations are untouched. The zfs profile gets archsetup-base-zfs.qcow2. create-base-vm.sh picks archsetup-test.conf vs the new archsetup-test-zfs.conf (FILESYSTEM=zfs, NO_ENCRYPT=yes for an unattended install), and the Makefile resolves the matching image for its base-VM check. The archsetup run config stays shared. archsetup reads no filesystem key. It detects ZFS from the live root via is_zfs_root, so the ZFS branch fires on its own once the base image is ZFS. The design doc is reconciled to that: no separate archsetup-vm-zfs.conf, and the non-ZFS profile is btrfs, not ext4. Building the ZFS base image and running the ZFS sweep green is next.
* fix(testing): raise the install monitor timeout to 150 minutesCraig Jennings3 days1-2/+3
| | | | | | | | A full archsetup install with heavy AUR builds (vagrant and its git-cloned installers) can run past the old 90-minute monitor cap on a slow mirror. When that happened the run stopped monitoring mid-install and validated a half-installed system, producing spurious late-step failures. Raise MAX_POLLS from 180 to 300 (90 -> 150 minutes) so a slow-but-healthy install completes.
* test(archsetup): make Testinfra the authoritative validator (P3 cutover)Craig Jennings3 days2-39/+66
| | | | | | | | | | | | | run-test.sh no longer runs the shell run_all_validations sweep; the Testinfra pytest sweep now drives the run's pass/fail. run_testinfra_validation returns pytest's exit code (and treats "could not run" as a failure, not a silent pass), surfaces the pass/skip/fail counts through the shared VALIDATION_* counters, and parses the attribution file so generate_issue_report still buckets failures into archsetup / base_install / unknown. The shell-sweep functions stay in validation.sh for now because run-test-baremetal.sh still calls them; removing them (after migrating the bare-metal runner) is filed as a follow-up.
* test(archsetup): expand validation coverage + fix ParallelDownloads (P4)Craig Jennings3 days3-0/+135
| | | | | | | | | | | | | | | | | | Add post-install checks beyond the original shell sweep, validated against a live VM: test_hardening (sshd prohibit-password, quiet-printk sysctl, emptied /etc/issue, console font, EFI mount perms), test_config_applied (pacman ParallelDownloads/Color/multilib, makepkg flags, NetworkManager drop-ins, fail2ban jail, reflector), and test_backups (the .archsetup.bak files backup_system_file leaves behind — end-to-end proof of that feature). The new tests caught a real bug: ParallelDownloads stayed at Arch's default 5 because the sed only matched a commented "#ParallelDownloads", but current Arch ships it uncommented. Match both (^#?ParallelDownloads) so the intended 10 takes effect. Verified against a kept VM: 95 passed, 10 skipped (the one remaining failure was the pre-fix ParallelDownloads on the already-built VM, which the sed fix resolves on the next fresh install).
* test(archsetup): fix fixture scope and initramfs path in the sweepCraig Jennings3 days2-10/+14
| | | | | | | | | | | | | VM run #2 exposed two test bugs (archsetup itself passed clean, 53/0/0): - ScopeMismatch errors on 26 tests: the host-dependent fixtures were session-scoped, but Testinfra's host fixture is module-scoped, and a session fixture cannot request a module one. Drop those fixtures to module scope. - test_console_font_in_initramfs hardcoded /boot/initramfs-linux.img; this fleet runs linux-lts, so the image is initramfs-linux-lts.img. Pick the main (non-fallback) initramfs by glob instead.
* fix(testing): authorize a root key so make test survives sshd hardeningCraig Jennings4 days4-19/+63
| | | | | | The VM test SSHes into the guest as root with a password for the whole run. archsetup hardens sshd to PermitRootLogin prohibit-password and reloads it partway through the install, so every SSH after that step failed with "Permission denied" and the run aborted before any validation — make test had been silently broken since the hardening landed. inject_root_key authorizes a throwaway root key right after the first SSH (before archsetup runs) and the ssh/scp helpers now add -i <key> via SSH_KEY_OPT. prohibit-password still allows root key auth, so the harness survives the very hardening it validates. Password stays as the fallback, so the change is additive.
* test(archsetup): port full shell validation sweep to Testinfra (P2)Craig Jennings4 days8-6/+417
| | | | | | | | | | | | | | | | | | Port all ~26 post-install checks from validation.sh to pytest/Testinfra, reaching parity before the cutover. Adds test_users, test_packages, test_services, test_desktop, test_boot, test_keyring, and test_archsetup (88 tests after parametrizing groups, services, timers, tools, and configs), plus shared conftest fixtures for ZFS/NVMe/compositor/networking gating. The shell sweep's three outcomes map cleanly: hard failures become assertions, advisory warnings and unmet preconditions (headless compositor, slirp networking, optional services, non-ZFS/non-NVMe hosts) become skips. One correctness fix vs the shell sweep: check awww, not swww — archsetup installs awww (swww's successor) and `pacman -Q swww` no longer matches. Verified on the host: py_compile clean, pytest --collect-only green (88 tests). The sweep against a real VM is verified by the make test run that follows.
* test(archsetup): scaffold Testinfra post-install validation (P1)Craig Jennings4 days6-0/+209
| | | | | | | | Stand up the Testinfra/pytest harness alongside the existing shell sweep so the two can be compared for parity before pytest takes over. Adds scripts/testing/tests/ (conftest with failure attribution markers, a report hook, and a target_user fixture, plus three parity checks: user, ufw, dotfiles) and scripts/testing/lib/testinfra.sh, which injects a throwaway SSH key into the VM and runs pytest over SSH. The sweep is advisory here (RUN_TESTINFRA toggle, non-fatal) and does not yet affect pass/fail. Pulls python-pytest and python-pytest-testinfra into make deps. Verified on the host: py_compile clean, pytest --collect-only green, bash -n and shellcheck clean. The sweep running against a real VM is verified by the next make test run.
* chore: open-source release-prep (udev flag, SPDX headers, boolean style)Craig Jennings4 days20-0/+20
| | | | | | | | Three release cleanups, all behavior-preserving for my machines: - Gated the Logitech BRIO udev rule behind INSTALL_DEVICE_UDEV_RULES (default yes, opt-out), so the device-specific rule is off for anyone without that hardware. Added the config read, validation, and a conf.example entry. - Added a GPL-3.0-or-later SPDX-License-Identifier header after the shebang of all 24 shell scripts in the repo. - Standardized boolean conditionals on the explicit [ "$var" = "true" ] form, replacing the bare `if $var` idiom. The STEPS function-dispatch is left alone, since it runs a function name rather than testing a boolean.
* test(scripts): lock package-inventory behavior with characterization testsCraig Jennings14 days1-5/+10
| | | | | | | | package-inventory compares archsetup's declared packages against the live system but had no tests, so a future archsetup edit (a new for-loop shape, a renamed install helper) could silently break the extraction. I added two env seams so the script is testable without the real system. PKGINV_ARCHSETUP points the extractor at a fixture installer, PKGINV_PACMAN swaps in a fake pacman serving controlled query output. Both default to the real targets, so normal use is unchanged, and the seams match the env-override pattern audit-packages.sh already uses. The 7 tests pin the extraction (direct calls, for-loop lists, variable-arg skip) and both diff directions against the fixture, with no network or real pacman db. I also added a make package-diff target so the tool is reachable alongside the test targets.
* fix(testing): lingering check could never pass — ls output broke the captureCraig Jennings2026-06-111-2/+5
| | | | The check captured 'ls path && echo yes', so a present linger file produced 'path\nyes', which never string-equals yes — every run warned regardless of actual state. Forensics on a kept VM showed lingering correctly enabled all along (file present mid-install, loginctl Linger=yes, logind healthy): the original VM-artifact hypothesis was wrong, archsetup's enable-linger calls were always fine. test -e captures cleanly; verified returning 'yes' against the live VM.
* feat(scripts): package auditor + fix the four packages it caughtCraig Jennings2026-06-111-0/+135
| | | | | | scripts/audit-packages.sh extracts every pacman_install/aur_install package (loop lists included) and verifies each against its declared source — sync dbs for official, one batched RPC query for AUR — flagging movers in both directions. Unit-tested against fixture installers with fake pacman/curl. First real run over 420 packages found four that vanished from both sources, each now fixed: libva-mesa-driver folded into mesa (line dropped), nvidia-dkms replaced by nvidia-open-dkms (Turing+; legacy cards are the preflight task's problem), swww replaced by awww (its successor, already what both machines run), and libappindicator-gtk3 replaced by libayatana-appindicator. Fifteen AUR entries that graduated to official repos still install fine via yay and are left as-is.
* fix(testing): key the portal-query skip on the compositor, close warning tasksCraig Jennings2026-06-101-3/+5
| | | | The 19:06 verification run showed the portal skip not firing: a socket-activated xdg-desktop-portal process exists even headless, so the process check was the wrong precondition. The skip now keys on a running Hyprland, same as the socket check. That run confirmed the other three skips live (warnings 5 to 2); the remaining counted warnings are this portal case and the lingering question, which stays open.
* fix(testing): skip environment-impossible checks instead of warningCraig Jennings2026-06-101-8/+35
| | | | Four warnings fired on every headless VM run, training the reader to ignore the warning count: the Hyprland socket and portal queries (no graphical login), the mDNS ping (slirp passes no multicast), and docker-not-responding (enabled but deliberately not started pre-reboot). Each now detects its precondition and logs a skip that counts nowhere; the warn paths stay for the cases that are real (compositor running without a socket, portal running but unqueryable, mDNS failing on real networking, docker active but dead). The lingering warning stays — it needs its own investigation.
* fix(testing): expect minimal/ tree for the .zshrc symlink on DESKTOP_ENV=noneCraig Jennings2026-06-101-2/+5
| | | | The dotfiles validation hardcoded .dotfiles/common/.zshrc, but a none install stows the standalone minimal/ tree, so the first none-run ever to reach validation failed on a correct symlink. The expected path now follows DESKTOP_ENV from the VM conf.
* refactor: fold pocketbook in-tree and drop its install stepsCraig Jennings2026-05-261-1/+0
| | | | | | Pocketbook is nowhere near ready, so I pulled it back from publication: deleted the github mirror and the cjennings.net repo, removed the server mirror hook, and copied the package into pocketbook/ here until it's ready to spin back out. Dropped the steps that provisioned it on a fresh install: the gtk4-layer-shell dep and the pip install in archsetup, and the clone in post-install.sh. That clone pointed at the now-deleted github repo, so it would have failed a fresh run regardless. Re-wiring the install is tracked in the pocketbook backlog.
* fix(testing): expect ~/.dotfiles symlink target in dotfiles validationCraig Jennings2026-05-221-2/+4
|
* refactor(testing): clone the dotfiles repo into the VM testCraig Jennings2026-05-222-1/+32
| | | | The dotfiles live in a separate repo now, so the VM test clones that source, bundles it, and clones from the bundle into /tmp/dotfiles-test on the VM. archsetup's in-VM clone of DOTFILES_REPO then resolves against the local path with no network. DOTFILES_SOURCE overrides the source for testing a local checkout instead of the published repo. The cleanup trap tracks the host-side bundle and clone, so a mid-run abort leaves nothing behind.
* feat(notify): add --silent flag, volume knob, and level sound filesCraig Jennings2026-05-211-0/+48
| | | | | | | | The touchpad toggle's notification was too loud, and the eight notify sounds varied by ~13 dB in RMS loudness — bug and fail came out two to three times louder than info or security. I added a --silent flag to notify (shows the popup, plays no sound) and a NOTIFY_VOLUME knob (paplay scale, default 65536) so the master level can drop without re-encoding. toggle-touchpad now passes --silent on both enable and disable. normalize-notify-sounds.sh measures each .ogg and shifts it to a uniform -31 dB mean. It writes through the file instead of mv-ing over it, so the stow symlinks survive when the script runs against the live sound dir. I re-encoded all eight sounds to the new level. Tests: a new tests/notify suite (12 tests) covers --silent, the volume knob, flag composition, and the error paths.
* fix: correct a POSIX-sh bashism in init and document two SC2034 casesCraig Jennings2026-05-202-0/+2
| | | | | | init runs under #!/bin/sh but used $(<file) to read /etc/hostname, a bashism that breaks on a strict POSIX sh. I switched it to $(cat) and quoted $interface_up in the same script. The two VM_IP assignments in the test scripts are read by the sourced validation.sh, which shellcheck can't follow, so they now carry a documented disable=SC2034 instead of a bare suppression. The rest of the shellcheck findings across the scripts are intentional (word-splitting on $SSH_OPTS, integer tests in [ ]) or already accepted, so I left them alone.
* fix(testing): cleanup traps, arg validation, and two real bugsCraig Jennings2026-05-179-48/+146
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Two real bugs and a sweep of hygiene across the harness. `make test` passed cleanly on this branch with the same 52/0/5 profile as the 2026-05-11 run, so the wiring is verified end-to-end. Real bugs: - `lib/vm-utils.sh` `snapshot_exists` was running `qemu-img snapshot -l | grep -q "$snapshot_name"`, which matches the name as a substring anywhere in the output — including inside dates or filenames in other fields. Replaced with an awk field extraction on the TAG column plus `grep -Fxq` for a whole-line literal match. - `run-test-baremetal.sh` was setting `VALIDATION_PASSED=true|false` after validation, but `validation.sh` already uses `VALIDATION_PASSED` as a pass counter. The test report then referenced `$VALIDATION_PASSED_COUNT`, which is defined nowhere. Renamed the boolean to `TEST_PASSED` (matching run-test.sh's pattern) and report the actual counter. Cleanup traps and arg validation: - `run-test.sh` now installs a top-level EXIT trap that, on abort, kills QEMU and restores the clean-install snapshot. A `CLEANUP_DONE=1` sentinel keeps the existing normal-path cleanup from double-firing. This is the recurring pain from 2026-05-11 where two failed runs left orphaned QEMU processes and dirty base disks behind. - `create-base-vm.sh` and `debug-vm.sh` got the same kind of trap, plus `debug-vm.sh` now rejects non-`.qcow2` paths up front instead of letting QEMU fail later. - `run-test.sh`, `run-test-baremetal.sh`, and `cleanup-tests.sh` now validate that options with required values actually receive one (`${var:?msg}` for `--script`/`--snapshot`/`--host`/`--password`, numeric check for `--keep`). - `run-test-baremetal.sh` traps the temp git bundle for cleanup if the script aborts before its explicit `rm`. The ZFS rollback loop now uses `while IFS= read -r ds` and quotes `$ds` inside the ssh_cmd so dataset names with whitespace wouldn't break it. Smaller hygiene: - `vm-utils.sh` `check_ovmf` also checks `OVMF_VARS_TEMPLATE`; `start_qemu` validates disk and ISO paths before building the QEMU command; numeric tests quoted. - `cleanup-tests.sh` find expression for temp disks wrapped in `\( ... -o ... \)`, all `while read` loops use `IFS= read -r`, orphaned QEMU cleanup tries SIGTERM with a 2s sleep before SIGKILL. - `create-base-vm.sh` moved the "Copy an archangel-*.iso" info line before its `fatal` instead of after (unreachable), and added the serial-log path to the final summary. - `lib/logging.sh` `stop_timer` no longer produces `$((end - ))` when the named timer was never started. - `lib/network-diagnostics.sh` `read` → `IFS= read -r`. - `setup-testing-env.sh` now installs all missing pacman packages in one transaction instead of one-at-a-time (avoids half-installed state if package N fails). KVM check also verifies the user has read+write on `/dev/kvm` and prints the `gpasswd -a $(id -un) kvm` fix if not. A few items from the review I deliberately skipped: replacing the codebase-wide unquoted `$SSH_OPTS` string with an array (cosmetic, would need to be done everywhere at once), `set -e` adds where the existing fall-through-on-failure is intentional, and a `--force` gate on `create-base-vm.sh` (would break the expected workflow).
* refactor(scripts/games): array + loop, flathub remote check, failure summaryCraig Jennings2026-05-171-29/+50
| | | | | | | | | | | | | | | | | | | | Three things were wrong with the old script: - One line had a duplicate `flathub` argument (`flatpak install ... flathub flathub org.gnome.Crosswords`). Flatpak tolerated it; still a typo. - Nothing added the flathub remote, so a fresh machine without it would fail on every line. - 24 nearly identical `flatpak install` lines with no central handling if one app failed. I moved the app IDs into a single `APPS=()` array (sorted) and looped. The script now runs `flatpak remote-add --if-not-exists --user flathub https://flathub.org/repo/flathub.flatpakrepo` up front, collects any failed apps into a `failed` array, and prints a summary plus a non-zero exit at the end if anything didn't install. I used `set -uo pipefail` rather than `-euo` on purpose so a single failed install doesn't abort the rest of the run.
* fix(cmail-setup-finish): verify both Bridge ports and dump status on failureCraig Jennings2026-05-171-2/+8
| | | | | | | | | | | | | | The "verifying Bridge is listening" check used a regex `127\.0\.0\.1:(1143|1025)` against `ss -ltn` output. That matches if *either* port is listening, but the success message claims both are. So a half-broken Bridge (IMAP up, SMTP down or vice versa) would pass the check. I split the check into two greps and report which port is missing. When the check fails, the script now also prints the last 10 lines of `systemctl --user status protonmail-bridge` to stderr so the operator sees the service state immediately instead of being told to go run the command themselves.
* refactor(scripts/post-install): consolidate gitrepos.sh and harden the scriptCraig Jennings2026-05-172-51/+72
| | | | | | | | | | | | | | | | | | | | | | | | gitrepos.sh did the same `~/.dotfiles` / `~/.emacs.d` remote swap that post-install.sh already had, plus a `git pull --set-upstream origin main` follow-on that post-install was missing. I folded the pull into the post-install remote-rewrite block and dropped gitrepos.sh. While in the file, I also: - Quoted every variable (`"$logfile"`, `"$HOME"` paths, `"$(whoami)"`). - Sent the remote-rewrite block to the log file like the other blocks do (was leaking to stdout). - Made the remote-rewrite idempotent. A re-run used to break the `cd && remote remove && remote add` chain because remove fails when origin is already the desired URL. The loop now uses `git -C "$dir" remote set-url` when origin exists and `remote add` when it does not. - Pre-created `~/sync`, `~/pictures`, `~/code`, `~/projects` so the clones don't fail on missing parent dirs. - Wrapped each `git clone` in a `clone_if_missing` helper so a re-run skips destinations that already exist instead of erroring out. README.md picks up the gitrepos.sh removal in the forking note.
* chore(scripts): drop dead and superseded scriptsCraig Jennings2026-05-165-101/+0
| | | | | | | | | | | | | | | | | Audit pass: each of these had no references anywhere in the repo (excluding self-references and review notes). - wip-bootcandy.sh — "wip" prefix, non-executable. Comments mention a boot animation but the script only installs ly and disables getty@tty2. - protonmail-bridge.sh — `pacman_install protonmail-bridge` (the package landed in extra) plus cmail-setup-finish.sh now cover this. - wireguard-proton.sh — hardcoded USGA tunnel and a relative `../assets/wireguard-config/*.conf` path that depends on the caller's pwd. - create-archiso-zfs.sh — one-off ISO build snippet, non-executable. - scripts/testing/lib/finalize-base-vm.sh — libvirt-era leftover. The test stack moved to direct QEMU and nothing sources or calls it.
* Update En Croissant AppImage pinCraig Jennings2026-05-161-2/+2
|
* Install setup-chess prerequisites automaticallyCraig Jennings2026-05-162-77/+520
|
* feat(cmail): clean autostart stub and add DNS-wait drop-inCraig Jennings2026-05-131-5/+49
| | | | | | | | I extended cmail-setup-finish.sh with two boot-cleanliness fixes for the systemd --user Bridge service. The autostart cleanup removes ~/.config/autostart/Proton Mail Bridge.desktop, which double-launches Bridge and throws an "orphan instance" dialog every login. The wait-for-dns drop-in installs an ExecStartPre loop that waits up to 30 seconds for DNS before Bridge's first API call. User-instance systemd doesn't carry network-online.target, so After=network.target doesn't imply the resolver is up. The leading '-' makes the pre-step non-fatal so an offline boot still starts the unit.
* fix(testing): drop stale plugin checks, count failed validationsCraig Jennings2026-05-112-52/+9
| | | | | | validate_hyprland_plugins and validate_hyprpm_hook checked for the hyprland-plugins-setup script and the hyprpm pacman hook, both removed in 4a3056a (Hyprland 0.54 brings the layouts into core). I deleted the two functions and their calls in validate_window_manager. I also disabled errexit in run-test.sh from the validation phase onward, so one failed check is counted in VALIDATION_FAILED instead of aborting the run before the report or VM cleanup. About 16 validations across the file do a bare `return 1` after `validation_fail`; any of them firing under the previous behavior would have killed the harness mid-run.
* feat: add post-install cmail Bridge setupCraig Jennings2026-05-091-0/+79
| | | | | | | | | | | | | | Bridge first-run is interactive, so I put the cmail wiring in a post-install helper rather than running it inside archsetup. scripts/cmail-setup-finish.sh handles the post-first-run steps idempotently: it decrypts the encrypted cmailpass, copies Bridge's self-signed cert to ~/.config/protonbridge.pem, symlinks the cmail-action triage helper into ~/.local/bin, and enables the user-level protonmail-bridge service. I added loginctl enable-linger in essential_services so the user service survives logout — without it, triaging cmail from a remote agent or SSH session has nothing to talk to. outro prints a four-step runbook for the manual steps after reboot.
* feat(hyprland): rebind mod+shift+f to allfloat, add chess setup scriptCraig Jennings2026-03-021-0/+223
| | | | | | | Add workspace allfloat toggle on mod+shift+f (was togglefloating, now on mod+shift+space only). Add scripts/setup-chess.sh for En Croissant, lc0, Maia, and Stockfish setup. Update log-cleanup to use filename dates instead of mtime. Update ssh and calibre configs.
* feat(archsetup): add rustup, log-cleanup cron, update configsCraig Jennings2026-02-272-2/+12
| | | | | | | Add rustup toolchain manager to developer_workstation (before AUR packages that need rust to compile). Add log-cleanup cron job with test validation. Update ISO glob for archangel naming. Add dunst icon theme, hyprlock animations, waybar log filtering.
* feat(archsetup): add pocketbook installation to hyprland setupCraig Jennings2026-02-251-0/+1
| | | | | | | Install gtk4-layer-shell and pocketbook (via pipx) during Hyprland setup, and clone the source repo in post-install for development. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore(archsetup): add texlive-latexextra, update test scriptsCraig Jennings2026-02-122-2/+2
| | | | | Add texlive-latexextra for pdflatex resume builds (enumitem package). Update test VM password and Arch mirror URL. Process inbox items.
* feat(archsetup): add package-inventory script and reconcile packagesCraig Jennings2026-02-071-0/+222
| | | | | | | | | Add package-inventory script that compares archsetup-declared packages against the live system. Fix awk for-loop parser and dependency filtering. Add 10 missing packages to archsetup (hyprpaper, wev, socat, sshpass, flatpak, solaar, ttf-dejavu, atomicparsley, freetube, tidal-dl-ng). Fix pipx_install function name bug. Change Hyprland follow_mouse to 0 to fix swap focus issue.
* feat(hyprland): install plugins on first login via setup scriptCraig Jennings2026-02-011-19/+14
| | | | | | | | hyprpm requires running Hyprland to determine version for plugin compilation. Move plugin installation from archsetup to a first-login script (hyprland-plugins-setup) that runs via exec-once. Script checks if plugins are already installed and skips if so. Update validation to check for setup script presence instead of enabled plugins.
* fix(hyprland): auto-rebuild plugins and preserve stash master positionCraig Jennings2026-01-311-0/+56
| | | | | | | - Add pacman hook to rebuild hyprpm plugins after Hyprland updates - Change startup to hyprpm update -n (rebuilds if needed) - Fix stash-restore to preserve master window using batch commands - Add validation tests for plugins and hyprpm hook
* test(validation): add Settings portal dark mode checkCraig Jennings2026-01-301-0/+33
| | | | | | Validates that portals.conf uses gtk backend for Settings portal and that the portal returns color-scheme=1 (prefer-dark) for libadwaita apps like Nautilus.
* fix(test): use local repo for archsetup instead of remoteCraig Jennings2026-01-291-0/+3
| | | | | | | | Set ARCHSETUP_REPO=/tmp/archsetup-test in VM config so archsetup uses the bundled test repo instead of cloning from remote server. This ensures tests use the current local changes. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(test): use PROJECT_ROOT for git bundle creationCraig Jennings2026-01-291-1/+1
| | | | | | | The git bundle command was running from current directory instead of PROJECT_ROOT, causing it to bundle from wrong repo. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(test,hyprland): improve test infrastructure and fix easyeffectsCraig Jennings2026-01-292-0/+6
| | | | | | | | | | | | | | | | | | | | Test Infrastructure: - Add make test-keep target to keep VM running after test - Add make test-vm-base target for creating base VM only - Update make test to auto-create VM if missing - Remove manual user creation from create-base-vm.sh (archsetup handles it) - Remove unused USERNAME/USER_PASSWORD from archsetup-test.conf Archsetup: - Add snapper-gui-git for btrfs snapshot GUI - Add SYNC_ACL=yes for snapper permissions - Add setfacl for wheel group access to /.snapshots Hyprland: - Remove easyeffects scratchpad (keep auto-launch) - Remove ecosystem permissions (caused too many popups) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(testing): add make test target and display report on completionCraig Jennings2026-01-271-0/+4
| | | | | Add 'make test' Makefile target to run full VM integration test suite. Print test report to terminal after generation for immediate visibility.