feat(hub): v0.57.0 reinstall-of-existing-customer arc — claim/offsite/escrow continuity
F2 claim re-issue on clean-slate re-enroll (ReissueForReenroll, host-enroll mint path, single-bump, reset code; hub never stores the password so fork B). F3 offsite re-issue on re-enroll (ReissueOffsiteForCustomer, same machinery as the manual button). 2.3 escrow honesty (red-proofed): re-issuing offsite marks the escrow stale (MarkEscrowStale), withholds the mismatched restic hash from auto-confirm, DR checklist shows stale not done. Events: claim_reissued_reenroll / offsite_reissued / escrow_stale. Controller + scripts unchanged (source contradicted both premises): the controller reads escrow prereqs live from the agent; the installer can't know the descriptor-provisioned storage id. F4 root fix is agent-side -> ROADMAP R-22; demo unblocked live (Part 0 ACL grant). VALIDATION doc F2 erratum + F3/F4 dispositions. Green gate + Scenario-C red-proof pass.
This commit is contained in:
@@ -2,36 +2,54 @@
|
||||
|
||||
> **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md).
|
||||
|
||||
## R-21 physical run — N100 bare-metal reinstall + onboarding rehearsal — 2026-07-16
|
||||
## Reinstall-of-existing-customer arc — F2/F3/F4/2.3 (hub v0.57.0) — 2026-07-16
|
||||
|
||||
Supervised run (Viktor at the box, CC on Phase-0 prep + the SSH-side legs). Full detail:
|
||||
**`documentation/tests/VALIDATION-n100-baremetal-2026-07-16.md`**. No production code changed.
|
||||
Closes the N100 physical-run findings (`documentation/tests/VALIDATION-n100-baremetal-2026-07-16.md`).
|
||||
**Only the hub shipped** — controller + scripts unchanged (both spec premises contradicted by source,
|
||||
below). Baseline: felhom.eu @ `dd961a6`, hub v0.56.0 → **v0.57.0**.
|
||||
|
||||
**Core objectives — GREEN.** The demo N100 (felhom-pve, serving demo-felhom.eu) was reinstalled
|
||||
clean-slate from a pipeline-built ISO (`felhom-pve-9.2-1-v1.16.0-n100-demo.iso`, profile filter
|
||||
`ID_SERIAL_SHORT=QDF922W009654S30EX`, appliance). The first-boot chain reached **rc-0 on the first
|
||||
attempt (`NRestarts=0`)** on real hardware — enrolled `demo-felhom`, provisioned guest 9201, agent
|
||||
0.88.0, WG up, `bootstrap.env` shredded. This **closes slice A's operator-gated rc-0 boundary on
|
||||
metal.** Serial-filter safety proven on real hardware (external-HDD canary byte-identical). PBS-DR
|
||||
reconciler self-healed on the reused peer (all four steps done incl. escrow). DMI verdict on real
|
||||
cheap hardware: all "Default string" → slice-C keys on **MAC + UUID**.
|
||||
### Fork verdicts (source-verified)
|
||||
- **2.1 = FORK B.** `hub/internal/claim/engine.go` + `handler.go:413-429` (`MarkClaimed`, set-only): the
|
||||
hub stores the claim code + a **claimed boolean**, never the password hash (controller-owned by the
|
||||
arc's design). Fork A (hub delivers the hash) would violate the design → **B** (bump generation + email).
|
||||
- **3.1 = no controller change (spec premise contradicted).** `controller/internal/agentapi/escrow.go`
|
||||
`EscrowPreflight` fetches the prereq checklist **live from the agent** (`GET /escrow/preflight`); it
|
||||
never sources `pbs_storage_id` from hub config. The agent seeds it on PBS-DR convergence. The fresh
|
||||
box "lacked" it only because F4's 403 blocked convergence — Part 0 + the demo grant restore it. **No
|
||||
controller v0.138.0.**
|
||||
|
||||
**The obstacle was firmware, not the pipeline.** This board's early AMI `AN3PLUS 0.01` UEFI cannot
|
||||
boot the ISO's GRUB **from USB** (`relocation 0x0 is not implemented yet`); Secure-Boot-off and
|
||||
shim-bypass did **not** help (it's GRUB, not shim). The identical ISO boots in reference UEFI, and the
|
||||
box's installed GRUB boots fine from the SSD — so it's the firmware relocating the ISO's USB-loaded
|
||||
GRUB. **Worked around live** by rebuilding the stick's `BOOTX64.EFI` with `grub-mkimage` from the box's
|
||||
own working `2.12-9+pmx2` GRUB (all needed modules embedded, config that searches+boots the ISO). This
|
||||
is the top **slice-B input**: the pipeline should ship a firmware-compatible loader and/or a PXE path.
|
||||
### Part 0 — live unblock (done, reversible)
|
||||
Granted `FelhomAgentStore` on `/storage/felhom-offsite` (user + token) on felhom-pve. The agent's next
|
||||
tick converged: created the storage, ran `felhom-pbs-apply grant`, **seeded `escrow.pbs_storage_id`**,
|
||||
`pbsdr: converged state=applied`; `pvesm` shows **felhom-offsite pbs active**. The 403s stopped.
|
||||
|
||||
**Findings to tackle (7):** F1 firmware boot loader (HIGH, slice-B); F2 no claim-code re-issue on
|
||||
reinstall (+ verify open-vs-gated); F3 offsite creds need re-issue on reprovision; F4 PBS-DR 403 —
|
||||
install ACL grants only default `felhom-pbs`, not the config's `felhom-offsite` storage id; F5 guest
|
||||
RAM 2 GB not configurable; F6 drive-initialize formats but doesn't mount+attach (client-disconnect
|
||||
aborts post-mkfs, no UI feedback); F7 storage Back-route → /settings. F2/F3/F4 are reused-customer
|
||||
clean-slate edges feeding R-1/Peti. BookStack deployed + works.
|
||||
### Part 2 — hub v0.57.0 (shipped)
|
||||
- **F2 claim continuity** — `claim.ReissueForReenroll` (claimed → bump generation once + reset email;
|
||||
no-op unclaimed), hooked at the host-enroll **mint path** (single-bump-per-re-enroll). Event
|
||||
`claim_reissued_reenroll`.
|
||||
- **F3 offsite continuity** — the re-enroll path calls `web.ReissueOffsiteForCustomer` (same machinery
|
||||
as the manual button; wired via `SetOffsiteReissuer`). Event `offsite_reissued`.
|
||||
- **2.3 escrow honesty** — `offsite.ReissueCredentials` marks the escrow stale (`store.MarkEscrowStale`;
|
||||
cleared by the next ceremony); the ACK **withholds** the mismatched `restic_pw_sha256`; the DR
|
||||
checklist shows **stale** not "done." Event `escrow_stale`.
|
||||
|
||||
**Current state:** box healthy, demo-felhom.eu live, guest 9201 running (controller/traefik/cloudflared/
|
||||
filebrowser/bookstack), external HDD reformatted + attached as `hdd_1`. Onboarding not finished (claim
|
||||
+ escrow pending on F2/F3/F4). Boot stick (secret-bearing, with the GRUB workaround) to be wiped at
|
||||
teardown. Findings will be worked next per Viktor.
|
||||
### Scenarios / red-proofs
|
||||
- **A (claim)**: `TestReissueForReenroll` — claimed rotates + reset email; unclaimed no-op. PASS.
|
||||
- **C (escrow, red-proof)**: `TestReissue_InvalidatesEscrow` — after a re-issue the escrow is STALE and
|
||||
the hash is withheld. **Red-proof run-fail-revert:** with `MarkEscrowStale` gutted → FAIL ("escrow
|
||||
must be STALE… advertising ceremony-done against a key the repo no longer accepts"); restored → PASS.
|
||||
- Green gate: `go build ./... && go vet ./... && go test ./...` all clean.
|
||||
- Deployed versions + Scenario E (escrow prereqs green on the live demo): see the deploy section / the
|
||||
task's verification.
|
||||
|
||||
### F4 — NOT an installer fix (reported)
|
||||
The DR storage id lives in the agent-domain **pbs_dr descriptor** (`web/pbsdr.go`), provisioned post-WG
|
||||
— not in the installer-fetched config — so `step_agent_config()` can't derive it. The block is a
|
||||
bootstrap circularity: the agent's token-auth pre-check `GET /storage/<id>` 403s and aborts before its
|
||||
own root-run `felhom-pbs-apply grant`. **Root fix is agent-side → ROADMAP R-22 (agent train)**; the demo
|
||||
was unblocked live (Part 0). Default-storage-id customers (all new/Peti installs) already work — F4 only
|
||||
bites non-default ids. Per Viktor: do NOT flip the demo's descriptor id.
|
||||
|
||||
### NOT done
|
||||
The escrow **ceremony itself** — Viktor's S10 step (CC's boundary is prereqs-green; CC never runs the
|
||||
ceremony, touches R, or mints a recovery code).
|
||||
|
||||
Reference in New Issue
Block a user