Files
felhom.eu/REPORT-universal-iso-spike.md
T
admin bb29186d62 SPIKE 3: [first-boot] does NOT fire on an interactive install
Findings only — no script, profile or build file changed; no release ISO built, nothing published.
documentation/audits/SPIKE-universal-iso-3-2026-07-31.md

MEASURED with a control from the SAME image (one ISO, 15 GRUB entries):
- Automated entry  -> hook fires: ttyS0 marker, marker file,
  /var/lib/proxmox-first-boot/proxmox-first-boot (0700), activation symlink, unit active.
- Terminal-UI entry, normal manual install -> ALL absent, and the proxmox-first-boot PACKAGE is
  not installed at all. A whole-filesystem grep for the marker returns nothing.

Mechanism cited: Config.pm:118 defaults first_boot.enabled=0 and set_first_boot_opt is never
called in the Perl tree; Install.pm:746 returns early without it; Install.pm:1360 skips the
package. proxinstall (graphical) has ZERO occurrences of first-boot. [first-boot] is an
automated-installer feature, unavailable on every interactive path by construction. R-154.

A delivery mechanism DOES exist and is UNTESTED: Install.pm:1343-1372 unpacks every .deb in the
ISO's /proxmox/packages/ into the target on every path (fixed skip-list), then dpkg --configure -a
runs postinsts (:1378) — how PVE ships first-boot itself. Read from source, not measured.

Q5: the public image should carry NO answer.toml at all — that removes the baked root hash, the
disk profile and the whole Spike 1-2 problem space, and makes it a one-line release gate. But
iso-repack.sh:100-106 refuses an ISO without auto-installer-mode.toml. R-155.

Incidental R-153: hub hostInstallVersion=1.19.0 vs SCRIPT_VERSION=1.22.0; hostinstall_gates.py
detects it and exits 1 — the gate works, nothing runs it.

Q3 (real stub at before-network) was NOT reached and is recorded as not reached.
2026-07-31 14:47:18 +02:00

89 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# REPORT — SPIKE 3: on an interactive install, does the ISO deliver anything at all? (2026-07-31)
> Written as `REPORT-universal-iso-spike.md`, not `REPORT.md`: the shared file belongs to today's hub
> v0.85.0 session and the second session in a shared clone never touches it. Supersedes this file's
> Spike 1 and Spike 2 contents.
**Class: Spike.** Findings only — no production file changed, no release ISO built, nothing published.
Evidence: `documentation/audits/SPIKE-universal-iso-3-2026-07-31.md`.
## The answer: no, and more completely than expected
**`[first-boot]` does not fire on an interactive install.** Measured, with a control from the *same*
image (one ISO, 15 GRUB entries):
- **Automated entry** → hook fires: `ttyS0` marker, marker file,
`/var/lib/proxmox-first-boot/proxmox-first-boot` (0700), activation symlink, unit `active`.
- **Terminal UI entry, normal manual install** → every one of those **absent**, and the
`proxmox-first-boot` **package is not installed at all**. A whole-filesystem grep for the marker
returns nothing.
It is not that the hook fails to run — nothing that could run it is ever placed on the system. The
mechanism, cited: `Config.pm:118` defaults `first_boot.enabled => 0` and `set_first_boot_opt` is never
called anywhere in the Perl tree; `Install.pm:746` returns early without the flag; `Install.pm:1360`
skips the package. And `proxinstall`, the graphical installer, contains **zero** occurrences of
`first-boot`. **This is a property of the PVE installer, not a Felhom defect** — but nothing in our
tree records it, which is R-154.
## The commercially relevant part
**A delivery mechanism does exist.** `Install.pm:1343-1372` unpacks **every** `.deb` in the ISO's
`/proxmox/packages/` into the target on *every* install path — a fixed skip-list of known package
names, everything else installed — then `dpkg --configure -a` runs postinsts. That is exactly how PVE
ships `proxmox-first-boot` itself.
**It is read from source, not measured**, and I have not proven either that our repack preserves an
added `.deb` or that a postinst running in the installer chroot can do the job (it runs *inside the
installer*, not on a booted system). Proving it is the top follow-up, ~45 min. Until then the honest
position is: the *insert-stick-install-type-claim-code* experience is **plausible but unvalidated**,
and the documented one-command manual path is what works today.
Incidentally confirmed: the interactive installer shows the target disk and a summary listing
`Bootdisk(s) /dev/sda` before erasing. Your ruling needs no Felhom work for that warning.
## The manual path is already most of the way there
Two of the three things I was asked to look for already exist:
- **The hub already renders the command with the customer-id filled in**
(`customer_unified.html:563-564`, plus a JS generator that adjusts the flags per role).
- **The URL is already short, public and always current** —
`felhom.eu/scripts/felhom-host-install.sh`, git-synced from `main` on a 30-second period.
- **Console display does not exist.** Nothing writes `/etc/issue`; PVE's own banner is what appears
after install. That file is the obvious carrier. Reported, not built.
## Two things I'd flag
**A working gate is red and nobody runs it.** `configs.go:28` has `hostInstallVersion = "1.19.0"`
against `SCRIPT_VERSION = "1.22.0"`, and `scripts/hostinstall_gates.py` detects it and exits 1. The
comment saying drift "is now gated" is true of the gate's existence and false of its enforcement, so
the customer page's install-command generator targets a flag surface three minor versions stale.
**R-153.**
**The cleanest public-image posture is currently blocked by our own tooling.** §6 of the findings
argues the public image should carry **no `answer.toml` at all** — which removes the baked root hash,
the disk profile, and every question Spikes 12 wrestled with, and makes "no `answer.toml`" a
one-line release gate. But `iso-repack.sh:100-106` refuses any ISO lacking `auto-installer-mode.toml`.
That guard is sound for its original case and wrong for this one. **R-155.**
## Not reached
**Q3 — the real stub at `before-network`** was not run; driving the interactive install consumed the
session. It is recorded as not reached, not inferred. Spike 2's structural case stands unrefuted, and
§2 narrows its scope: with no first-boot hook on the interactive path, that question now governs
**operator-built images only**. ~40 min when wanted.
## R-rows
**R-153** (a working gate is red and unrun) · **R-154** (`[first-boot]` is automated-only and nothing
in our tree says so) · **R-155** (`iso-repack.sh` blocks the no-`answer.toml` posture).
## Teardown
All three layers verified positively. demo-hp back to its exact pre-spike state — `spike3/` removed,
0 QEMU processes, 0 loop devices, **disk usage 6.6 G, identical to pre-spike**, 4 storages unchanged,
nothing on `local-lvm`, `drill-r50` stopped and 9201 running. demo-felhom: nothing placed, external
drive observed only. DooPlex: scratchpad 4.4 GB → 80 K, both throwaway passwords destroyed,
`felhom-iso/out/` untouched at 17 ISOs, no production file modified. **Hub-side: nothing created**
verified by fetching and searching the customer list, not asserted. Nothing published.