Files
felhom-agent/REPORT.md
T
admin aa4dfb75ea slice 9: GET /host/metrics + CPU/chassis-temp collector (v0.14.0)
Add a host-wide, token-authed GET /host/metrics local-API endpoint that
re-serves the slice-4 collector's host + per-storage view to the customer
(the de-privileged controller can't read the host itself). Add the one new
collector — CPU/chassis temperature via sysfs hwmon/thermal-zones, graceful-
null — to the shared HostMetrics struct, so the hub report carries cpu_temp_c
too. Cross-repo host-report golden updated byte-identical.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 16:16:03 +02:00

54 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# REPORT — slice 9 (agent half): host metrics to the controller (v0.14.0) (2026-06-10)
> Overwrite-latest report. Cumulative history: [CHANGELOG.md](CHANGELOG.md).
## What was implemented
The agent half of **slice 9** — re-serving the host's health to the customer's controller, plus the
one new collector (CPU/chassis temperature). The de-privileged controller (slice 8C) sees only its
own cgroup, so it cannot read host metrics itself; the agent already collects host CPU/mem/loadavg/
uptime + per-storage targets for the hub, and slice 9 exposes that to the customer over the local API.
### `internal/hub/cputemp.go` — CPU/chassis-temp collector (new)
- `TempReader` seam + `SysfsTempReader`: reads the CPU package temperature from **sysfs** — hwmon
(`coretemp`/`k10temp`/`zenpower`/`cpu_thermal`, preferring the `Package id 0` input) then thermal
zones (preferring `x86_pkg_temp`/`coretemp`/`cpu-thermal`, falling back to `acpitz`).
- **No external binary, no privilege** (sysfs is world-readable) → the root-CLI fence is untouched.
- **Graceful-null**: a missing sensor, an unsupported board, an implausible reading (outside
5150 °C), or any read error all degrade to `nil` ("n/a") — never fails the report. Same nullable
contract as the per-disk `SmartSummary.TemperatureC`.
### `internal/hub` — shared wire field + collector reuse
- `HostMetrics` gains **`CPUTempC *int` (`cpu_temp_c`)** — nullable, on the **shared** struct, so the
**hub report carries it too** (operator freebie). Cross-repo host-report golden updated
**byte-identical** with the hub's copy.
- `Collector` gains a nil-safe `temp TempReader` (defaults to the real `SysfsTempReader`;
`SetTempReader` injects a fake in tests). `Collect()` now sets `cpu_temp_c` on the report.
- **`Collector.HostMetricsNow(ctx)`** — a fresh `NodeStatus` + CPU-temp read returning just the host
block; the source for the local API (current cpu%/temp, not the 15-min hub snapshot).
### `internal/localapi` — `GET /host/metrics` (new endpoint)
- `host_metrics.go`: host-wide health (cpu%/mem/load/uptime/`cpu_temp_c`) + per-storage capacity
(total/used/fraction, thin-pool, SMART temp+wear). Token-authed via `withGuest` (host-wide data; a
cross-guest `?vmid=` still 403). Best-effort on storage (a view error still returns the host
block). Served only when the `HostMetrics` provider (the shared collector) is wired in
`buildLocalAPIServer` — else 503 "not configured".
## Tests (all green)
- `cputemp_test.go`, `hostmetrics_test.go`, `host_metrics_test.go`: hwmon/thermal-zone selection +
**graceful-null**, `HostMetricsNow` populate/null/hard-error, endpoint populated + `cpu_temp_c:null`
serialization + **401 without a token** + 403 cross-guest + 503 not-configured.
- `go test ./...` green; `go vet ./internal/hub ./internal/localapi` clean.
## Versioning / docs
- Version `0.13.0 → 0.14.0`; `CHANGELOG.md` updated. Doc 03 §6 (local-API surface) + §9 (roadmap +
changelog) updated.
## Assumption (noted, not built)
- **One customer per host** (home-server model): `/host/metrics` is host-wide. A multi-customer host
would leak cross-customer CPU/mem → revisit then.
## Pending
- **Live validation** on the demo (build + deploy agent v0.14.0; controller monitoring page → real
N100 CPU%/temp + per-storage, cross-checked vs `pvesh`/`free`/`df`).