Tap each node's Beszel metrics (GPU/temps/disk-IO/network/per-container — beyond
our basic heartbeat) by reading the workspace's Beszel hub. The agents run in
WS-only mode with no locally-readable socket, so (per the de-risk) the server taps
the hub's PocketBase API instead of the daemon reading agents — no daemon changes.
- migrations: workspace_beszel (BYO hub URL + login, server-side only, mirrors the
Tailscale BYO pattern) + node_metrics (latest scalar columns + JSONB blob).
- cm-db: repo/fleet_beszel.rs, repo/node_metrics.rs; nodes SELECT joins node_metrics
(gpu_pct/temp_max surfaced on node_json for the live cards).
- cm-api: beszel.rs client (auth-with-password, poll `systems`, map to nodes by
hostname, upsert metrics) + a 15s spawn_poller; routes/beszel.rs (connect/status/
disconnect + GET /api/nodes/{id}/metrics with history proxied live from the hub).
- frontend: HostCard gains a GPU/temp readout + a Monitor button; NodeMonitor is a
full-width per-node page (current panel + CPU/mem/GPU/temp/net/disk charts from the
hub's 1m history); a "Beszel monitoring" connect form in the Local view.
Reachability confirmed: gw-04 → the hub over the tailnet (100.123.224.84:8090). Needs
the user to connect their hub login to activate the poller.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
12 lines
600 B
SQL
12 lines
600 B
SQL
-- Bring-your-own Beszel hub: a workspace connects its Beszel monitoring hub so we
|
|
-- read rich per-node metrics (GPU / temps / disk-IO / network / per-container) via
|
|
-- its PocketBase API. Credentials are used server-side only (never returned to the
|
|
-- client). TODO: move credentials into the cm-secrets broker store (like Tailscale).
|
|
CREATE TABLE workspace_beszel (
|
|
workspace_id UUID PRIMARY KEY REFERENCES workspaces (id) ON DELETE CASCADE,
|
|
hub_url TEXT NOT NULL,
|
|
username TEXT NOT NULL,
|
|
password TEXT NOT NULL,
|
|
connected_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|