diff --git a/CHANGELOG.md b/CHANGELOG.md index a10f854..6978624 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ ## Changelog +### What was just completed (2026-02-20 session 63) +- **v0.20.0 — Hub Config Management (Phase B):** + + Two new features enabling the Hub to manage and compare controller configuration remotely. + + **Feature A — Config Apply Endpoint:** + - `router.go`: Added `POST /api/config/apply` — accepts YAML body from Hub, validates it's parseable via `config.LoadFromBytes()`, writes atomically to controller.yaml (`.tmp` + `os.Rename`), returns success JSON. Restart required to apply. + - `router.go`: Added `GET /api/config/hash` — returns SHA256 hex digest of current controller.yaml + - `router.go`: Router struct gained `configPath string` field; `NewRouter()` signature updated + - `config.go`: Added `LoadFromBytes([]byte)` — parses YAML without file I/O (for validation) + - `config.go`: Added `FileHash(path)` — SHA256 hex digest helper + - `main.go`: Config endpoints use same dual auth middleware as self-update (session OR Hub API key Bearer token) + - `main.go`: Added `/api/config/` mux entry with `selfUpdateAuthMiddleware` + + **Feature B — Config Hash in Reports:** + - `types.go`: Added `ConfigHash string` field to `Report` struct (JSON: `config_hash`) + - `builder.go`: `BuildReport()` now accepts `configPath string` parameter, computes SHA256 of controller.yaml and includes it in every report + - `main.go`: All 4 `BuildReport()` call sites updated to pass `*configPath` + - Hub uses this hash to compare against its generated YAML — shows "In sync" / "Config mismatch" / "Unknown" on the unified customer detail page + ### What was just completed (2026-02-20 session 62) - **docker-setup.sh — Hub Config Download:** - Added `--hub-customer` and `--hub-password` CLI flags for downloading pre-configured controller.yaml from Felhom Hub diff --git a/controller/README.md b/controller/README.md index 4ab883e..ead5001 100644 --- a/controller/README.md +++ b/controller/README.md @@ -4,7 +4,7 @@ A single, lightweight Go container that replaces Portainer + scattered systemd scripts with a unified, Hungarian-language web dashboard for managing Docker Compose stacks, backups, storage, monitoring, and notifications on customer hardware. -**Current version: v0.19.0** +**Current version: v0.20.0** --- @@ -774,6 +774,7 @@ Periodic JSON push (default every 15 min) to the central felhom-hub service: - Backup: last run, success, repo stats, snapshot count, restic password (for disaster recovery) - Health: current status, issues, warnings - Stacks: deployed apps with versions and states +- Config hash: SHA256 of `controller.yaml` for Hub-side config comparison Bearer token authentication, 3-attempt retry with 5-second backoff. @@ -1045,6 +1046,20 @@ All daily jobs use Europe/Budapest timezone. Skip-if-running prevents concurrent Self-update endpoints accept session auth OR `Authorization: Bearer ` for external triggering. +### Config Management + +| Method | Endpoint | Description | +|--------|----------|-------------| +| POST | `/api/config/apply` | Apply new controller.yaml from Hub (atomic write) | +| GET | `/api/config/hash` | Get SHA256 hash of current controller.yaml | + +Config endpoints accept session auth OR `Authorization: Bearer ` (same as self-update). The `/api/config/apply` endpoint: +- Accepts raw YAML body (the generated config from Hub) +- Validates YAML is parseable before writing +- Atomic write: writes to `.tmp` then `os.Rename` for crash safety +- Does NOT reload config — restart required to apply changes +- Returns `{"ok": true, "message": "Config applied. Restart controller to apply changes."}` + ### Metrics | Method | Endpoint | Description | @@ -1066,7 +1081,7 @@ Response format: `{"ok": true/false, "data": ..., "error": "...", "message": ".. # On build server (192.168.0.180) cd ~/build/felhom-controller git -C ~/git/deploy-felhom-compose pull -./build.sh v0.14.1 --push +./build.sh v0.20.0 --push ``` ### Deploy on customer node @@ -1132,6 +1147,7 @@ See `docker-compose.yml` for the full volume configuration. - [x] Infrastructure config in cross-drive backup (v0.14.1) — stacks dir + controller.yaml in `_infra/` + restic - [x] Disaster recovery (v0.15.5) — Hub-based infra backup, auto-mount by UUID, restore UI with full-page takeover - [x] Controller self-update (v0.16.0) — Watchtower-style pull + restart, Settings page UI, API key auth, auto-update scheduling +- [x] Hub-managed config (v0.20.0) — Config apply endpoint (`POST /api/config/apply`), config hash in reports for sync comparison ### In Progress / Planned @@ -1147,7 +1163,7 @@ See `docker-compose.yml` for the full volume configuration. | Node | Hardware | Domain | Status | |------|----------|--------|--------| -| demo-felhom | Acemagic GK3PLUS N100, 16G RAM, 512G SSD + 1TB HDD | demo-felhom.eu | Controller v0.16.0 | +| demo-felhom | Acemagic GK3PLUS N100, 16G RAM, 512G SSD + 1TB HDD | demo-felhom.eu | Controller v0.20.0 | | pi-customer-1 | Raspberry Pi 3B+, 1G RAM, 32G SD | pi-customer-1.local | Not yet tested | ## Related Repositories