deploy: pass init= on the EFI-stub cmdline (stage 2 init not found)

findiso now works — the installer loop-mounted the iso, mounted the store
squashfs and the overlay — then died with:

  stage 2 init script (/mnt-root//init) not found

The live ISO's root is a tmpfs; stage 1 locates the real system's init via
init=<toplevel>/init, which the grub/isolinux menu supplies on a normal boot
(iso-image.nix:47,159). EFI-stub-booting our own cmdline off the ESP, we
never passed it, so stage 1 fell back to /mnt-root/init on the empty tmpfs.

Build the installer-iso toplevel and prepend init=$toplevel/init to the
cmdline (both boot modes). That path resolves once the store squashfs mounts,
because the iso carries the full closure of its own toplevel. Also switch
root=fstab -> root=LABEL=<volumeID> to match what the ISO menu passes (findiso
overwrites /dev/root regardless), and add boot.shell_on_fail for a shell
instead of the reboot/ignore prompt if stage 1 ever fails again.

Verified: the generated cmdline carries init=/nix/store/<toplevel>/init and
that store path contains /init.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-24 11:09:15 +02:00
co-authored by Claude Opus 4.8
parent 75b51af81b
commit f675c628a8
+14 -3
View File
@@ -360,11 +360,17 @@ local_install_prepare_and_reboot() {
fi fi
echo ">> building installer-iso (kernel + initrd + iso image)" echo ">> building installer-iso (kernel + initrd + iso image)"
local kernel initrd isodir iso mnt_point iso_relpath boot_src boot_partuuid local kernel initrd isodir iso toplevel mnt_point iso_relpath boot_src boot_partuuid
kernel="$(nix build --no-link --print-out-paths .#nixosConfigurations.installer-iso.config.system.build.kernel)/bzImage" kernel="$(nix build --no-link --print-out-paths .#nixosConfigurations.installer-iso.config.system.build.kernel)/bzImage"
initrd="$(nix build --no-link --print-out-paths .#nixosConfigurations.installer-iso.config.system.build.initialRamdisk)/initrd" initrd="$(nix build --no-link --print-out-paths .#nixosConfigurations.installer-iso.config.system.build.initialRamdisk)/initrd"
isodir="$(nix build --no-link --print-out-paths .#nixosConfigurations.installer-iso.config.system.build.isoImage)" isodir="$(nix build --no-link --print-out-paths .#nixosConfigurations.installer-iso.config.system.build.isoImage)"
iso="$(one_match 'installer iso' "$isodir"/iso/*.iso)" iso="$(one_match 'installer iso' "$isodir"/iso/*.iso)"
# The live ISO's root is a tmpfs; stage 1 finds the real system's init via
# init=<toplevel>/init, which the grub/isolinux menu supplies on a normal
# boot (iso-image.nix). EFI-stub-booting our own cmdline, we must pass it too
# — omit it and stage 1 loop-mounts the iso fine, then dies on
# "stage 2 init script (/mnt-root//init) not found".
toplevel="$(nix build --no-link --print-out-paths .#nixosConfigurations.installer-iso.config.system.build.toplevel)"
# A short write is not visible until the reboot, when findiso finds a # A short write is not visible until the reboot, when findiso finds a
# truncated iso and drops to an emergency shell. Check first — `install` # truncated iso and drops to an emergency shell. Check first — `install`
@@ -413,8 +419,13 @@ local_install_prepare_and_reboot() {
# Identical either way — only the mechanism that gets the kernel booted with # Identical either way — only the mechanism that gets the kernel booted with
# it differs. # it differs.
local cmdline # root=LABEL=<volumeID> matches what the ISO menu passes; findiso overwrites
cmdline="nohibernate root=fstab loglevel=4 lsm=landlock,yama,bpf findiso=$iso_relpath homelab.install=$config homelab.keypart=$boot_partuuid" # /dev/root with the loop-mounted iso regardless, but keep it honest.
# boot.shell_on_fail gives a shell instead of the reboot/ignore prompt if
# stage 1 ever fails again. init= is the one that actually made this work.
local cmdline volumeID
volumeID="$(nix eval --raw .#nixosConfigurations.installer-iso.config.isoImage.volumeID)"
cmdline="init=$toplevel/init nohibernate root=LABEL=$volumeID boot.shell_on_fail loglevel=4 lsm=landlock,yama,bpf findiso=$iso_relpath homelab.install=$config homelab.keypart=$boot_partuuid"
case "$boot_mode" in case "$boot_mode" in
systemd-boot) systemd-boot)