scripts v1.18.0 — R-21 slice B: firmware loader option --loader shim|mkimage (F1)
Closes N100 F1 (HIGH): cheap AMI (AN3PLUS 0.01-class) UEFI firmware can't relocate the ISO's stock signed GRUB from USB (relocation 0x0). The run's live grub-mkimage workaround is now a first-class pipeline mode. - build-felhom-iso.sh: --loader shim|mkimage (default shim, byte-for-byte unchanged; profile-settable FELHOM_LOADER; --loader wins). Loud banner + manifest loader:/grub-mkimage: fields + -mkimage filename suffix. - mkimage-surgery.sh (new): post-prepare-iso, in the assistant container. Builds a monolithic grub-mkimage loader from the ISO's own GRUB (module set from its grub.cfg; embedded search --fs-uuid -> configfile the real menu). Swaps it into the ISO9660 tree (real lowercase path) + the efi.img ESP; xorriso re-master preserves BIOS-hybrid + UEFI + GPT-ESP, drops only Apple HFS+/APM. Recipe from the N100 run evidence, not re-derived. - Dockerfile.assistant: grub-common + grub-efi-amd64-bin + mtools + dosfstools. profiles/n100.profile (new, mkimage + SB-off note). - Validated on nested VM 311 (RUNBOOK-B legs): leg1 shim boots+installs under OVMF SB-enforcing + SeaBIOS; leg2 mkimage boots+installs under SB-off; leg3 (red-proof) mkimage under SB-enforcing FAILS Access Denied (unsigned -> SB must be OFF); leg4 surgery byte-identical payload. bash -n + shellcheck clean. Physical N100 closure folds into the rehearsal (n100-safety match-nothing ISO built + sha-recorded, unbooted). PXE stays a deferred R-21 note.
This commit is contained in:
+42
-6
@@ -1,4 +1,4 @@
|
||||
# Felhom bare-metal ISO pipeline (R-21 slice A)
|
||||
# Felhom bare-metal ISO pipeline (R-21 slice A + B)
|
||||
|
||||
Turns the official Proxmox VE ISO into a **Felhom auto-install ISO** whose first-boot chain,
|
||||
unattended, fetches and runs `felhom-host-install.sh` until the host is enrolled and a guest is
|
||||
@@ -18,7 +18,8 @@ channel).
|
||||
| File | Role |
|
||||
|---|---|
|
||||
| `Dockerfile.assistant` | build host: Debian trixie + `proxmox-auto-install-assistant` (paired to the ISO's PVE generation by Debian codename) + `xorriso` + `shellcheck` |
|
||||
| `build-felhom-iso.sh` | the pipeline: render answer, mint throwaway root hash, **validate-answer output-parse gate**, render stub, `prepare-iso`, emit ISO + sha256 + manifest |
|
||||
| `build-felhom-iso.sh` | the pipeline: render answer, mint throwaway root hash, **validate-answer output-parse gate**, render stub, `prepare-iso`, **optional `--loader mkimage` surgery**, emit ISO + sha256 + manifest |
|
||||
| `mkimage-surgery.sh` | slice-B loader surgery (runs in the container, post-`prepare-iso`): builds a monolithic `grub-mkimage` UEFI loader and swaps it into the ISO's EFI boot path (F1 firmware fix) |
|
||||
| `answer.toml.tmpl` | Proxmox answer template (`__FQDN__` / `__ROOT_HASH__` / `__ROOT_SSH_KEYS__` / `__DISK_SETUP__` placeholders; `[first-boot]` from-iso/fully-up) |
|
||||
| `profiles/*.profile` | disk-selection + fqdn fragments (sourceable, no secret) |
|
||||
| `stub-first-boot.sh` | the ONE first-boot executable (skeleton; build injects the bootstrap script/unit/env as base64) |
|
||||
@@ -66,6 +67,33 @@ glob. **A filter matching nothing, or a non-existent disk, fails-safe**: the ins
|
||||
1, no disk touched) rather than installing on the wrong disk (spike S5c). Never commit a real key in
|
||||
`FELHOM_ROOT_SSH_KEY` unless it is meant to ship in every ISO built from that profile.
|
||||
|
||||
A profile may also set `FELHOM_LOADER="shim"|"mkimage"` (see below); `--loader` on the command line
|
||||
overrides it.
|
||||
|
||||
## Loader modes (`--loader shim|mkimage`, slice B)
|
||||
|
||||
The UEFI boot loader is selectable. Default **shim**; a profile can pin `FELHOM_LOADER`; `--loader`
|
||||
wins over both.
|
||||
|
||||
- **`shim`** (default) — the stock output: the ISO's MS-signed shim → GRUB chain. **Secure Boot keeps
|
||||
working** on compliant firmware (no MOK, no keypress — spike S2b). Use this everywhere it boots.
|
||||
- **`mkimage`** — replaces the ISO's UEFI boot path with a **monolithic `grub-mkimage` loader** built
|
||||
from the ISO's own GRUB modules. This is the fix for cheap AMI (`AN3PLUS 0.01`-class) mini-PC
|
||||
firmware that **cannot UEFI-boot the ISO's stock GRUB from USB** (`relocation 0x0 is not implemented
|
||||
yet`; SB-off and shim-bypass don't help) — the F1 finding of `tests/VALIDATION-n100-baremetal-2026-07-16.md`,
|
||||
worked around live during that run and now first-class. The recipe (module set from the ISO's
|
||||
`grub.cfg`, embedded `search --fs-uuid` → `configfile` the real menu) is reproduced from the run
|
||||
evidence, not re-derived.
|
||||
|
||||
> **⚠ mkimage is UNSIGNED → the target board MUST have Secure Boot OFF.** With Secure Boot
|
||||
> enforcing the firmware refuses the loader (`Access Denied`, no boot — proven, RUNBOOK-B leg 3).
|
||||
> mkimage ISOs are named with a **`-mkimage`** suffix and the manifest's `loader:` line says so;
|
||||
> never confuse them with a shim (SB-capable) build. shim mode's output is byte-for-byte the same as
|
||||
> before this flag existed (the surgery is skipped entirely).
|
||||
|
||||
The surgery runs **after** `prepare-iso` and touches only the EFI boot path — the answer file and
|
||||
the on-first-boot payload are provably byte-identical to the shim variant's (RUNBOOK-B leg 4).
|
||||
|
||||
## bootstrap-env (SECRET-BEARING)
|
||||
|
||||
The `--bootstrap-env` file becomes the in-ISO `/etc/felhom/bootstrap.env`:
|
||||
@@ -104,17 +132,25 @@ producer steps re-run each pass).
|
||||
|
||||
## N100 profile (for RUNBOOK B)
|
||||
|
||||
The nested profile uses `disk-list=["sda"]`. **A real single-disk mini-PC should use a unique-serial
|
||||
udev filter, not `disk-list`:**
|
||||
Use the committed `profiles/n100.profile` template (cheap-board, `FELHOM_LOADER="mkimage"`). **A real
|
||||
single-disk mini-PC uses a unique-serial udev filter, not `disk-list`:**
|
||||
|
||||
1. Boot once (or use a live env), harvest the target disk's udev id:
|
||||
`udevadm info --query=property --name=/dev/sda | grep -E 'ID_SERIAL_SHORT|ID_MODEL|ID_WWN'`.
|
||||
2. Write a profile: `filter.ID_SERIAL_SHORT = "<harvested>"` + `filter-match = "all"`. A
|
||||
2. In the profile, set `filter.ID_SERIAL_SHORT = "<harvested>"` + `filter-match = "all"`. A
|
||||
match-nothing filter fails-safe (won't wipe the wrong disk).
|
||||
3. **Prior-LVM prerequisite:** the auto-installer does **not** force-clear a pre-existing LVM PV
|
||||
signature — a disk with a previous Linux/Proxmox install aborts at "cannot init physical volume"
|
||||
(spike S2b). Wipe first: `blkdiscard -f /dev/<disk>` (or `wipefs -a` + zero the PV region).
|
||||
4. UEFI + Secure Boot: no caveat — installs and boots under SB enforcing, no MOK/keypress (spike S2b).
|
||||
4. **Boot loader + Secure Boot (F1):** cheap AMI (`AN3PLUS`-class) firmware can't boot the stock GRUB
|
||||
from USB, so `profiles/n100.profile` uses `--loader mkimage`. **That loader is unsigned → set
|
||||
Secure Boot to OFF/Disabled in the BIOS** before booting the stick (with SB enforcing the board
|
||||
refuses it: `Access Denied`, no boot). Firmware that boots the stock ISO fine needs no mkimage and
|
||||
keeps Secure Boot working (default `shim`, spike S2b). *Optional pre-flight (operator, no risk):* a
|
||||
`n100-safety` ISO — `--loader mkimage` + a **match-nothing** filter — boots the board, loads GRUB,
|
||||
and the installer aborts touching nothing (S5c). It confirms the loader + SB-off setting before the
|
||||
real install; its sha is recorded at build. Never boot the real install-armed ISO except in the
|
||||
supervised rehearsal.
|
||||
5. **BIOS "State After G3" → "Power On" (or "Last State")** before final sign-off — so the mini-PC
|
||||
auto-powers-on after a mains loss (a managed appliance must come back without a physical press).
|
||||
Set it in the BIOS power/ACPI menu; it is board-specific and cannot be scripted (operator step).
|
||||
|
||||
Reference in New Issue
Block a user