banger/internal/imagepull
Thales Maciel c3fb4ccc3e
Phase B-3: first-boot sshd install
New internal/imagepull/assets/first-boot.sh: POSIX-sh oneshot that
detects the guest distro from /etc/os-release (ID + ID_LIKE
fallback), installs openssh-server via the native package manager,
and enables/starts sshd. Covers debian/ubuntu/kali/raspbian/pop,
alpine, fedora/rhel/centos/rocky/almalinux, arch/manjaro, and
opensuse/suse. Unknown distros fail clearly with a pointer at
editing the script to add a branch.

Marker-driven: the service has ConditionPathExists=
/var/lib/banger/first-boot-pending, and the script removes the
marker on success. Subsequent boots no-op.

Testability seams in the script: RUN_PLAN=1 skips the
sshd-already-present short-circuit and makes the dispatch echo the
planned command instead of executing it. OS_RELEASE_FILE and
BANGER_FIRST_BOOT_MARKER env vars override paths so the Go tests
exercise the real dispatch logic in a tempdir without touching
/etc or /var/lib on the host.

Embedding: internal/imagepull/firstboot.go go:embeds both the
script and the systemd unit; exposes FirstBootScript() and
FirstBootUnit() plus the FirstBootScriptPath /
FirstBootMarkerPath / FirstBootUnitName constants.

Injection: InjectGuestAgents now drops /usr/local/libexec/
banger-first-boot (0755), /etc/systemd/system/banger-first-boot.
service (0644), the empty /var/lib/banger/first-boot-pending
marker (0644), and the multi-user.target.wants enable symlink.
All uid=0, gid=0.

Tests: eight-case dispatch-by-distro (debian, ubuntu, alpine,
fedora, arch, opensuse, plus ID_LIKE fallbacks for weird
derivatives). Script syntax check via `sh -n`. Unit-contains-
expected-fields check. Existing inject round-trip test extended
to assert the first-boot bits land in the ext4.

Deferred: per-image FirstBootPending flag + extended SSH wait
timeout at VM start. Will add if live verification (B-4) shows
the naive retry UX is unacceptable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 18:20:33 -03:00
..
assets Phase B-3: first-boot sshd install 2026-04-16 18:20:33 -03:00
ext4.go Phase 1: imagepull package — pull, flatten, ext4 2026-04-16 17:22:13 -03:00
firstboot.go Phase B-3: first-boot sshd install 2026-04-16 18:20:33 -03:00
firstboot_test.go Phase B-3: first-boot sshd install 2026-04-16 18:20:33 -03:00
flatten.go Phase B-1: ownership fixup via debugfs pass 2026-04-16 18:04:22 -03:00
imagepull.go Phase 1: imagepull package — pull, flatten, ext4 2026-04-16 17:22:13 -03:00
imagepull_test.go Phase B-1: ownership fixup via debugfs pass 2026-04-16 18:04:22 -03:00
inject.go Phase B-3: first-boot sshd install 2026-04-16 18:20:33 -03:00
inject_test.go Phase B-3: first-boot sshd install 2026-04-16 18:20:33 -03:00
ownership.go Phase B-1: ownership fixup via debugfs pass 2026-04-16 18:04:22 -03:00