Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.2 KiB
felhom.eu — task reports
Overwrite this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in hub/CHANGELOG.md.
REPORT — Hosts page: read-only fleet view (hub v0.27.0)
Date: 2026-07-01 · Repo: felhom.eu (hub/) · Audit finding: F-M1 (resolved)
What & why
The agent enrolls as a host and the hub stores rich host state (identity, agent version, guests, storage targets with SMART, DR/escrow, staleness) and alerts on it — but the entire host domain was invisible in the GUI (email-only). This adds a Hosts nav section: a fleet list + a per-host detail page. Read-only (GET only, no host actions/mutation routes) — this surfaces state the pull/desired-state model demands; it does not reintroduce the inbound control retired in v0.26.0.
Baseline
hub v0.26.0 @ 73b3f6a (clean tree) → v0.27.0. Trunk-based main; commits
2289fc9 (code) + f8b8730 (manifest bump).
Files
Created
hub/internal/web/hosts.go—handleHostsList,handleHostDetail,hostStatus/hostStatusClass/hostStatusLabel,parseHostVitals,parseHostStorageTargets,customerName.hub/internal/web/hosts_test.go— 5 tests (incl. the no-secret assertion).hub/internal/web/templates/hosts.html,hub/internal/web/templates/host_detail.html.
Modified
hub/internal/store/store.go— newListGuestsForHost(hostID) ([]Guest, error)+scanGuesthelper overguestRealitySelectCols(reality columns only; omitsapi_key,desired_spec_json).hub/internal/store/host_test.go—TestListGuestsForHost.hub/internal/web/server.go—GET /hosts(+/hosts/) andGET /hosts/{id}routes (modelled on the/appspair); newtimeAgoPtrtemplate helper for*time.Time.- 7 existing templates (
dashboard,configs,apps,config_form,configuration,customer_unified,app_detail) — added theHostsnav link (nav is duplicated per page, not a shared partial). hub/CHANGELOG.md(newest-on-top),manifests/hub.yaml(:0.26.0→:0.27.0).
Design decisions
- Status badge reuses the alerting threshold.
hostStatus()reusess.staleThresholdand theHostStalenessChecker's bands (stale after the threshold, down at 2×) — one definition, so the GUI badge agrees with the emails.nillast-report → "waiting for first report". - No new ingestion path. Vitals + rich storage (role/state/fill/thin-pool/SMART) are parsed from the
already-stored latest
report_json(GetLatestHostReportJSON); worst-fill fromGetHostStorageTargets. Guest counts fromListGuestsForHost(per-host accurate). - No secrets. The guests reader never selects
api_key/desired_spec_json; DR/escrow are shown as presence booleans only — never the opaque blobs. A test asserts the hostapi_keyis absent from the rendered detail body. - Nil-safe. No report / no guests / no storage / no DR all render empty states, never a panic.
Tests — go build ./... && go vet ./... && go test ./... all ok
TestListGuestsForHost— none→empty; multiple→vmid-ordered; a foreign-host guest excluded; theapi_keycolumn is not surfaced. PASSTestHostStatus— nil→pending, fresh→ok, 45m→stale, 3h→down. PASSTestHandleHostsList— 2 host rows, ONLINE + NO REPORT badges, worst-fill (73%) rendered, no<button>. PASSTestHandleHostDetail— identity/guest/controller-version/storage/SMART(41°C)/role/customer-link present; DR + escrow both "present";api_keyabsent (no-secrets); no<button>. PASSTestHandleHostDetail_Unknown— unknown host → 404. PASSTestHandleHostDetail_NoReport— renders "waiting for first report", no panic. PASS
Deploy (GitOps via ArgoCD — the felhom app; auto-sync off)
Image gitea.dooplex.hu/admin/felhom-hub:0.27.0 built+pushed on the build server (180); manifests/hub.yaml
bumped + committed; ArgoCD felhom hard-refreshed → OutOfSync → synced → Synced / Healthy;
deploy/hub rolled out on image :0.27.0; logs show [INFO] Listening on :8080.
Live validation (claude-in-chrome, operator-authed, hub.felhom.eu)
/hosts— listsdemo-felhom-01ONLINE (agent0.51.0, guests 11/15, CPU 3% / MEM 21% / DISK 29%, worst storage 29%local) + two drill hosts NO REPORT. Hosts nav active; footer0.27.0./hosts/demo-felhom-01— Identity (customer Demo Ügyfél cross-linked to/customers/…, agent0.51.0, enrolled 21d ago, last report 8 min ago, desired generation 2), Vitals, Guests (15 rows, VMID/name/status running=green/stopped=red/last-seen), Storage Targets (felhom-usb SMART PASSED 33°C; local-lvm lvmthin 11% fill / 11% thin-pool; others UNKNOWN/graceful "—"), DR / Backup DR Recipe + Key Escrow both present. Confirmed: no action buttons, and the page text carries noapi_key/secret.
Remaining audit follow-ups (not this slice)
Controller-side geo intent sync; a read-only reported-vs-desired "Show Diff"; the cosmetic controllerURL
cleanup in configs.go.