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:
2026-06-09 21:27:49 +02:00
parent 9f6753de0f
commit 57405c1a99
10 changed files with 1184 additions and 73 deletions
+9 -2
View File
@@ -50,8 +50,15 @@ type JournalEntry struct {
// scratch guest may exist and MUST be destroyed" — so Recover resolves it by ensuring
// VMID is gone (a benign teardown), NOT by re-checking any sub-task UPID. The entry is
// terminal only after teardown. See recover.go.
Scratch bool `json:"scratch,omitempty"`
At time.Time `json:"at"`
Scratch bool `json:"scratch,omitempty"`
// Rollback marks an entry that OWNS a guest the agent is CREATING in this journaled
// bring-up transaction (slice 7, doc 03 §9). While such an entry is in-flight, the
// invariant is "VMID may be a half-built guest and MUST be destroyed" (a compensating
// rollback) — so Recover resolves it by ensuring VMID is gone, NOT by re-checking the
// restore sub-task UPID (whose OK status would otherwise leave a half-provisioned guest).
// On SUCCESS the bring-up records this entry terminal and KEEPS the guest. See recover.go.
Rollback bool `json:"rollback,omitempty"`
At time.Time `json:"at"`
}
// Journal is the durable operation log + idempotency store. It mirrors