Skip to content

Phase A migration follow-ups: postInstall stages + flatpak→Phase B#18

Merged
AdamJHall merged 4 commits into
mainfrom
postinstall-stages
Jul 4, 2026
Merged

Phase A migration follow-ups: postInstall stages + flatpak→Phase B#18
AdamJHall merged 4 commits into
mainfrom
postinstall-stages

Conversation

@AdamJHall

@AdamJHall AdamJHall commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Two Phase-A-migration follow-ups. They share the stage-registry/window tests, so
they ride together.

1. Promote postInstall side-effects into numbered Phase A stages

The archinstall stage (Order 10) used to bundle six chroot side-effects inside
postInstall, invisible and untestable. They're now five real numbered stages
between mount@20 and packages@30, all requireChroot-guarded (so encrypted
installs skip cleanly):

Order Stage Was
21 swap setupSwapfile
22 locale configureLocales
23 user configureUserShell
24 repos enableMultilib + configureRepos
26 kernels installKernels

Behavior-preserving: emitted commands + order unchanged, archinstall render
goldens pass without -update; new per-stage dry-run command-plan tests prove
the behaviour. Helpers moved from the explicit ctx.R.Chroot("/mnt",…) primitive
to the chroot-aware ctx.R.Root/RootShell (the Runner wraps once now that
mount@20 opened the chroot). postInstall + dead chrootCmd/chrootShell
deleted; archinstall's Run is now render + run archinstall + return.

2. Move the flatpak stage back to Phase B

Extra-data flatpaks (Spotify, Zoom, Chrome, …) run an apply_extra bwrap
sandbox at install time that needs an unprivileged user namespace, which the
Phase A arch-chroot on the live ISO can't create (bwrap: No permissions to create a new namespace). Plain OSTree apps (Flatseal) don't hit apply_extra,
so the e2e suite never caught it.

The flatpak stage moves from Phase A (Order 40) to Phase B (Order 50),
joining yay/aur/snapper as the "needs a booted session" bucket where
userns/bwrap works. Flatpaks install on the first bootstrap run instead of at
first boot. Regression guard: the features-flatpak e2e config now also
installs Spotify (extra-data) and validates it, exercising the bwrap/userns path
on the booted system.

Testing

gofmt -l . clean, go build/vet/test ./... green (goldens not regenerated). The
full e2e QEMU matrix was green (18/18) for part 1 (every disk layout +
feature). Part 2's Spotify guard should be re-run to confirm the extra-data
install now succeeds in Phase B. Also includes two pre-existing /boot-permission
e2e test fixes (sibling of #17's features.sh fix): archinstall 4.4 mounts the
ESP dmask=0077, so the unprivileged validator must read /boot via sudo
validate.sh's grub grub.cfg check was the last un-sudo'd spot and had been
failing every grub disk-layout descriptor.

Note

Also carries an unrelated maintainer commit (8ace1fc) removing the obsolete
docs/bugs/* and docs/vm-validation.md (retrospectives now in CLAUDE.md).

🤖 Generated with Claude Code

AdamJHall and others added 4 commits July 4, 2026 12:42
Extract the six chroot side-effects archinstall@10 ran via postInstall
(swapfile, extra locales, user shell, multilib/repos, kernels) into real
numbered stages in the 21-29 window, between mount@20 and packages@30:

  swap@21  locale@22  user@23  repos@24  kernels@26

Each is Phase Install, guarded by requireChroot so encrypted installs skip
cleanly, and preserves postInstall's exact per-side-effect config gates — so
they are now --only-addressable, individually headered/timed, and
command-plan testable like packages/flatpak/etc.

The stages run AFTER mount@20 sets ChrootRoot="/mnt", so the helpers
(configureRepos, enableMultilib, configureLocales, configureUserShell,
installKernels, setupSwapfile) are converted from the explicit
ctx.R.Chroot("/mnt", ...) primitive to the chroot-aware ctx.R.Root /
ctx.R.RootShell forms. The Runner wraps those in `arch-chroot /mnt` exactly
once, so the emitted command is unchanged; setupSwapfile now uses in-chroot
paths (/swapfile, /etc/fstab) instead of /mnt-prefixed host paths so it
resolves correctly under the wrap. chrootCmd/chrootShell are removed.

postInstall itself is deleted: its ensureTargetMounted call is redundant
(mount@20 does it) and its encryption early-return is covered by
mount@20/finalize@99/requireChroot. The archinstall stage's Run is now
render + run archinstall + return. This is behavior-preserving — the emitted
commands and their order are identical, just re-homed across stage
boundaries, so the archinstall render goldens pass unchanged.

Tests: new per-stage command-plan tests (swap/locale/user/repos/kernels)
with self-contained inline configs; relocated the postInstall assertions
(user shell, multilib/repos, kernels, swapfile) out of the archinstall-plan
tests into the owning stages; added a planForNoChroot helper and encrypted-
path skip coverage across the new stages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sibling of the features.sh kernel-zen fix (#17): archinstall 4.4 mounts
the ESP at /boot with dmask=0077, so /boot is 0700 root:root and the
unprivileged validation user can't traverse it. The grub bootloader
assertion did a bare `[[ -f /boot/grub/grub.cfg ]]` and so reported a
present grub.cfg as missing, failing every grub disk-layout descriptor
(plain-*, lvm-*, btrfs-*). The systemd-boot branch already used
`sudo bootctl`, which is why sdboot-* passed. Read grub.cfg via sudo to
match. Pre-existing test bug, unrelated to the postInstall refactor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…erns)

Extra-data flatpaks (Spotify, Zoom, Chrome, …) run an apply_extra bwrap
sandbox at install time that needs an unprivileged user namespace. The
Phase A arch-chroot on the live ISO can't create one, so installing them
there fails with "bwrap: No permissions to create a new namespace". Plain
OSTree apps (e.g. Flatseal) don't hit apply_extra, which is why the e2e
suite — which only installed Flatseal — never caught it.

Move the flatpak stage from Phase A (Order 40) to Phase B (Order 50,
after aur), joining yay/aur/snapper as the "needs a booted session"
bucket, where userns/bwrap works. Flatpaks install on the first bootstrap
run instead of being pre-installed at first boot. Drop the requireChroot
guard; the --user installs run directly as the user and ensureTool uses
sudo — no chroot.

Regression guard: the features-flatpak e2e config now also installs
Spotify (extra-data) and validates it, so the apply_extra/bwrap/userns
path is actually exercised on the booted system.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@AdamJHall AdamJHall changed the title Promote postInstall side-effects into numbered Phase A stages Phase A migration follow-ups: postInstall stages + flatpak→Phase B Jul 4, 2026
@AdamJHall AdamJHall merged commit 2a3447f into main Jul 4, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant