Files
felhom.eu/REPORT-universal-iso-spike.md
T
admin 61e9b55737 SPIKE 4: a .deb in the ISO DOES deliver on an interactive install
Findings only — no script, profile or build file changed; no release ISO built, nothing published.
documentation/audits/SPIKE-universal-iso-4-2026-07-31.md

MEASURED, with a control, and the negative control is in the SAME box. One ISO (15 GRUB entries),
a trivial probe .deb injected into /proxmox/packages/, two qm-created VMs on demo-hp (400
interactive / 401 automated control) on a scratch dir storage at the /mnt/nvme-1tb mount ROOT.

Interactive (Terminal UI) install:
- package installed (ii felhom-spike4-probe 0.0.1)
- postinst RAN (marker + content intact)
- it enabled a systemd unit, and that unit FIRED ON FIRST BOOT (uptime 7.98s, pid1=systemd)
- while on the same machine proxmox-first-boot is NOT installed and /var/lib/proxmox-first-boot
  does not exist — Spike 3's negative reproduced, not assumed.

Postinst environment (identical both paths): pid1=unconfigured.sh, NO running systemd, but
'systemctl enable' SUCCEEDS; /proc+/sys mounted; network+DNS happened to be up (inherited from the
installer's DHCP — must NOT be relied on). Constraints: never systemctl start/daemon-reload, never
require network, never fail, do the real work in the unit at first boot.

Repack preserves it, but a naive 'xorriso -boot_image any replay' fails with 'Overlapping MBR
partition entries' — iso-repack.sh:270-292 already documents that exact failure and its fix.

R-153 RETRACTED into R-94 leg (b): OPEN-ITEMS.md:15 carries it verbatim at READY (XS), and R-29
says explicitly 'do not mint a new ID for a new instance'. Spike 3's further claim that the drift
leaves the generator 'three minor versions stale' was FALSE and is corrected — R-94 retracts that
exact reading; the served script is always main, so 1.22.0 is what every install already gets.

No new R-rows opened.
2026-07-31 15:35:07 +02:00

5.9 KiB
Raw Blame History

REPORT — SPIKE 4: can a .deb in the ISO deliver the stub on an interactive install? (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 13 contents.

Class: Spike. Findings only — no production file changed, no release ISO built, nothing published. Evidence: documentation/audits/SPIKE-universal-iso-4-2026-07-31.md.

The answer is yes, and it was measured with the negative control in the same box

One ISO, 15 GRUB entries, a trivial probe .deb injected into /proxmox/packages/. Two VMs on demo-hp built with qm so the run was visible in the web console: 400 interactive, 401 automated control.

On the interactive install (spikefour.felhom.eu):

  • the package is installed — ii felhom-spike4-probe 0.0.1
  • its postinst ran — marker file present, content intact
  • it enabled a systemd unit, and that unit fired on first boot (uptime 7.98 s, pid1: systemd)
  • and on that same machine, proxmox-first-boot is not installed and /var/lib/proxmox-first-boot does not exist — Spike 3's negative reproduced, not assumed

So the two delivery mechanisms are independent, and the one that survives the path we are actually shipping is the .deb. The product — insert the stick, install Proxmox normally choosing your own disk and password, box sets itself up and waits for a claim code — is now measured rather than hoped for. With one honest caveat: what was measured is a trivial probe package, not Felhom's real stub. Packaging the real stub and confirming pairing end-to-end is the last step before a spec (~60 min).

What a postinst may and may not do

Identical on both paths: pid1 = unconfigured.sh, no running systemd, /proc and /sys mounted, and systemctl enable succeeds (it wrote the symlink). Network and DNS happened to be up — inherited from the installer's own DHCP.

Four constraints for the real postinst, so they get written against rather than discovered:

  1. Never systemctl start or daemon-reload — there is no systemd running. enable is the only verb.
  2. Never require the network, despite it being present here. A box installed with the cable out gives a postinst no route, and a failing postinst breaks the customer's install.
  3. Never fail — guard everything, exit 0.
  4. Do the real work in the unit at first boot, where systemd, network and a booted kernel exist.

Two smaller results

The repack preserves the .deb, but not naively. xorriso … -boot_image any replay fails with "Overlapping MBR partition entries" — and iso-repack.sh:270-292 already documents that exact failure and its fix. Mirroring it produced a working image (19 El Torito entries; the .deb extracted back out is byte-identical). So this is an insertion into an extract→modify→re-master cycle our repack already performs, not a new build stage.

Q3: iso-repack.sh:100-106 refuses an ISO without auto-installer-mode.toml. It is a guard, not a structural requirement, and its reasoning is sound for the shape it was written for — already R-155, cited exactly here. With no mode file the stock grub.cfg does not emit the Automated entry at all; with a mode file but no answer, that entry aborts safely and loudly.

A correction I owe you from last session

R-153 is retracted. The register grep this task mandated shows R-94 already carries it verbatim at OPEN-ITEMS.md:15, status READY (XS), with leg (b) being precisely "the gate fails today and is invoked by nothing" — and R-29, the class, says in terms "do not mint a new ID for a new instance." Spike 3 filed a duplicate.

And the substantive half of that Spike 3 claim was wrong. I wrote that the drift left the customer page's install-command generator "targeting a flag surface three minor versions stale." R-94 explicitly retracts exactly that reading: the constant selects no script — it renders as a text label, and the command beneath it fetches the script the website git-syncs from main, so 1.22.0 is what every install already gets. It is a wrong number on your screen and nothing more. I overstated it.

Still unknown

The real stub has not been packaged — that is the one thing between here and a build spec. Also unproven: dpkg --configure -a ordering for a package with dependencies; an ISO that never went through prepare-iso (blocked by R-155, which this spike was fenced from changing); and the Graphical installer, where the result should hold a fortiori since the .deb path is in Install.pm, shared by all front-ends — but that is inference, not measurement.

Spike 3's Q3 — the real stub at before-networkthis session did not touch it. Note it is now partly superseded: on the .deb route the unit's ordering comes from the unit file, not from [first-boot].ordering.

R-rows

None opened. Each candidate was grepped against the register first: the delivery result is a positive finding, the postinst constraints belong in the build spec, and the repack guard is already R-155. R-153 retracted into R-94 leg (b) / R-29.

Teardown

All three layers plus the scratch storage, verified positively. demo-hp: VMs 400/401 purged, storage spike4 removed (storage.cfg back to 4, grep -c spike4 = 0), /mnt/nvme-1tb/images/ empty, disk usage 6.6 G — identical to pre-spike, probe ISO and driver removed, 0 loop devices, drill-r50 stopped and untouched, 9201 running, felhom-backup unmodified, nothing on local-lvm. DooPlex: workspace scratch 4.8 GB removed, scratchpad 3.3 GB → 88 K, both throwaway passwords destroyed, 17 ISOs in out/ untouched, no production file modified. Hub-side: nothing created — the VMs took LAN DHCP leases but never ran felhom-host-install.sh or contacted the hub; verified by fetching and searching the customer list. Nothing published.