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:
@@ -131,6 +131,20 @@ kept its ssh host key. Run it after ANY change to the kexec paths.
|
||||
`HOMELAB_INSTALLER_STAGE_DIR` skips the prompt for scripted use. Both this and
|
||||
`kexec-local` self-elevate via `sudo` (`require_root()`) rather than requiring you to
|
||||
prefix the command yourself.
|
||||
- **terra runs Limine, not systemd-boot** — `bootctl set-oneshot` is useless there
|
||||
(`bootctl status` lists `✗ One-shot entry control`, and CachyOS's pacman hooks
|
||||
regenerate `limine.conf` anyway). `local_install_prepare_and_reboot()` therefore
|
||||
picks its one-shot mechanism at runtime: a systemd-boot loader entry when
|
||||
`$BOOT/loader/entries` exists, otherwise `arm_efi_bootnext()` — a temporary UEFI
|
||||
entry that EFI-stub-boots the kernel off the ESP, armed via the firmware's
|
||||
`BootNext`. Created with `efibootmgr --create-only` (NOT `--create`, which pushes
|
||||
it to the front of `BootOrder` and would make a wiped installer the permanent
|
||||
default if anything went wrong). BootNext is spent by that one boot, so a failed
|
||||
attempt still comes back on the normal bootloader. The EFI-stub path needs the
|
||||
kernel on the **ESP** itself, not on a separate XBOOTLDR — hence `--print-esp-path`
|
||||
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).
|
||||
- **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
|
||||
|
||||
Reference in New Issue
Block a user