3173 Commits

Author SHA1 Message Date
rcourtman 83d3e3e95e Bump version to 5.1.23 v5.1.23 2026-03-09 21:49:21 +00:00
rcourtman 7a394ed724 Use explicit success flag for disk carry-forward guard (#1319)
Replace the diskUsage <= 0 heuristic with a diskFromAgent bool that is
only set when the guest agent actually returns valid filesystem data.
Prevents carry-forward from firing on a genuine 0% disk reading.
2026-03-09 18:54:27 +00:00
rcourtman 9c279732f7 Skip disk carry-forward when guest agent is explicitly disabled (#1319)
Prevents stale disk data from persisting indefinitely in the efficient
poller when a user disables the guest agent after it had been providing
data.  Matches the fallback poller's agent-disabled exclusion.
2026-03-09 18:37:38 +00:00
rcourtman abbd0df609 Fix disk metric spikes when guest agent intermittently fails (#1319)
Carry forward previous cycle's disk data when the QEMU guest agent
times out or errors, instead of falling back to Proxmox cluster/resources
which always reports 0 for VM disk usage.  Applied to both polling paths
(pollVMsAndContainersEfficient and pollVMsWithNodes) with safety guards
against uint64 underflow and permanent-failure exclusions.
2026-03-09 18:23:15 +00:00
rcourtman a4b0771974 Prevent removed host agents from resurrecting via in-flight reports (#1331)
Host agents removed from the UI would reappear on the next report cycle
because there was no rejection mechanism — unlike Docker agents which
already had resurrection prevention. Mirror the Docker agent pattern:

- Track removed host IDs in a `removedHosts` map with 24hr TTL
- Persist removal records in `State.RemovedHosts` for frontend display
- Reject reports from removed hosts in `ApplyHostReport()`
- Add `AllowHostReenroll()` + API route to clear the block
- Show removed host agents in the Settings UI with "Allow re-enroll"
- Sync removed-agent maps from state on startup for all agent types
- Fix mock integration snapshot missing `RemovedDockerHosts` field
2026-03-09 17:52:34 +00:00
rcourtman 9b531c547d Fix recovery notifications silently disabled by config PUT (#1332)
Two fixes for missing recovery/resolved notifications:

1. API config PUT handler now preserves notifyOnResolve when the client
   omits it from the request body. Go decodes a missing bool as false,
   which silently disabled recovery notifications on older clients.

2. CancelAlert now always cleans up the cooldown record even when the
   alert has already left the pending buffer, preventing stale cooldown
   entries from suppressing future alert cycles.
2026-03-09 11:28:28 +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 aa139b73fb Fix intermittent VM disappearance from dashboard (#555)
Two root causes: (1) When Proxmox cluster/resources returns a partial
response (e.g. during migration or transient API issue), VMs missing
from a responsive node were silently dropped because the node appeared
in nodesWithResources, bypassing grace-period preservation. Now
preserves recently-seen guests from online nodes for up to the grace
window. (2) The task queue allowed overlapping polls for the same PVE
instance — a slower stale poll could overwrite a newer complete VM list.
Added per-instance execution lock to skip duplicate scheduled tasks.
2026-03-08 22:16:24 +00:00
rcourtman d560de15ad Increase alerts test cleanup sleep to fix flaky test under load
The 10ms goroutine drain pause was insufficient under full parallel
test suite load, causing intermittent failures in
TestPulseMonitorOnlySkipsDispatchButRetainsAlert.
2026-03-08 22:16:24 +00:00
rcourtman 98c9de7c91 Fix FreeBSD SMART disk detection for ada/da/nvd devices (#1254)
FreeBSD disk discovery now falls back to scanning /dev for ada*, da*,
nvd*, nda* and other FreeBSD disk names when kern.disks misses them.
Probe order prefers the correct device type first (sat for ada, nvme
for nvd). Standby disks are preserved as valid results instead of
being dropped.
2026-03-08 22:16:24 +00:00
rcourtman 82c615b3b9 Filter virtual disks from SMART checks to prevent false positives (#1329)
ZFS zvols (zd*), device-mapper, virtio disks, and other virtual block
devices don't support SMART and were being reported as FAILED. Use lsblk
JSON metadata to filter by device prefix, transport, subsystem, and
vendor/model. Also treat missing smart_status as unknown rather than
failed, and ignore UNKNOWN health in Patrol/AI signals.
2026-03-08 22:16:24 +00:00
rcourtman f66aa66e74 Auto-update Helm chart version to 5.1.22 helm-chart-5.1.22 2026-03-08 12:27:01 +00:00
rcourtman 015a33ba13 Auto-update Helm chart documentation 2026-03-08 12:27:00 +00:00
rcourtman 43864ffb95 Bump version to 5.1.22 v5.1.22 2026-03-08 11:51:17 +00:00
rcourtman 45b5c8a861 Restore previous license on persistence failure instead of clearing it
If license save fails, the in-memory license was being cleared, which
could drop a valid existing license. Now snapshots the current license
before activation and restores it if persistence fails.
2026-03-08 11:49:26 +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 ff1bbe2fb8 Guard per-VM guest agent calls with timeout and panic recovery (#1319)
A broken or hung qemu-agent on one VM could stall the entire polling
loop, preventing higher-VMID VMs from being detected. Wrap all guest
agent work in a 10s per-VM budget with panic recovery, and add a 2s
timeout to GetVMStatus in the efficient poller to match the legacy path.
2026-03-07 22:30:18 +00:00
rcourtman 0dd3fc779b Fix alert disable notification suppression 2026-03-07 18:40:08 +00:00
rcourtman d6e8bffaeb pulse/license upgrade safety hardening 2026-03-07 15:13:09 +00:00
rcourtman a6f6f66078 Improve auto-register auth errors and setup token grace window (#1319)
The /api/auto-register endpoint returned a generic "Invalid or expired
setup code" for all auth failures, making cluster registration issues
impossible to diagnose. Now returns specific errors for expired tokens,
wrong scope, invalid API tokens, etc.

Also extend the setup token grace window to /api/auto-register so
multiple cluster nodes can register with the same token within the
1-minute grace period after first use.
2026-03-07 13:39:26 +00:00
rcourtman c0b3a0e665 Restart Pulse service after failed auto-update (#1323)
The auto-update flow stops the Pulse service before applying updates.
If the update fails, the rollback path restored files but never
restarted the service. Since the main unit was explicitly stopped
(not crashed), systemd's Restart=always didn't rescue it.

Add restart-on-failure guards to both pulse-auto-update.sh and
install.sh so Pulse is always restarted after a failed update attempt.
2026-03-07 10:46:19 +00:00
rcourtman 64f3bfa922 Bump dompurify to 3.3.2 to fix XSS vulnerability (Dependabot #64)
DOMPurify 3.1.3–3.3.1 has an XSS vulnerability via missing rawtext
element sanitization. Bump to 3.3.2 which includes the fix.
2026-03-07 10:46:12 +00:00
rcourtman ddecf6d00c Guard legacyMonitor typed-nil and add OIDC refresh panic recovery
Normalize SystemSettingsMonitor interface assignments via reflect to
prevent typed-nil-in-interface (same class as #1324 fix). Also add
defer/recover to the background OIDC token refresh goroutine so a
panic there cannot take down the process.
2026-03-07 10:21:07 +00:00
rcourtman 23a9fa70da Fix nil pointer crash when saving settings (#1324)
SystemSettingsHandler.mtMonitor was an interface field. A nil
*MultiTenantMonitor stored in it became a non-nil interface
(Go typed-nil-in-interface), bypassing the nil guard in getMonitor()
and panicking on every settings save in single-tenant mode.

Change mtMonitor to concrete *monitoring.MultiTenantMonitor so nil
checks work correctly. Also resolve getMonitor() once per request
instead of repeated calls to eliminate a TOCTOU race.
2026-03-07 10:21:07 +00:00
rcourtman 4ea2f49771 Auto-update Helm chart version to 5.1.21 helm-chart-5.1.21 2026-03-06 12:15:39 +00:00
rcourtman c26a96ef51 Auto-update Helm chart documentation 2026-03-06 12:15:38 +00:00
rcourtman 01bf637d0d Fix QNAP agent duplicate processes during upgrades (#1317)
Add singleton watchdog with lock dir, pidfile tracking, and signal
traps to prevent multiple pulse-agent instances spawning on QNAP.
Tighten procfs matching to avoid killing unrelated processes.
v5.1.21
2026-03-06 11:40:53 +00:00
rcourtman 9244498b75 Bump version to 5.1.21 2026-03-06 11:05:01 +00:00
rcourtman 89577fe533 Fix OIDC token refresh bypass and guard AISettingsHandler nil path
The applyAuthContextHeaders early-return in CheckAuth skipped the OIDC
token refresh block, causing long-lived OIDC sessions to expire instead
of auto-refreshing. Move the refresh trigger into extractAndStoreAuthContext
so it fires at the middleware level before CheckAuth's early return.

Also add a nil guard on mtPersistence in AISettingsHandler.GetAIService
for non-default org paths, preventing a potential panic if background
code carries a non-default org context in v5 single-tenant mode.
2026-03-06 11:05:01 +00:00
rcourtman 743ef17b79 Fix AI and config profile handlers broken in v5 single-tenant mode
The single-tenant lockdown (499ab812e) set mtPersistence to nil but
only patched AISettingsHandler with a legacy fallback. AIHandler (chat
service) and ConfigProfileHandler were missed, so AI features (Patrol,
Chat) failed with "chat service not available" and config profiles
would panic on nil dereference. Wire legacy persistence into both
handlers and add the same fallback to ProfileSuggestionHandler.

Fixes #1322
2026-03-06 11:05:01 +00:00
rcourtman 73bf2c1c7b Auto-update Helm chart version to 5.1.20 helm-chart-5.1.20 2026-03-06 00:33:13 +00:00
rcourtman 4c5fbb0c04 Auto-update Helm chart documentation 2026-03-06 00:33:12 +00:00
rcourtman 6618db7799 Fix v5 single-tenant router test setup v5.1.20 2026-03-05 23:58:11 +00:00
rcourtman ed8283b223 Bump version to 5.1.20 2026-03-05 23:46:35 +00:00
rcourtman 499ab812e3 Fix post-release regressions and lock v5 to single-tenant runtime 2026-03-05 23:46:35 +00:00
rcourtman 464d3f8486 Fix stale queued notification delivery 2026-03-05 23:46:35 +00:00
rcourtman 74ce77132b Auto-update Helm chart version to 5.1.19 helm-chart-5.1.19 2026-03-05 11:21:24 +00:00
rcourtman 74c55c79bb Auto-update Helm chart documentation 2026-03-05 11:21:23 +00:00
rcourtman ba8490c252 fix(ui): use SolidJS class prop instead of deprecated className 2026-03-05 10:17:51 +00:00
rcourtman 7cfcaab250 chore: bump version to 5.1.19 v5.1.19 2026-03-05 10:01:43 +00:00
rcourtman 0493fb78bf fix(agent): detect rootless Docker/Podman sockets for other users (#1200)
When the agent runs as root, os.Getuid() returns 0 so it only probes
/run/user/0/docker.sock. Rootless Docker installs live at
/run/user/1000/docker.sock (or similar). Glob /run/user/*/docker.sock
and /run/user/*/podman/podman.sock to discover sockets for all users.
2026-03-05 10:01:43 +00:00
rcourtman 10872c8ca8 fix(patrol): remove noisy per-alert log when patrol is disabled (#1258)
The alert callback logged at Info level for every alert regardless of
whether patrol was enabled. TriggerPatrolForAlert already has an
enabled/running guard and its own debug logging.
2026-03-05 10:01:43 +00:00
rcourtman 1491e0ee6e fix(alerts): add stable sort tiebreaker to prevent hostname scrambling (#1218)
When multiple alerts fire in the same polling cycle they share identical
startTime values. Without a tiebreaker, JS sort returns them in arbitrary
order on each reactive recomputation, causing hostnames to visually
shuffle. Use alert.id as a deterministic lexicographic tiebreaker in both
the Overview and History tab sort comparators.
2026-03-05 10:01:43 +00:00
rcourtman 3a263bc4f0 fix(ai): pass correct identifiers to Docker container discovery (#1315)
Use host.agentId and container.name for DiscoveryTab props to match
backend storage keys. Previously host.id (derived ID) and container.id
(Docker hash) were used, causing discovery lookups to always miss.
2026-03-05 10:01:43 +00:00
rcourtman 72be883f4e fix(proxmox): prevent broken TLS config on auto-register fingerprint failure (#1303)
When FetchFingerprint fails during agent auto-registration, set verifySSL
based on whether a fingerprint was captured rather than hardcoding true.
Also heal already-broken nodes (verifySSL=true with empty fingerprint) on
legacy re-register to prevent permanent connection failures with self-signed
Proxmox certs.
2026-03-05 10:01:43 +00:00
rcourtman cdceccef05 fix(agent): kill old QNAP agent processes during upgrade (#1317)
Add stop_qnap_agents() helper that kills wrapper scripts before binaries
to prevent watchdog respawn, and uses path-based pkill patterns that work
with BusyBox and match agents at both old and new install paths.
2026-03-05 10:01:43 +00:00
rcourtman d4d67315de Auto-update Helm chart version to 5.1.18 helm-chart-5.1.18 2026-03-03 22:11:55 +00:00
rcourtman a3fcaafbdb test(notifications): remove queue stats race with background processor v5.1.18 2026-03-03 21:37:27 +00:00
rcourtman 1c9d53cf20 chore: bump version to 5.1.18 2026-03-03 20:56:04 +00:00
rcourtman ac83074fc2 fix(hostmetrics): skip network mounts before usage probe (#1313) 2026-03-03 20:27:41 +00:00