v0.96.0 — R-50 island NIC: provision attaches the guest island net1

- LocalAPIConfig.island_bridge + island_guest_addr (+ IslandEnabled, Validate
  all-or-nothing + CIDR guard)
- buildBringUpConfig attaches static net1 (island) on provision + DR when set;
  absent otherwise (pre-R-50 byte-for-byte). Plumbed from cfg.LocalAPI at both
  RunBringUp sites. Endpoint already follows listen_addr (A0: no template change).
- healer stays eth0-only (A3 verify-only) — red-proof test locks the scoping
- example config + firewall example rewritten for the island; REUSE updated
- 3 non-hollow tests; full green. MinAgent unchanged.

Coupling: host-install island config requires agent >= 0.96.0 (vouch first).
This commit is contained in:
2026-07-25 14:16:23 +02:00
parent 36ed6594d4
commit dfd5d731ee
11 changed files with 223 additions and 68 deletions
+26
View File
@@ -1,3 +1,29 @@
## v0.96.0 — R-50 island NIC: provision attaches the guest's island net1 (2026-07-25)
Additive; **MinAgent unchanged** (no controller coupling — the controller dials whatever `bootstrap.json`
says, and the pin is address-independent). Implements the provisioning half of the R-50 island control
plane, spiked GO in `felhom.eu/documentation/audits/SPIKE-island-bridge-2026-07-25.md`. A fresh install
is now born immune to F1 (`AUDIT-vacation-remote-ops-2026-07-20`: a LAN/DHCP move made the agent fail to
bind → storage/PBS/quiesce/restore-test/DR down, silently).
- **`LocalAPIConfig`** gains `island_bridge` + `island_guest_addr` (config.go). `IslandEnabled()` = both
set. `Validate()` enforces all-or-nothing + a CIDR guest addr — a half-set/malformed island fails at
load (a botched install), never a silent LAN fallback that would leave an island bind with no island NIC.
- **`buildBringUpConfig`** (reconcile/bringup.go): when both island fields are set, attaches a static
`net1=name=eth1,bridge=<vmbr9>,ip=<169.254.253.2/30>` (no hwaddr → fresh per-guest MAC) on BOTH
provision and DR bring-up. Empty = pre-R-50, no net1 (byte-for-byte the old config on non-island hosts).
Plumbed from `cfg.LocalAPI` at both `RunBringUp` call sites (cmd/main.go). The bootstrap `endpoint`
already derives from `listen_addr` (main.go), so moving the agent bind to the island moves the guest
dial for free — **no template change** (A0 determination).
- **Design note (A0/A3):** endpoint is config-derived, so no code was needed there; the guestnet healer
is eth0-only (`parseMode` is dev-scoped) so the static island `eth1` is outside its scope — a red-proof
test locks that in (`TestParseMode_IslandStaticNICDoesNotConfuseEth0`) rather than changing the healer.
- Tests (all non-hollow, red-proofed): `TestBuildBringUpConfig_IslandNIC`,
`TestLocalAPIConfig_IslandValidation`, plus the healer scoping test above.
- **Coupling (deploy order):** a host-install that writes the island config REQUIRES agent ≥ 0.96.0 to
read `island_guest_addr` and attach net1 — vouch 0.96.0 before island installs go live. Migration of
existing boxes is the Phase-B runbook (`felhom.eu/documentation/runbooks/RUNBOOK-island-migration.md`).
## v0.95.0 — SMART coverage: union-path drives + LVM/dm root + device model (2026-07-25)
Additive; **MinAgent unchanged**; hub untouched (unknown JSON fields ignored). Implements the graded