slice 7 Phase 1: unified bring-up reconcile job (provision + guest-loss DR) (v0.8.0)
The shared front half of provision and guest-loss DR as a journaled reconcile job (internal/reconcile/bringup.go), mirroring the restore-test's crash-safety but keeping the guest on success and applying a scenario-specific identity policy. Agent-only; no hub/wire change. Grounded by the slice-7 bring-up spike (commit 3342993): F1/F3/F4. - RunBringUp: restore -> reset identity -> size -> attach mounts -> start link-up; verdict is liveness (waitRunning), success KEEPS the guest. - identity policy: provision = fresh MAC (net0 sans hwaddr -> PVE regen) + hostname, host-side; machine-id/host-keys regenerate guest-side (systemd + baked golden unit). dr_guest_loss = preserve continuity (keep hostname; keep MAC unless KeepMAC=false). - compensating rollback: mid-flight failure destroys the just-created guest (SameTxnCreated provenance, gated); new Rollback journal flag + Recover.recoverBringUp reap a half-built guest from a crash. - F4: coalesced config PUT + bounded retry on the transient PVE config-lock 500 only. - --selftest=bring-up (mode/archive/vmid/hostname/keep). - configs/build-golden.sh: validated golden recipe incl. the F3 first-boot host-key unit. - doc-03 §9 + identity-reset settled/implemented. Deferred (stated): provisioning back half -> slice 8; host-loss DR + escrow consumption and the BringUpSpec source (hub desired-state) -> slice 10. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,56 @@
|
||||
All notable changes to **felhom-agent** are recorded here. Update on every code
|
||||
change that gets pushed.
|
||||
|
||||
## v0.8.0 — slice 7 Phase 1: unified bring-up reconcile job (provision + guest-loss DR) (2026-06-09)
|
||||
|
||||
The shared FRONT HALF of provision and guest-loss DR, as a journaled reconcile job mirroring the
|
||||
slice-6 restore-test's crash-safety — but it KEEPS the guest on success and applies a
|
||||
scenario-specific identity policy. Agent-only; no hub/wire change (the new guest auto-appears in
|
||||
the host-report via `ListLXC`). Grounded by the slice-7 bring-up spike findings (commit `3342993`):
|
||||
F1 (restore preserves the archived MAC → provision reset is unconditional), F3 (SSH host keys do
|
||||
not auto-regenerate → a baked golden first-boot unit, not an agent guest-internal op), F4 (the
|
||||
transient PVE config-lock 500 → bounded retry).
|
||||
|
||||
### Added
|
||||
- **`reconcile.RunBringUp`** (`bringup.go`) — `BringUpSpec` (Mode `provision`|`dr_guest_loss`,
|
||||
Archive, VMID, RestoreStorage, Hostname, Cores/MemoryMB, RootfsGrowGB, Mounts, KeepMAC,
|
||||
BootTimeout) → `BringUpResult` (VMID, AssignedMAC, Pass, Verified, StartWarnings/Recognized).
|
||||
Sequence (each mutation preceded by journaling the owning entry): restore → identity reset →
|
||||
size → attach mounts → start LINK-UP. **Verdict is liveness (`waitRunning`), never the start
|
||||
exitstatus** (reuses the v0.7.0 WARNINGS surface). **Success KEEPS the guest** (no teardown).
|
||||
- **Scenario-specific identity reset** (doc 03 §9): *provision* → fresh MAC unconditionally
|
||||
(`PUT net0` with `hwaddr` omitted → PVE regenerates, F1) + hostname; machine-id + SSH host keys
|
||||
regenerate guest-side on first boot (golden bake + the new unit) — the agent does NOT touch
|
||||
guest internals. *dr_guest_loss* → preserve continuity (keep hostname; keep MAC unless
|
||||
`KeepMAC=false`); never resets restic/tunnel/hub identity.
|
||||
- **Compensating rollback** — any mid-flight failure destroys the just-created guest
|
||||
(`ClassGuestDestroy`, benign via `Provenance{SameTxnCreated:true}`, gated); on teardown failure
|
||||
the entry is left in-flight for `Recover`. New journal flag **`Rollback`** + `Recover`'s
|
||||
`recoverBringUp` reap a half-built guest left by a mid-job crash (idempotent, via `ListLXC`).
|
||||
- **F4 config-lock retry** — steps 3+5 coalesced into ONE `PUT config` (net0+hostname+cores+
|
||||
memory+mpN); rootfs grow stays its own call. `setConfigWithLockRetry` retries ONLY the transient
|
||||
PVE config-lock 500 (`pveConfigLock`: 500 + "can't lock file"/"got timeout"); any other error
|
||||
fails immediately — never retried.
|
||||
- **`--selftest=bring-up`** (`-mode provision|dr -archive -vmid -hostname [-keep]`) — runs the real
|
||||
journaled job (after a `Recover`), then tears the guest down unless `-keep`.
|
||||
- **`configs/build-golden.sh`** — the validated golden recipe as a script, incl. the F3
|
||||
first-boot `felhom-regen-hostkeys.service` unit (Condition-gated: fires on provision, no-ops on
|
||||
DR). The slice-7 spike archive (which lacks the unit) is superseded.
|
||||
|
||||
### Deferred (stated, not built)
|
||||
- Provisioning BACK HALF (controller deploy, bootstrap, per-guest token mint) → **slice 8**.
|
||||
- Host-loss DR + PBS escrow consumption → **slice 10**.
|
||||
- The SOURCE of a `BringUpSpec` (hub desired-state: which archive/VMID/mounts) → **slice 10**;
|
||||
this job takes the spec as input. `GuestMount` is defined minimally (no hub coupling).
|
||||
|
||||
### Tests
|
||||
- provision happy path (fresh MAC = net0 without hwaddr, hostname, coalesced sizing+mount, rootfs
|
||||
grow separate, started, **guest NOT destroyed**); compensating rollback at each step (restore /
|
||||
config / start-task / waitRunning — asserts the guest WAS destroyed); DR continuity (MAC kept,
|
||||
hostname not reset) + DR `KeepMAC=false` resets MAC; liveness verdict (warnings+running pass /
|
||||
not-running fail); F4 (lock-500→retry→proceed; non-lock-500→fail without retry); owning entry
|
||||
journaled BEFORE restore; reserved/existing VMID refused; `Recover` rolls back / clean.
|
||||
|
||||
## v0.7.0 — restore-test: verdict is liveness, not start-task exitstatus (2026-06-09)
|
||||
|
||||
Fixes a correctness bug found by the live hub-enrollment runbook: the self-restore-test reported
|
||||
|
||||
Reference in New Issue
Block a user