package web import ( "net/http" ) // Agent-backed host metrics (slice 9). // // The de-privileged controller (slice 8C) sees only its own cgroup, so it cannot read host // health itself. This thin proxy forwards GET /api/host-metrics to the agent's GET /host/metrics // and returns the host-wide view (cpu%/mem/load/uptime/cpu-temp + per-storage capacity) for the // monitoring page. It reuses the same pinned agentapi.Client + {ok,data,error} envelope as the // disk proxy (agent_disk_handlers.go). Read-only; no CSRF mutation. // ServeHostMetricsAPI proxies GET /api/host-metrics → agent GET /host/metrics. // Wired in main.go behind RequireAuth. func (s *Server) ServeHostMetricsAPI(w http.ResponseWriter, r *http.Request) { if s.isDebug() { s.logger.Printf("[DEBUG] [web] ServeHostMetricsAPI: %s %s from %s", r.Method, r.URL.Path, r.RemoteAddr) } if r.Method != http.MethodGet { writeDiskJSON(w, http.StatusMethodNotAllowed, false, "method not allowed", nil) return } client, err := s.agentClient() if err != nil { // Unprovisioned guest / no local API configured — the UI shows "host metrics unavailable". writeDiskJSON(w, http.StatusServiceUnavailable, false, err.Error(), nil) return } resp, err := client.HostMetrics(r.Context()) if err != nil { s.logger.Printf("[ERROR] [web] host metrics via agent failed: %v", err) writeDiskJSON(w, http.StatusBadGateway, false, err.Error(), nil) return } writeDiskJSON(w, http.StatusOK, true, "", resp) }