docs: CHANGELOG + README for v0.70.0 (config-apply self-restart, restart button, geo report push, always-report geo, autocomplete fix)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,33 @@
|
||||
## Changelog
|
||||
|
||||
### v0.70.0 — config-apply self-restart + geo-restriction UX fixes (2026-06-16)
|
||||
|
||||
Fixes found during live geo testing (rotating the Cloudflare API token).
|
||||
|
||||
- **Config-apply now self-restarts (core fix).** `POST /api/config/apply` previously wrote the new
|
||||
`controller.yaml` but logged "restart needed" and left stale in-process singletons — the Cloudflare
|
||||
client is built once at startup, so a rotated CF token kept 403'ing until a manual LXC restart. Now:
|
||||
if the pushed config is byte-identical to the current one, do nothing (no flap on idempotent
|
||||
re-push); otherwise write, respond 200 (flushed), then **gracefully self-restart** (`os.Exit(0)` after
|
||||
~500ms; the container is `restart: unless-stopped`, so it comes back with fresh config). The exit is
|
||||
behind an injectable `Restarter` seam (`Router.restart`/`SetRestarter`) for unit testing. Removed the
|
||||
stale "restart needed" wording and the dead `OnConfigApplied` hook (Phase-1-retired infra-backup push).
|
||||
- **Manual "Vezérlő újraindítása" button** on the settings page → `POST /api/selfrestart` (auth + CSRF
|
||||
via the `/api/` mount) using the same helper. Confirm dialog → POST → polls `GET /` every 2s until the
|
||||
controller answers → reloads. Self-serve restart without rebooting the whole guest.
|
||||
- **Immediate hub report push on geo change.** A successful geo settings save and a successful manual
|
||||
geo sync now fire an out-of-band, non-blocking report push (`Router.reportPushNow`), so the hub
|
||||
reflects the new geo state / clears a stale `last_sync_error` within seconds instead of after the
|
||||
next ~15-min cycle. (Pattern can extend to other settings later; scoped to geo handlers for now.)
|
||||
- **Always report `geo_restriction`.** `BuildReport` now always populates the field (Enabled=false,
|
||||
empty countries when never configured) instead of omitting it when nil — so the hub always renders
|
||||
the geo section ("Inaktív" when off) rather than hiding it.
|
||||
- **Country autocomplete fixed.** Root cause (diagnosed live): `filterCountries` populated the list
|
||||
correctly but revealed it with `style.display = ''`; the `.geo-country-list` CSS default is
|
||||
`display:none`, so clearing the inline style kept the populated dropdown hidden — no console error,
|
||||
just an invisible list. Latent since the geo feature's first commit (not the hypothesised JS throw).
|
||||
Fix: reveal with `display = 'block'`.
|
||||
|
||||
### v0.69.0 — remove dead infra-backup stubs + the unused restic-password report field (2026-06-16)
|
||||
|
||||
Controller half of the Phase-1 Infra Backup retirement (hub v0.12.0; see
|
||||
|
||||
+13
-1
@@ -1215,15 +1215,27 @@ Five sections:
|
||||
Periodic JSON push (default every 15 min) to the central felhom-hub service:
|
||||
- System: hostname, OS, CPU, memory, disk usage, uptime
|
||||
- Containers: running/stopped counts, per-container CPU/memory
|
||||
- Backup: last run, success, repo stats, snapshot count, restic password (for disaster recovery)
|
||||
- Backup: last DB-dump run, success (disk-tier backup is the host agent's; restic password is no longer reported — removed v0.69.0)
|
||||
- Health: current status, issues, warnings
|
||||
- Stacks: deployed apps with versions and states
|
||||
- Config hash: SHA256 of `controller.yaml` for Hub-side config comparison
|
||||
- **Geo-restriction (always present, v0.70.0):** `geo_restriction` is always populated — `Enabled=false` with an empty country list when never configured — so the Hub always renders the geo section ("Inaktív" when off) instead of hiding it. `buildGeoRestrictionReport` in `internal/report/builder.go`.
|
||||
- **App telemetry** (v0.28.0+): Per-stack memory (current/avg/peak) and CPU averages from the last 15 minutes of metrics data, plus log scan results (error/warning counts with deduplicated issues). Only non-protected, deployed stacks are included. Backward-compatible: old Hub versions silently ignore this field.
|
||||
- **Controller telemetry** (v0.32.4+): The controller's own container (`felhom-controller`) is included as a special entry in the `app_telemetry` array. Its memory/CPU metrics come from the same metrics collector, and its log warnings/errors are scanned via `docker logs` using the same pipeline as app containers. This reuses all existing Hub telemetry infrastructure (memory trend charts, known issues, fleet aggregation) with zero Hub-side changes.
|
||||
|
||||
Bearer token authentication, 3-attempt retry with 5-second backoff. Push status tracked via `PushStatus` struct (LastAttempt, LastSuccess, LastError, consecutive failures) — used by the monitoring page and alert system to show Hub connection health.
|
||||
|
||||
**Immediate report push on geo change (v0.70.0):** besides the periodic cycle, a successful geo settings save and a successful manual geo sync fire an **out-of-band, non-blocking** report push (`Router.reportPushNow`, wired in `main.go` to `BuildReport`+`Push` in a goroutine), so the Hub reflects the new geo state / clears a stale `last_sync_error` within seconds instead of after the next ~15-min cycle. Currently scoped to the geo handlers; the same seam can be reused for other settings later.
|
||||
|
||||
#### Config apply + self-restart (`internal/api/router.go`, `internal/api/selfrestart.go`)
|
||||
|
||||
`POST /api/config/apply` (Hub-authed) writes a new `controller.yaml`, but the new config only takes effect on **restart** — singletons such as the Cloudflare client are built once at startup (so a rotated CF API token would otherwise keep failing). Behaviour (v0.70.0):
|
||||
|
||||
- **No-op guard:** if the pushed body is byte-identical to the current file, do nothing — no rewrite, no restart (the Hub may re-push idempotently; never flap on a no-op).
|
||||
- Otherwise: write `0600`, respond `200` (flushed), then **gracefully self-restart** — `gracefulSelfRestart` waits ~500 ms for the response to flush, then `os.Exit(0)`. The container runs `restart: unless-stopped`, so Docker brings it back with the fresh config, and a startup report is pushed. The exit sits behind an injectable seam (`Router.restart` / `SetRestarter`) for unit testing.
|
||||
|
||||
**Manual restart (v0.70.0):** `POST /api/selfrestart` (session auth + CSRF via the `/api/` mount) runs the same helper — surfaced as the **"Vezérlő újraindítása"** button on the settings page (confirm → POST → poll `GET /` every 2 s → reload), so a customer can recover the controller without rebooting the whole guest.
|
||||
|
||||
#### App Telemetry (`internal/metrics/telemetry.go`, `internal/metrics/logscanner.go`, `internal/report/telemetry.go`)
|
||||
|
||||
Each report push now includes per-app telemetry data:
|
||||
|
||||
Reference in New Issue
Block a user