Commit Graph

111 Commits

Author SHA1 Message Date
rcourtman d393ccf310 Add typed NVIDIA GPU stats 2026-06-30 09:43:33 +01:00
rcourtman fe3c0f3ee3 Collect NVIDIA GPU temperatures 2026-06-30 09:11:18 +01:00
rcourtman 4fc56162f6 Harden hostagent SMART no-device test 2026-06-28 01:01:20 +01:00
rcourtman 28d2413c71 fix(hostagent): clear stale Unraid sync action when resync position is zero
Unraid's mdResyncAction field can retain its last value (e.g. "check")
after a parity check is canceled, causing Pulse to report a stale sync
action indefinitely. The mdResync/mdResyncPos field is the authoritative
indicator: it drops to 0 when no resync is running. Gate SyncAction on
a non-zero position so the alert clears once the sync actually stops.

Refs #1485
2026-06-27 17:08:02 +01:00
rcourtman 6a162a1736 Add macOS thermal state reporting
Report Darwin pmset pressure separately from Celsius readings and carry it through host sensor state and resource details.
2026-06-14 11:07:47 +01:00
rcourtman 7e26592f11 Fix CI SMART and grant refresh tests
Refs Build and Test failures on pulse/v6-release.
2026-06-11 16:26:21 +01:00
rcourtman c511c935b3 fix(disks): ground SMART disk discovery in /sys/block so no physical disk vanishes
On the #1483 reporter's Proxmox node a SATA SSD (INTEL SSDSC2BW240A4) never
appeared in Pulse even though smartctl reads it fine, because the agent's
discovery and probing both had single points of failure:

- Discovery trusted smartctl --scan-open exclusively whenever it returned at
  least one target. The scan silently omits any device it fails to open at
  scan time (the failure is only a #-comment in its output), so one bad open
  hid a real disk while its neighbours were listed.
- A scan-provided -d type got exactly one probe attempt on Linux. A type whose
  full query (-i -A -H) fails or returns nothing dropped the disk silently.
- A probe yielding no usable SMART data dropped the disk entirely instead of
  reporting the identity the kernel can prove.

Fixes, all in the agent collector:

- Union discovery: the kernel block device list (/sys/block, lsblk fallback)
  is the ground truth for which disks exist; smartctl --scan-open only
  contributes device-type hints. Any physical disk the scan misses gets an
  untyped probe target.
- Untyped retry: a typed Linux probe that errors, yields no usable data, or
  fails to open (exit bit 2, distinct from -n standby,3's exit 3) retries with
  smartctl auto-detection before giving up. Multiplexed controller members
  (megaraid, cciss, ...) are exempt since dropping -d would probe the array.
- Identity-only fallback: when every probe fails but the disk exists in
  /sys/block with nonzero capacity, report device/model/serial/size with
  health UNKNOWN instead of hiding it. No SMART data is fabricated;
  multiplexed array paths and zero-capacity media are excluded.
- Exclusion follow-through: --disk-exclude now also matches the canonical
  post-refine name (nvme0n1), not just the scan label (nvme0).

Regression tests use smartctl/lsblk fixtures captured from PVE 9.1.9 hosts
and the issue report. Verified live on two PVE nodes: NVMe keyed by
namespace with byte-exact pvesh sizes, SATA disk reported with full identity.

Completes the #1483 fix started in bd20069c6 (namespace devpath, authoritative
sizes, merge downgrade guard). Closes #1483.
2026-06-10 15:14:34 +01:00
rcourtman bd6f77e093 Prepare v6.0.0 release candidate
Tighten v5-to-v6 upgrade safety, release installability, provider MSP mode handling, AI cost accounting, metrics flushing, and frontend guardrails for the v6.0.0 GA candidate.
2026-06-04 14:07:14 +01:00
rcourtman 9fe769ecdb Parse OPNsense 'Current Drive Temperature' SMART output
Back-port the smartctl regex half of v5 fix 0c2de2938 to v6 (the
prerelease-aware CompareVersions half is already present). smartctl text
fallback now matches 'Current Drive Temperature:' in addition to
'Current Temperature:', so OPNsense/pfSense disk temperatures are read
instead of reported as missing. Adds a regression test.
2026-06-04 09:50:37 +01:00
rcourtman b97fe12911 Stabilize hostagent backend release tests
Isolate hostagent coverage tests from failed websocket upgrades and runner-local device state.

Refs release run 26910672866.
2026-06-03 21:41:09 +01:00
rcourtman bd20069c60 fix(disks): report authoritative disk size and namespace devpath from the host agent
On a Proxmox node, physical disks collected by the host agent were keyed by
the NVMe controller (e.g. "nvme0 [nvme]") instead of the namespace, reported
sizeBytes 0 (or a stale filesystem-usage value), and flickered as the agent
reading intermittently replaced the authoritative Proxmox disks/list reading.

Root causes:
- smartctl --scan-open reports NVMe disks by their controller char device
  (/dev/nvme0), and that scan label became the reported devPath.
- DiskSMART carried no capacity, so the server backfilled size by matching the
  SMART device against host filesystem-usage entries, which never match a whole
  partitioned/LVM/ZFS disk, leaving size 0.
- The unified-resource merge let the agent's controller label overwrite the
  canonical Proxmox /dev/... devPath.

Fixes:
- The agent now reports the canonical block device (an NVMe controller resolves
  to its namespace) and the authoritative capacity from /sys/block, with the
  smartctl user_capacity / nvme_total_capacity as a cross-platform fallback.
  Disks behind multiplexing controllers (megaraid, cciss, areca) keep their
  disambiguating label and smartctl-reported size.
- SizeBytes flows through the agent report, host model, and adapter; the
  filesystem-usage match is demoted to a legacy fallback.
- The merge keeps a canonical /dev/<device> devPath and never downgrades it to
  a scan label, so an un-updated agent can no longer corrupt Proxmox data.

Refs #1483.
2026-05-29 19:55:53 +01:00
rcourtman 06fd4fc89e Bypass approval gate for trusted internal Discovery commands
Discovery wraps every probe in `docker exec <container> sh -c '...'`.
The agentexec command policy lists `^docker\s+exec\s` as RequireApproval
(a sound default for user-driven docker exec) and Discovery has no path
to mint or supply an ApprovalID. Result: every probe was rejected, the
scanner returned empty CommandOutputs, and the AI fell back to
"Unknown Infrastructure Resource" at confidence 0. The Discovery sub-tab
rendered empty after a "successful" run.

Add a Trusted bool to ExecuteCommandPayload on both the server-facing
agentexec type and the agent's wire struct. When set, the approval gate
is skipped on both ends and the server does not attempt to auto-mint an
approval grant (which would fail with "approval id is required").
PolicyBlock still applies; this is not a way to run arbitrary commands.

Only the discoveryCommandAdapter sets Trusted=true. The flag is never
populated from a deserialised HTTP body or any user-driven path. Patrol
fixes, Assistant remediation, and AI tool calls continue to flow through
the governed approval-record path with a real ApprovalID.

Contracts: amend agent-lifecycle Completion Obligations and Current
State to document the lone exception to the on-agent approval rail, and
amend ai-runtime to fence the Trusted flag to the discovery adapter
only.
2026-05-17 21:59:39 +01:00
rcourtman 3580a5ed6d Clarify storage topology and recovery guards 2026-05-14 20:51:32 +01:00
rcourtman aab3711765 Fix PVE version detection on agent hosts 2026-05-08 15:30:08 +01:00
rcourtman 31d07e74ce Fix Unraid storage health explanations 2026-05-08 12:18:09 +01:00
rcourtman 8df57ba50d Detect Proxmox VE host agent OS identity 2026-05-08 11:19:56 +01:00
rcourtman ac82a28521 Fix Unraid agent host profile detection 2026-05-08 11:05:14 +01:00
rcourtman 4736358acc Drive agent host profiles from platform manifest 2026-05-07 23:42:15 +01:00
rcourtman 7da942226a Clarify Pulse Agent host profile support
Separate first-class platform support from Pulse Agent host profiles and classify Unraid as an agent-backed host profile while preserving it as presentation-only platform vocabulary.
2026-05-07 22:28:24 +01:00
rcourtman ce7b459aa7 Harden runtime Proxmox token ACLs 2026-05-05 14:42:05 +01:00
rcourtman 641660dced Fix mdadm RAID fallback discovery
Refs #1455
2026-05-05 09:29:34 +01:00
rcourtman a3617b923a Fix remaining RC3 backend CI races 2026-05-01 22:03:22 +01:00
rcourtman af7d727d45 Gate RAID rebuild alerts on mdstat operation
Parse the /proc/mdstat operation keyword for mdadm arrays and propagate it through host reports, models, unified resources, monitoring views, alert metadata, and AI storage summaries.

Treat recovery and reshape as rebuild signals while silencing routine check and resync maintenance, with fallback rebuild detection only when no mdstat operation is available.

Tests cover mdstat operation parsing plus recovery, check, and resync alert behavior.

Fixes #1446
2026-04-30 14:31:14 +01:00
rcourtman c51708000f Tighten unified agent hardening proof 2026-04-23 23:37:25 +01:00
rcourtman 9bada35337 Harden unified agent runtime and installer 2026-04-23 23:04:18 +01:00
rcourtman 386099aeee Surface ZFS pool membership on physical disks 2026-04-23 20:38:33 +01:00
rcourtman 60d7db6ef9 Harden agentexec token binding and disk filtering 2026-04-23 15:54:48 +01:00
rcourtman eb98c13896 Allow insecure dev HTTP agent runtime URLs 2026-04-23 13:48:54 +01:00
rcourtman b33e21e0e8 Add least-privilege SSH deploy mode 2026-04-22 15:23:02 +01:00
rcourtman ccb2edc3b8 Require explicit websocket origin continuity 2026-04-22 04:46:13 +01:00
rcourtman d64f5b2917 Canonicalize loopback-only Pulse transport validation 2026-04-22 04:11:18 +01:00
rcourtman 7b1520b760 Add fingerprint-pinned TLS mode for unified agent 2026-04-22 01:36:46 +01:00
rcourtman c49176d700 Require TLS for non-loopback agent transport 2026-04-21 23:56:07 +01:00
rcourtman 3ec2c0779e Harden agent command and deploy trust boundaries 2026-04-21 23:50:34 +01:00
rcourtman c4a4d175ce Fix v6 dry run backend contract regressions 2026-04-20 14:57:49 +01:00
rcourtman 40a25f82d1 Add periodic Proxmox registration health check loop
The cold-startup race: if Pulse and the agent restart together, the
monitor has no connection-health data when the agent calls
checkRegistrationWithPulse at startup. The server defaults to
registered=true (no known-disconnected entry), so the agent skips
re-registration even though the token is stale. The node stays broken
until the next manual agent restart.

Fix: after the initial runProxmoxSetup call, start a background goroutine
that waits 2 minutes (giving the monitor time to poll PVE and record
failure state), then rechecks every 5 minutes via RunHealthCheck.

RunHealthCheck only acts on types that have a local registration marker.
Types without a marker are skipped to prevent uncontrolled token rotation
when Pulse is temporarily unreachable — those need a full startup setup
cycle via RunAll.

Together with the two earlier commits this closes all three stale-token
scenarios: install-time 401, long-running stale state, and cold-startup
race.
2026-04-18 22:25:18 +01:00
rcourtman 501c61b82f Fix PVE stale token self-healing after failed registration
Two gaps in the existing flow allowed a disconnected PVE node to stay
broken indefinitely even after the agent restarted:

1. Server-side: autoRegisteredNodeExists checked only that a PVE/PBS
   instance existed in the config, not whether its connection was
   healthy. A node with a stale token would return registered=true on
   every check, causing the agent to skip re-registration forever.
   Fixed: also consult GetConnectionStatuses(); return registered=false
   when the monitor has a definitive disconnected entry so the agent can
   rotate and re-register.

2. Agent-side: the type-specific registration marker was cleared only on
   success. If rotation succeeded but the Pulse update failed (e.g.
   transient network error), the old marker from a previous successful
   registration persisted, leaving next-startup to skip setup again.
   Fixed: clear the marker before entering the token setup/rotation
   phase so any failure leaves the system in a retriable state.

Together these two fixes make the stale-token scenario self-healing:
the monitor detects the broken connection, the next agent startup sees
registered=false, clears its marker, rotates the token, and updates
Pulse — without manual intervention.
2026-04-18 22:07:30 +01:00
rcourtman b0b790cf55 Fix PVE token re-registration after agent reinstall
When the agent is reinstalled on a Proxmox host, it rotates the PVE API
token in Proxmox but the Pulse server's /api/setup-script-url endpoint
requires settings:write scope — agent tokens only have agent:report — so
the 401 aborted the update, leaving Pulse with a stale token and a
disconnected PVE node.

Three-part fix:
- server: accept agent API tokens on /api/auto-register for updating
  existing nodes (new nodes still require setup-token auth)
- agent: fall through instead of aborting when setup token fetch returns
  4xx; send X-API-Token header so the server can authenticate via the
  agent token instead
- update: allow HTTP auto-update URLs for RFC 1918 private network
  addresses (LAN installs without HTTPS no longer block auto-update)
2026-04-18 21:44:42 +01:00
rcourtman d03056f656 Port v5 NAS vendor identity and RAID normalization 2026-04-15 12:54:15 +01:00
rcourtman 05fa111ca1 Stabilize backend race tests for v6 RC publish 2026-04-11 22:46:34 +01:00
rcourtman 7028c95ed0 Hermeticize Linux SMART discovery tests 2026-04-09 21:28:37 +01:00
rcourtman 8de5c60b46 Self-heal stale Proxmox auto-register markers 2026-04-01 19:56:20 +01:00
rcourtman 24fc9a019b Forward-port SMART collector hardening 2026-04-01 15:15:59 +01:00
rcourtman bf7ca9fa0b Select reachable Proxmox auto-register hosts 2026-04-01 13:49:40 +01:00
rcourtman 82ce98f7ca Prefer hostname endpoints for Proxmox auto-register 2026-04-01 12:49:17 +01:00
rcourtman 2afb96ee13 fix(release): align api and hostagent rc contracts 2026-03-26 17:08:48 +00:00
rcourtman 778a2577b6 feat: Pulse v6 release 2026-03-18 16:06:30 +00:00
rcourtman 572520ebc6 Promote guest-agent /proc/meminfo fallback for accurate VM memory (#1270)
Move the guest-agent file-read of /proc/meminfo earlier in the memory
fallback chain so it runs before RRD, giving real-time MemAvailable that
correctly excludes reclaimable buff/cache on Linux VMs. Also add
VM.GuestAgent.FileRead permission for PVE 9 and fix install.sh to use
comma-separated privilege strings.
2026-03-09 10:04:28 +00:00
rcourtman fe0706f614 Fix cluster double-registration invalidating Proxmox credentials (#1319)
Two nodes in the same PVE cluster generated identical Proxmox API token
names, so the second node's setup rotated the shared token and broke the
first node. Include the hostname in the token name so each node gets its
own token. Also refresh the stored cluster credential on the server when
a new endpoint merges into an existing cluster entry.
2026-03-07 22:36:01 +00:00
rcourtman 499ab812e3 Fix post-release regressions and lock v5 to single-tenant runtime 2026-03-05 23:46:35 +00:00