slice 8A (controller half): bootstrap.json ingestion + pinned agent local-API client (v0.35.0)

internal/bootstrap: first-run bootstrap.json ingestion (decision (c)) — seed
controller.yaml + skip setup; idempotent + fail-safe. internal/agentapi:
minimal pinned local-API client (leaf-cert SHA-256 pin, fails closed). config
LocalAPIConfig; startup /storage connectivity probe.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 09:47:54 +02:00
parent 086281b582
commit 2a0d9a1b7a
7 changed files with 608 additions and 0 deletions
+29
View File
@@ -1,5 +1,34 @@
## Changelog
### v0.35.0 — slice 8A: bootstrap.json ingestion + pinned agent local-API client (2026-06-10)
The in-guest controller half of slice 8A (doc 03 §6). Pairs with `felhom-agent` v0.10.0. No
behaviour change for an already-configured controller; adds the first-run provisioning path.
#### Added
- **`internal/bootstrap`** — first-run **`bootstrap.json` ingestion** (config-contract decision (c)).
On startup, if the controller is NOT yet configured AND the host agent's back-half attached a
`bootstrap.json` config mount, the controller **seeds `controller.yaml` from it and comes up
configured, skipping the setup wizard**. Idempotent (an existing `controller.yaml` is **never**
clobbered) and fail-safe (a malformed/absent/missing-identity/unsupported-schema bootstrap leaves
the controller in setup mode — logs, never crashes). The agent emits the stable contract; the
controller owns the translation (the two stay decoupled).
- **`internal/agentapi`** — a minimal **pinned client** for the agent's local API. It reaches the
agent over the bridge, **pinning the agent leaf-cert SHA-256** from the bootstrap (fails closed on
mismatch — `VerifyPeerCertificate` exact leaf-DER match, the same pin convention the agent uses for
the Proxmox/PBS host certs), and authenticates with the per-guest bearer token. In 8A it exercises
`GET /storage` (connectivity + the controller learning its mounts); the `/backup/due` quiesce loop
is 8B.
- **`config.LocalAPIConfig`** (`local_api`: endpoint, fingerprint, token) — seeded from the bootstrap.
- **Startup probe** — when seeded with a local-API endpoint, the controller proves the channel at
boot and logs this guest's mounts (non-fatal).
#### Tests
- bootstrap: seeds when unconfigured (reloads configured, skips setup); never clobbers a configured
controller; stays in setup on malformed / missing-identity / unsupported-schema / absent bootstrap.
- agentapi: correct pin + token reaches `/storage`; a **wrong pin fails closed**; a bad fingerprint
is rejected at construction; colon-separated fingerprints are accepted.
### docs: reflow CLAUDE.md; unify REPORT/CHANGELOG convention; add no-secrets rule (2026-06-08)
#### Changed