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:
2026-07-24 02:35:33 +02:00
co-authored by Claude Opus 4.8
parent e538788907
commit c87fd3b1f2
4 changed files with 148 additions and 17 deletions
+16 -5
View File
@@ -87,7 +87,8 @@ Manual alternative (USB ISO): boot installer, `disko` the disk, then
## First install on terra — no-USB findiso reinstall (replacing CachyOS)
terra is a Ryzen 9 5900X / Radeon RX 6800 XT desktop, currently running
CachyOS with a writable root and systemd-boot. Everything is already prepped
CachyOS with a writable root and **Limine** as its bootloader (not
systemd-boot — see step 4). Everything is already prepped
in this repo: real OS-disk id in `disk-config.nix`, real login pubkey in
`common.nix`, terra's age recipient in `.sops.yaml`, its host key
pre-generated at `~/.config/homelab/terra/`, and `secrets/terra.yaml` already
@@ -137,10 +138,20 @@ self-elevates:
pre-generated ssh host key** to the boot partition (found via
`bootctl --print-boot-path`, not assumed to be `/boot`) and the iso to the
staging dir.
4. Writes a systemd-boot **one-shot** entry (`bootctl set-oneshot` — reverts to
the normal default after this one boot, even if it fails) with `findiso=` +
`homelab.install=terra` + `homelab.keypart=<PARTUUID>` on its kernel
cmdline, and reboots — a real `systemctl reboot`, not kexec.
4. Arms a **one-shot** boot of it with `findiso=` + `homelab.install=terra` +
`homelab.keypart=<PARTUUID>` on the kernel cmdline, and reboots — a real
`systemctl reboot`, not kexec. Two mechanisms, picked automatically:
- **systemd-boot** (jupiter, neptun, and terra once NixOS is on it): a
`bootctl set-oneshot` loader entry.
- **anything else** — terra today runs Limine, which reports `One-shot entry
control: ✗` and has no equivalent: the firmware's own **`BootNext`**,
pointing at a temporary UEFI entry that EFI-stub-boots the kernel straight
off the ESP. Created with `--create-only` so it never enters `BootOrder`,
which means it is reachable exactly once and nothing else changes.
Either way the box falls back to its normal bootloader if the attempt
fails — nothing is made permanent before the install succeeds. The
temporary UEFI entry is deleted by the installer as soon as it boots.
The booted installer clones the repo (`homelab-checkout.service`, needs
network — it's public now, no credentials involved) and then