deploy: one-shot boot without the bootloader's help (terra runs Limine)
`install <config> localhost` assumed systemd-boot. terra's CachyOS boots
Limine, so it stopped at "/boot/loader/entries doesn't exist" — the check
added in e538788 doing its job, but with nowhere to go.
Limine cannot help here at all: `bootctl status` lists it as
`✗ One-shot entry control`, and CachyOS's pacman hooks regenerate
limine.conf regardless. So drop below the bootloader entirely and use the
firmware's own BootNext, pointing at a temporary UEFI entry that
EFI-stub-boots the installer kernel straight off the ESP. That keeps the
property which makes this safe to attempt: BootNext is spent by that one
boot, so a failed try still comes back on the normal bootloader.
- picked at runtime: systemd-boot loader entry when $BOOT/loader/entries
exists, else arm_efi_bootnext(). jupiter/neptun and terra-after-install
keep the systemd-boot path.
- `efibootmgr --create-only`, NOT `--create`: the latter pushes the entry
to the front of BootOrder, which would make a wiped installer the
permanent default if the install died halfway.
- the EFI stub loads initrd= from the volume it was loaded from, so this
mode stages on --print-esp-path rather than --print-boot-path.
- stale entries from an earlier attempt are removed before adding one, and
homelab-auto-install.service deletes the entry as soon as it boots, so
nothing lingers in NVRAM pointing at a reformatted partition.
- label matching is EXACT ("Homelab Installer"); a prefix match would have
deleted this box's Windows or Limine entry.
Verified against terra's real NVRAM (read-only): the label parser picks out
Limine/UEFI OS/Windows by exact name and rejects prefixes, and both branches
run end-to-end under stubs — BootNext mode emits the right --disk/--part,
loader path and initrd= cmdline, systemd-boot mode still writes its entry and
never calls efibootmgr.
README/CLAUDE.md corrected: terra runs Limine, not systemd-boot.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -252,7 +252,7 @@
|
||||
after = [ "homelab-checkout.service" ];
|
||||
requires = [ "homelab-checkout.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [ pkgs.gnugrep pkgs.util-linux pkgs.coreutils pkgs.git ];
|
||||
path = [ pkgs.gnugrep pkgs.gnused pkgs.util-linux pkgs.coreutils pkgs.git pkgs.efibootmgr ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
# systemd does NOT set $HOME for a system service without User=
|
||||
# (systemd.exec(5): SetLoginEnvironment= "defaults to true if
|
||||
@@ -294,6 +294,18 @@
|
||||
fi
|
||||
fi
|
||||
|
||||
# On a box whose old bootloader had no one-shot (Limine on
|
||||
# terra), scripts/deploy got us here via a temporary UEFI
|
||||
# entry + BootNext (arm_efi_bootnext). BootNext is already
|
||||
# spent, but the entry itself would linger in NVRAM pointing
|
||||
# at a partition disko is about to reformat. Drop it now, so
|
||||
# even an install that fails later leaves NVRAM clean.
|
||||
for n in $(efibootmgr 2>/dev/null \
|
||||
| sed -n 's/^Boot\([0-9A-Fa-f]\{4\}\)\*\?[[:space:]]Homelab Installer[[:space:]].*/\1/p'); do
|
||||
echo "removing temporary UEFI entry Boot$n"
|
||||
efibootmgr -q -B -b "$n" || true
|
||||
done
|
||||
|
||||
echo "auto-installing $cfg (homelab.install= on the kernel cmdline)"
|
||||
cd /root/homelab
|
||||
exec ./scripts/deploy install "$cfg" localhost --yes
|
||||
|
||||
Reference in New Issue
Block a user