From 75b51af81b017e47453187f4b7466e688fba4055 Mon Sep 17 00:00:00 2001 From: Erik Simon Date: Fri, 24 Jul 2026 10:42:52 +0200 Subject: [PATCH] =?UTF-8?q?installer-iso:=20force=20script=20stage=201=20?= =?UTF-8?q?=E2=80=94=20systemd=20initrd=20has=20no=20findiso?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit terra booted the staged installer this time but dropped to an emergency shell: stage 1 mounted /sysroot, then timed out on /sysroot/nix/.ro-store waiting for /dev/disk/by-label/nixos-minimal-26.05-x86_64. findiso= is handled only in the scripted stage-1-init.sh, which loop-mounts the file the param points at and symlinks it to /dev/root. The systemd initrd — the default since 26.05 — has no findiso handling at all: iso-image.nix mounts /iso directly from /dev/disk/by-label/, a label that only exists when the ISO is the physical boot medium. Booted as kernel + initrd off the ESP with the iso as a plain file on another partition, that label never appears, so the store squashfs never mounts. The entire `install localhost` path is built on findiso, so pin the installer to script stage 1. Verified: /iso device flips to /dev/root, root=LABEL=... is added to the params, the rebuilt initrd's /init is stage-1-init.sh and carries the findiso logic. Co-Authored-By: Claude Opus 4.8 --- CLAUDE.md | 9 +++++++++ flake.nix | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index a64c86e..1d62eeb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -145,6 +145,15 @@ kept its ssh host key. Run it after ANY change to the kexec paths. rather than `--print-boot-path` in that mode. `homelab-auto-install.service` deletes the leftover NVRAM entry as soon as it boots; both it and the script match the label `Homelab Installer` EXACTLY (a prefix match would delete the Windows or Limine entry). +- **`installer-iso` must force `boot.initrd.systemd.enable = false`.** `findiso=` is a + SCRIPT-stage-1 feature (`stage-1-init.sh` loop-mounts the file it points at and + symlinks it to `/dev/root`). The systemd initrd — default since 26.05 — has NO findiso + path: it mounts `/iso` straight from `/dev/disk/by-label/` (iso-image.nix), + a label that only exists when the ISO is the physical boot medium. EFI-stub-booted off + the ESP with the iso as a plain file on another fs, that label never appears; stage 1 + mounts `/sysroot` fine, then times out on `/sysroot/nix/.ro-store` waiting for + `/dev/disk/by-label/nixos-minimal-…` and drops to an emergency shell. The whole + `install localhost` findiso path depends on script stage 1. - **The staging-dir guard must fail CLOSED, and `findmnt` needs `--nofsroot`**: on btrfs `findmnt -no SOURCE` prints `/dev/sdb2[/@]`, which `lsblk` cannot open, so a naive parent-device lookup comes back empty. Treating empty as "different disk" silently diff --git a/flake.nix b/flake.nix index 027abdb..4ec9527 100644 --- a/flake.nix +++ b/flake.nix @@ -208,6 +208,19 @@ networking.hostName = "homelab-installer"; environment.systemPackages = [ pkgs.git ]; + # findiso= is a SCRIPT-stage-1 feature (stage-1-init.sh) only. The + # systemd initrd — the default since 26.05 — has no findiso path + # at all: it mounts /iso straight from + # /dev/disk/by-label/ (iso-image.nix), which only exists + # when the ISO is the physical boot medium. Booted as a kernel + + # initrd off the ESP with the iso as a plain file elsewhere, that + # label never appears and stage 1 times out into an emergency + # shell (mounts /sysroot fine, then fails /sysroot/nix/.ro-store). + # Script stage 1 instead loop-mounts the file findiso= points at + # and symlinks it to /dev/root — which is the whole mechanism this + # install path relies on. So force it off here. + boot.initrd.systemd.enable = false; + # installation-cd-minimal leaves experimental-features unset, so # the ISO's nix.conf has no `nix-command`/`flakes` at all (unlike # the nixos-images kexec installer, which sets