v0.86.0: Phase 2 managed updates — floor-driven auto-update
The controller honors an operator-enforced minimum version (FLOOR) on the hub report ACK and auto-updates to the floor when below it (managed default, no click), reusing the Phase 1 in-guest-pull + agent-swap + rollback. Latest stays the opt-in button; the floor is the auto-target, never latest. - pusher.go: PushResponse += min_controller_version, latest_version (existing ACK seam) - main.go: OnPushResponse → updater.SetFloor + MaybeAutoUpdate (rides report cycle) - updater.go: SetFloor/GetFloor + MaybeAutoUpdate reusing performUpdate (auto-floor); no-op at/above floor, floor>latest, dev/no-agent/backup; no flap (in-mem+persisted) - settings UI (HU): floor display + auto restart-poll during an auto-update - tests: below/at/floor>latest/no-flap/raised-floor; below-floor red-proof verified - no agent change (reuses Phase 1 POST /controller/swap) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FSZmmSFVzGwEzhYmxbkgBK
This commit is contained in:
+24
-2
@@ -1086,8 +1086,30 @@ in-guest and delegates the container **swap to the host agent**, which owns the
|
||||
or failure (rollback → version mismatch). The Settings button polls /api/health and reloads.
|
||||
```
|
||||
|
||||
Latest-only (no version picker). Per-customer version floor + operator desired-version fleet-push are
|
||||
Phase 2 (hub-side). No host agent wired (un-provisioned guest) → self-update unavailable.
|
||||
The button is latest-only (no version picker) and opt-in. No host agent wired (un-provisioned guest) →
|
||||
self-update unavailable.
|
||||
|
||||
##### Phase 2 — managed updates: the version FLOOR (v0.86.0)
|
||||
|
||||
On top of the opt-in button, the controller now honors an operator-enforced **minimum version (FLOOR)**.
|
||||
The hub returns the customer's *effective* floor (per-customer override else a global default) on the
|
||||
**report ACK** (`min_controller_version`, alongside `latest_version`). The controller's report pusher
|
||||
(`internal/report/pusher.go`, `OnPushResponse`) hands the floor to the updater (`SetFloor`) and calls
|
||||
`MaybeAutoUpdate()` — **on the existing report cycle, no new timer/endpoint**:
|
||||
|
||||
- If the box is **below** the floor it **auto-updates to the floor** (not latest) by reusing the Phase 1
|
||||
flow above (`performUpdate`, `initiatedBy="auto-floor"`) — same pull → agent swap → rollback. No
|
||||
customer click.
|
||||
- **At/above** the floor: nothing (it does **not** chase latest — that's the button's job).
|
||||
- Guards: dev build / no agent / backup running → skip; floor must be **pullable** (floor ≤ latest
|
||||
available; floor > latest → warn + do nothing); one attempt per below-floor condition (in-memory flag
|
||||
+ persisted `update-state.json`) → **no flapping/storm**.
|
||||
- Settings UI shows "Minimális verzió (üzemeltető): X" and, during an auto-update, the same restart-poll
|
||||
panel as the button.
|
||||
|
||||
The floor is the **auto-target** (the operator raises it for a controlled fleet rollout); latest stays
|
||||
the customer's manual opt-in. Floor source + operator UI are hub-side (felhom-hub v0.15.0). **No agent
|
||||
change — Phase 2 reuses the Phase 1 `POST /controller/swap`.**
|
||||
|
||||
##### Design Philosophy
|
||||
|
||||
|
||||
Reference in New Issue
Block a user