docs: v0.42.0 controller-swap — README endpoint + REPORT (live-validated)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TtXesNa2LGbMmE4DNL6SE7
This commit is contained in:
2026-06-26 21:43:22 +02:00
parent b17d07bf2d
commit 2dcee2d7e8
2 changed files with 77 additions and 68 deletions
+17
View File
@@ -141,6 +141,23 @@ See the table in [`internal/proxmox/doc.go`](internal/proxmox/doc.go). Summary:
lifecycle **including restore** is API-token-covered; OS-root is confined to golden-image
`keyctl` create, host mounts, and SMART/sensors (phase3 §B3).
### Controller swap (agentic controller update, Phase 1 — v0.42.0)
The local API (`internal/localapi/`) owns the in-guest controller image **swap** — the new-architecture
replacement for the controller's dead in-container `docker compose` self-update. The in-guest controller
pre-pulls the target image then calls the agent:
- `POST /controller/swap {image}` (`withGuest`-scoped) → **202**, then async: record previous
(`/var/lib/felhom-agent/controller-swap-<vmid>.json`) → confirm the target is present in the guest →
write `/etc/felhom-controller-image``systemctl restart felhom-controller-bootstrap.service` → poll
the new controller to healthy (`docker inspect`, ≤90s) → **roll back** to the previous image if not (the
guest is never left without a controller). Strict image-ref gate; single-flight per guest (409).
- `GET /controller/swap/status``{state, current, previous, target, error}`.
The agent is **external** to the controller container, so it survives the controller being killed
mid-swap (which the controller cannot do to itself). `GuestBinder.GuestExec` is the single `pct exec`
seam. Exercise directly with `--selftest=controller-swap -vmid <id> -image <ref>`.
### TLS trust
The host serves a self-signed cert. Verification is **not** blanket-disabled. Pick one in