<feed xmlns='http://www.w3.org/2005/Atom'>
<title>archangel/installer, branch main</title>
<subtitle>Arch Linux installer ISO — ZFS-on-root or BTRFS, doubles as rescue disk
</subtitle>
<id>https://git.cjennings.net/archangel/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/archangel/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/'/>
<updated>2026-04-13T04:16:04+00:00</updated>
<entry>
<title>refactor: decompose install_btrfs into named orchestration stages</title>
<updated>2026-04-13T04:16:04+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-13T04:16:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=a15a92cf36d2460784587b3fa6f586e94e9ff6ab'/>
<id>urn:sha1:a15a92cf36d2460784587b3fa6f586e94e9ff6ab</id>
<content type='text'>
Pull the single-vs-multi-disk and LUKS-vs-no-encryption branching out
of install_btrfs() into five helpers in lib/btrfs.sh:

- btrfs_open_encryption         — LUKS open + fill devices array
- btrfs_make_filesystem         — create_btrfs_volume dispatch
- btrfs_configure_luks_target   — in-chroot LUKS config
- btrfs_install_grub            — GRUB primary + multi-disk mirror
- btrfs_close_encryption        — LUKS close (cleanup)

Helpers use namerefs (local -n) to take the caller's arrays as locals
instead of promoting them to globals. install_btrfs() drops from ~99
lines of nested if-then-else to a ~45-line flat sequence of named
stages — matching the style of install_zfs().

Behavior preserved — this is pure code movement, no new disk/LUKS
operations. No unit tests added for the new helpers: they all wrap
real LUKS/mkfs.btrfs calls that need block devices and root; VM
integration tests in scripts/test-install.sh remain the source of
truth. .shellcheckrc: disable SC2178 (nameref array heuristic) and
SC2153 (globals from sourced files) — both recurring false positives.

make test: 65/65. shellcheck clean.
</content>
</entry>
<entry>
<title>refactor: merge install_base and install_base_btrfs</title>
<updated>2026-04-13T04:10:17+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-13T04:10:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=bc613e72238f864a597777826d1f9cc533c4cffa'/>
<id>urn:sha1:bc613e72238f864a597777826d1f9cc533c4cffa</id>
<content type='text'>
Extract the pacstrap package list into pacstrap_packages(filesystem)
in lib/common.sh (common + filesystem-specific). install_base() now
dispatches on FILESYSTEM for both the archzfs-repo-append and the
package list. install_base_btrfs() deleted; install_btrfs() call site
updated to invoke install_base.

Old: 49 + 38 lines of ~95% copy-paste.
New: 32 lines + a 20-line pure helper.

7 bats tests cover: zfs has zfs-dkms/zfs-utils, btrfs has btrfs-progs
+ grub + grub-btrfs + snapper + snap-pac, each flavor excludes the
other's specifics, common packages are in both, unknown filesystem
returns status 1, output is one-per-line. make test: 65/65.
</content>
</entry>
<entry>
<title>refactor: unify get_{luks,zfs}_passphrase and get_root_password</title>
<updated>2026-04-13T04:07:46+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-13T04:07:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=9f6c75916cee8cb65b21b71c69f62d080818ad63'/>
<id>urn:sha1:9f6c75916cee8cb65b21b71c69f62d080818ad63</id>
<content type='text'>
Extract the prompt/confirm/min-length loop into prompt_password() in
lib/common.sh using a nameref for the output variable, so UI output
stays on the terminal (no command-substitution capture) and the three
callers collapse from ~30 lines each to a single helper call.

- get_luks_passphrase() — min 8 chars
- get_zfs_passphrase()  — min 8 chars
- get_root_password()   — no min (was unchecked before; preserved)

5 bats tests added: match+min-ok path, length-retry loop,
mismatch-retry loop, min_len=0 disables check, empty passphrase
when min_len=0. make test: 58/58.
</content>
</entry>
<entry>
<title>refactor: drop dead mount_efi and select_raid_level from lib/disk.sh</title>
<updated>2026-04-13T04:05:09+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-13T04:05:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=88d2fafe410a82dfa3534d7c0466689997407a0c'/>
<id>urn:sha1:88d2fafe410a82dfa3534d7c0466689997407a0c</id>
<content type='text'>
lib/disk.sh:mount_efi() was shadowed by installer/archangel:mount_efi()
(different signature, no-arg ZFS-specific) and had zero callers.
lib/disk.sh:select_raid_level() was superseded by get_raid_level() in
archangel and also had zero callers. Both removed.
</content>
</entry>
<entry>
<title>refactor: extract pure RAID logic to lib/raid.sh with bats coverage</title>
<updated>2026-04-13T03:58:01+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-13T03:58:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=19f4624749228fcbe385d1edf1d2542c036440ff'/>
<id>urn:sha1:19f4624749228fcbe385d1edf1d2542c036440ff</id>
<content type='text'>
Peel the testable pieces of get_raid_level() out of the 1600-line
installer monolith into installer/lib/raid.sh:

- raid_valid_levels_for_count(count) — replaces the inline option-list
  builder in get_raid_level()
- raid_is_valid(level, count) — useful for unattended-config validation
- raid_usable_bytes(level, count, smallest, total) — usable-space math
- raid_fault_tolerance(level, count) — max tolerable disk failures

archangel now sources lib/raid.sh and uses raid_valid_levels_for_count
for the fzf option list. Fzf preview subshell still inlines its own
usable-bytes arithmetic (calling exported lib functions across preview
subshells is fragile; left for a later pass).

30 bats tests in tests/unit/test_raid.bats cover the full enumeration
table, every valid/invalid level-vs-count combo from 2 to 5 disks,
mixed-size mirror, and unknown-level error paths. make test: 53/53.
</content>
</entry>
<entry>
<title>security: gitignore host configs, add .example templates</title>
<updated>2026-04-13T03:20:48+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-13T03:20:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=33ff55507895af2c29a20ec7e7e707d317cb8ef1'/>
<id>urn:sha1:33ff55507895af2c29a20ec7e7e707d317cb8ef1</id>
<content type='text'>
velox-{zfs,btrfs}.conf contain LUKS/ZFS passphrases and root passwords.
Untrack them and add velox-*.conf to .gitignore. Committed .example
templates show the expected structure with 'welcome' placeholders.
</content>
</entry>
<entry>
<title>refactor: remove dead installer/lib/zfs.sh</title>
<updated>2026-04-13T02:57:54+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-13T02:57:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=3321f0fe09b545a7ae3cfd98a80111bb43c0e448'/>
<id>urn:sha1:3321f0fe09b545a7ae3cfd98a80111bb43c0e448</id>
<content type='text'>
The library was sourced but only zfs_preflight was reachable from
install_zfs(); the other ten functions either had names that were
never called (create_zfs_datasets, configure_zfs_pacman_hook, etc.)
or were shadowed by same-named definitions in the monolithic
installer/archangel (create_zfs_pool, configure_zfsbootmenu,
configure_zfs_services).

Inlined zfs_preflight into archangel and dropped the source line.
Removes a trap where fixes appear to be "mirrored" but only one
copy actually runs.
</content>
</entry>
<entry>
<title>fix: drop zroot/tmp dataset and dedup pacman snapshot hook</title>
<updated>2026-04-13T02:55:02+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-13T02:55:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=64260df38906e68b3d75169b8cae3b69715f5bc6'/>
<id>urn:sha1:64260df38906e68b3d75169b8cae3b69715f5bc6</id>
<content type='text'>
- /tmp on ZFS breaks systemd-tmpfiles-clean (statx ENOLINK on
  PrivateTmp paths). Use tmpfs via fstab instead; keep zroot/var/tmp.
- zfs-pre-snapshot gains a 60s lockfile in /run so burst transactions
  (archsetup produced 357 snapshots in one run) collapse to one.

Both fixes mirrored in installer/archangel and installer/lib/zfs.sh.
Already applied and verified on velox.
</content>
</entry>
<entry>
<title>session: first bare metal install on velox, multiple fixes</title>
<updated>2026-04-10T16:26:56+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-10T16:26:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=77b9caac5a6bb5c338f691fdadd2f781557a9d7b'/>
<id>urn:sha1:77b9caac5a6bb5c338f691fdadd2f781557a9d7b</id>
<content type='text'>
ZFS and Btrfs tested on bare metal. Fixed archzfs repo URL, LUKS pbkdf2
for GRUB, no-color default, and missing inetutils. Tagged v0.8.
</content>
</entry>
<entry>
<title>fix: add inetutils to installed system packages</title>
<updated>2026-04-10T03:23:52+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-10T03:23:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=4833969e73e45c5880065d164dc87252809735b3'/>
<id>urn:sha1:4833969e73e45c5880065d164dc87252809735b3</id>
<content type='text'>
Provides hostname, ping, and other networking basics on the target system.
</content>
</entry>
</feed>
