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
|
## 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)
|
### 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
|
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:
|
Periodic JSON push (default every 15 min) to the central felhom-hub service:
|
||||||
- System: hostname, OS, CPU, memory, disk usage, uptime
|
- System: hostname, OS, CPU, memory, disk usage, uptime
|
||||||
- Containers: running/stopped counts, per-container CPU/memory
|
- 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
|
- Health: current status, issues, warnings
|
||||||
- Stacks: deployed apps with versions and states
|
- Stacks: deployed apps with versions and states
|
||||||
- Config hash: SHA256 of `controller.yaml` for Hub-side config comparison
|
- 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.
|
- **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.
|
- **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.
|
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`)
|
#### App Telemetry (`internal/metrics/telemetry.go`, `internal/metrics/logscanner.go`, `internal/report/telemetry.go`)
|
||||||
|
|
||||||
Each report push now includes per-app telemetry data:
|
Each report push now includes per-app telemetry data:
|
||||||
|
|||||||
Reference in New Issue
Block a user