slice 8B (agent half): /backup/due cadence policy + /backup/status phases (v0.11.0)

internal/localapi: real /backup/due (cadence; due when no successful backup or
newest older than backup.backup_cadence_seconds; false in-window after success;
failed doesn't count) + /backup/status phases (idle|running|done|failed + job
id) + POST /backup single-flight with job id. Drives the controller quiesce loop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 10:44:50 +02:00
parent e51b3a2f66
commit 33dfd9afb3
6 changed files with 352 additions and 54 deletions
+26
View File
@@ -3,6 +3,32 @@
All notable changes to **felhom-agent** are recorded here. Update on every code
change that gets pushed.
## v0.11.0 — slice 8B: app-consistent backup — /backup/due policy + /backup/status phases (2026-06-10)
The agent half of slice 8B (doc 03 §8). Turns the 8A thin backup stubs into the real policy the
in-guest controller's quiesce loop drives (controller half: `felhom-controller` v0.36.0). No hub
change. The downtime optimization (`vzdump --mode snapshot` + a `snapshotted` phase) is the 8B.2
fast-follow; the hub-served per-guest policy is slice 10.
### Changed (`internal/localapi`)
- **`GET /backup/due`** — real **cadence** policy (replaces the 8A "never backed up" stub): a guest
is due when no **successful** backup is recorded OR the newest one is older than the agent-local
cadence (`backup.backup_cadence_seconds`, default 24h). A successful `POST /backup` flips due to
**false** for the window, so the controller won't re-quiesce in a loop. A failed backup does not
satisfy the cadence. Returns `age_seconds` for diagnosis.
- **`GET /backup/status`** — real **phases** `idle | running | done | failed` + the job id, so the
controller can poll a backup to completion (was: just the latest stored backup).
- **`POST /backup`** — returns a **job id** + `running` phase; tracks the in-flight job and is
**single-flight per guest** (a second POST while one runs returns the same job — no concurrent
vzdump). On completion the job transitions done/failed and the result is recorded to the store.
- Config: `backup.backup_cadence_seconds` + `BackupCadence()`; the local-API server takes the cadence.
### Tests
- `/backup/due`: due when stale / no backup, **not due within the window after a success**, due again
past the cadence, **a failed backup does not count**. `/backup/status`: running→done and
running→failed (gated fake to observe the running phase). `POST /backup` single-flight (one vzdump
for concurrent POSTs). All still self-scoped (token→guest).
## v0.10.0 — slice 8A: agent local-API server + provisioning back-half (2026-06-10)
The host-agent half of slice 8A (doc 03 §6). Adds the per-guest **local API** the in-guest