<feed xmlns='http://www.w3.org/2005/Atom'>
<title>archsetup/tests/installer-steps/test_idempotency_cluster.py, branch main</title>
<subtitle>Builds a full dev workstation from a bare Arch Linux install.
</subtitle>
<id>https://git.cjennings.net/archsetup/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/archsetup/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/'/>
<updated>2026-07-20T20:50:44+00:00</updated>
<entry>
<title>fix(installer): make three resume-fragile steps idempotent and correct</title>
<updated>2026-07-20T20:50:44+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-20T20:50:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archsetup/commit/?id=8917f2fd17a729af55138d6240cd363887f3d83e'/>
<id>urn:sha1:8917f2fd17a729af55138d6240cd363887f3d83e</id>
<content type='text'>
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.
</content>
</entry>
</feed>
