Commit graph

4826 commits

Author SHA1 Message Date
rcourtman
3fd20340d1 fix: increase PBS storage content timeout to 60s
PBS storage content queries with encrypted backups can take 10-20+ seconds
to enumerate. The previous 30s timeout was causing intermittent failures
when polling backup data from PBS storage configured in PVE.

This increases the timeout to 60s to accommodate slow PBS backends while
still preventing indefinite hangs on unavailable NFS/network storage.
2025-12-26 00:21:17 +00:00
rcourtman
11c79173b4 fix: Resolve TypeScript build errors
- Remove unused imports (formatPercent, MetricText) from multiple components
- Remove unused variables (memPercent, memUsageLabel)
- Fix ResourceTable.tsx type error by adding proper tuple typing
- Add handleRemoveKubernetesCluster function for proper type safety
- Fix Kubernetes cluster remove button to use correct handler
2025-12-26 00:06:49 +00:00
rcourtman
cba4418be3 fix: Remove Alpine from LXC template options
Alpine uses apk/OpenRC instead of apt/systemd, which the Pulse
LXC installation flow requires. This prevents failed installations.

- Remove Alpine download option from advanced mode
- Add note that Pulse requires Debian-based templates
- Add validation when user selects from template list to catch
  Alpine/Gentoo/Arch/Void and fall back to Debian 12 with warning

Related to #915
2025-12-25 23:58:24 +00:00
rcourtman
86e41effc0 feat: Display environment variables for Docker containers
- Add Env field to Container struct in pkg/agents/docker/report.go
- Extract env vars from inspect.Config.Env in Docker agent
- Mask sensitive values (password, secret, key, token, etc.) with ***
- Display env vars in container drawer with green badges (amber for masked)
- Add tests for maskSensitiveEnvVars function

Related to #916
2025-12-25 23:52:57 +00:00
rcourtman
4f4fdcf81b feat(mobile): improve table layouts for remaining pages
- Add horizontal scrolling to Hosts table with 900px min-width
- Add horizontal scrolling to Ceph tables with 700/650px min-widths
- Tighten padding on Storage tables for compact mobile display
- Add min-width to DiskList table for physical disks
- Add min-width to Settings tables (PVE, PBS, PMG, Agents)
- Add horizontal scroll container to Alerts patrol run table
- Hide scrollbars across all scrollable tables for cleaner UI
2025-12-25 23:07:49 +00:00
rcourtman
be0d777158 feat(mobile): optimize tables for mobile devices
- Implement horizontal scrolling for key tables (Dashboard, Storage, Backups, Docker, Node Summary).
- Ensure consistent column widths (140px fixed on desktop, 60px min on mobile) for metric columns (CPU, Memory, Disk).
- Switch Backups view from card to scrollable table for consistency.
- Reduce shell padding on mobile.
- Update ResourceTable (Alerts) with dedicated mobile view.
- Refine column visibility logic.
2025-12-25 22:32:56 +00:00
rcourtman
02000280a9 feat: improve Pro feature UI gating and error handling
- AISettings: Add Pro badge & disabled state for Autonomous Mode toggle
- APIClient: Parse JSON error responses for better user-facing messages
- Supports new 402 Payment Required responses from license-gated endpoints
2025-12-25 21:29:46 +00:00
rcourtman
fe3b4ed5b6 fix: require Pro license for auto-fix and autonomous mode
- patrol.go: Auto-fix now requires both config flag AND ai_autofix license
- service.go: IsAutonomous() checks for ai_autofix license before enabling
- ai_handlers.go: API returns 402 if enabling auto-fix/autonomous without license
2025-12-25 21:26:46 +00:00
rcourtman
08c04b78ae feat: add power consumption monitoring (Intel RAPL + AMD Energy)
- Add power.go with Intel RAPL and AMD energy driver support
- Read CPU package, core, and DRAM power consumption in watts
- Sample energy counters over 100ms interval to calculate power
- Add PowerWatts field to Sensors struct for API reporting
- Integrate power collection into host agent sensor gathering
- Add comprehensive tests for power collection module

Supports Intel CPUs (Sandy Bridge+) via RAPL and AMD Ryzen/EPYC
via the amd_energy kernel module.

Closes community-scripts/ProxmoxVE#9575
2025-12-25 21:14:12 +00:00
rcourtman
1329c08305 fix: URL edit popover now respects viewport boundaries. Related to #912
- Added viewport boundary detection using visualViewport API (iOS-friendly)
- Popover flips above the button when there isn't enough space below
- Ensures popover stays within horizontal viewport bounds
2025-12-25 20:47:28 +00:00
rcourtman
aee0b93a61 fix: ThresholdsTable now uses Guest URL for node navigation. Related to #870 2025-12-25 20:39:53 +00:00
rcourtman
c3a112a2ec docs: add social preview image for GitHub 2025-12-25 20:24:45 +00:00
rcourtman
a14a45b534 chore: add Ko-fi to funding options 2025-12-25 20:23:00 +00:00
rcourtman
e040d9a3e7 docs: improve README with stars badge, updated tagline, and evergreen headers 2025-12-25 20:19:30 +00:00
rcourtman
a9205e7d51 docs: update dashboard screenshot to match landing page 2025-12-25 20:17:39 +00:00
rcourtman
7dd6c0d57a feat: Collect and display all lm-sensors data (fans, DDR5, etc.)
Extended lm-sensors parsing to capture all sensor readings:
- Fan speeds (RPM) from SuperIO chips like NCT6687
- Additional temperatures (DDR5/RAM, motherboard, etc.)
- All sensors not already captured as CPU/NVMe/GPU

Updated frontend tooltip to display fans and additional sensors
in separate sections with formatted names.

Closes discussion #911
2025-12-25 19:08:03 +00:00
rcourtman
946e47542d fix: Remove hardcoded sudo from agent install commands
On Proxmox VE and many minimal Linux systems, sudo is not installed
when logged in as root. The install script already checks for root
privileges and exits with a message if not root.

Updated command templates to use 'bash -s --' instead of 'sudo bash -s --'
and added notes clarifying users should run as root (via sudo or su -).

Related to #909
2025-12-25 18:56:54 +00:00
rcourtman
b638420b72 docs: Add disk exclusion and S.M.A.R.T. documentation
- Document --disk-exclude flag and PULSE_DISK_EXCLUDE env var
- Document pattern types (exact, prefix, contains)
- Document S.M.A.R.T. requirements (smartmontools package)
- Add --enable-commands to configuration table
2025-12-25 12:20:07 +00:00
rcourtman
c1422882bd feat: Add disk exclusion filter for host agent. Closes #896
Users can now exclude specific mount points from disk monitoring:
- Via CLI: --disk-exclude /mnt/backup --disk-exclude '/media/*'
- Via env: PULSE_DISK_EXCLUDE=/mnt/backup,*pbs*

Patterns support:
- Exact paths: /mnt/backup
- Prefix patterns: /mnt/ext*
- Contains patterns: *pbs*

This addresses the common case where external disks or
PBS datastores are being monitored but shouldn't be.
2025-12-25 12:04:40 +00:00
rcourtman
05aeab43ad test: Add unit tests for smartctl package
- Test disk type detection (NVMe, SAS, SATA)
- Test WWN formatting
- Test struct creation and JSON parsing
- Test NVMe temperature fallback location
2025-12-25 11:55:37 +00:00
rcourtman
96fc475375 feat: Hide AI buttons when AI is not configured. Closes #905
- InvestigateProblemsButton now checks aiChatStore.enabled
- InvestigateAlertButton returns null when AI is not enabled
- This provides cleaner UX for users who don't use AI features
2025-12-25 11:50:06 +00:00
rcourtman
8f9d5c1120 feat: Agent collects S.M.A.R.T. disk data via smartctl. Related to #907
- Add smartctl package to collect disk temperature and health data
- Add SMART field to agent Sensors struct
- Host agent now runs smartctl to collect disk temps when available
- Backend processes agent SMART data for temperature display
- Graceful fallback when smartctl not installed
2025-12-25 11:37:53 +00:00
rcourtman
800fab10c2 fix: Use LinkedNodeID for temperature matching to fix duplicate hostname bug
When two Proxmox nodes have the same hostname (e.g., 'px1' on different IPs),
the getHostAgentTemperature function was matching by hostname alone, causing
both nodes to show temperature from whichever host agent appeared first.

The fix:
- Added getHostAgentTemperatureByID that first tries matching by LinkedNodeID
  (the unique node ID) before falling back to hostname matching
- Updated the caller to pass modelNode.ID for precise matching
- Maintains backwards compatibility for setups where linking hasn't occurred

Related to #891
2025-12-25 10:00:19 +00:00
rcourtman
974beeae48 fix(#903): Add 2-minute timeout for pending config sync
If an agent doesn't confirm the config change within 2 minutes (e.g., offline),
the sync indicator is cleared and a warning notification is shown. This prevents
the spinner from spinning forever when agents are unreachable.

The toggle returns to showing the agent-reported state after timeout, allowing
users to retry the toggle if needed.
2025-12-25 08:19:43 +00:00
rcourtman
0c7c6723c8 fix(#903): Optimistic toggle with sync indicator for AI commands
The toggle now:
1. Immediately shows the desired state after clicking (optimistic update)
2. Displays a spinning sync icon while waiting for agent confirmation
3. Disables the toggle during sync to prevent double-clicks
4. Reverts to original state if the API call fails
5. Clears sync state once agent reports the expected value

This provides clear visual feedback about the async nature of remote config
without requiring users to understand the underlying polling mechanism.
2025-12-25 08:15:35 +00:00
rcourtman
9a9c50f8b1 fix: Properly close command client WebSocket when disabling remotely
When the server disables command execution for an agent, we now properly
call Close() on the command client to tear down the WebSocket connection.
Previously we just set the pointer to nil which left the goroutine running
with an orphaned connection.
2025-12-25 08:09:42 +00:00
rcourtman
55f63d5e96 feat(#903): Remote agent configuration for AI command execution
This implements full remote configuration for the AI command execution setting:

Backend:
- Add CommandsEnabled field to HostMetadata for persistent storage
- Add GetHostAgentConfig/UpdateHostAgentConfig methods to Monitor
- Add /api/agents/host/{id}/config endpoint (GET for agents, PATCH for UI)
- Server includes config in report response for immediate agent application
- Agent parses response and dynamically enables/disables command client

Frontend:
- Add 'AI Commands' toggle column in Managed Agents table
- Toggle immediately updates server config; agent applies on next heartbeat
- Add 'Enable AI command execution' checkbox in agent installer wizard
- Checkbox adds --enable-commands flag to generated install commands

This allows users to:
1. Enable at install time via checkbox in the wizard
2. Toggle remotely via the Managed Agents UI for existing agents
3. Agents apply changes automatically on their next report cycle
2025-12-25 08:07:28 +00:00
rcourtman
598285d3d2 feat: Agent reports CommandsEnabled status to server. Related to #903
- Add CommandsEnabled field to AgentInfo in pkg/agents/host/report.go
- Agent now reports whether AI command execution is enabled
- Server stores and exposes this via Host model
- Frontend can now show which agents have commands enabled
- This provides visibility before implementing remote configuration
2025-12-25 07:55:22 +00:00
rcourtman
2b58722906 fix: Node disk column respects Trends view mode. Related to #904
The disk column for Proxmox nodes was always showing bars even when
Trends (sparklines) view mode was selected. Memory column was correctly
checking viewMode() but disk was not.

Added the same Show when={viewMode() === 'sparklines'} conditional
to the disk column rendering in NodeSummaryTable.
2025-12-25 05:08:34 +00:00
rcourtman
0feb039775 fix: Allow dismissing AI findings without Pro license. Related to #885
Users who accumulated AI patrol findings before the patrol-without-AI
bug was fixed (24c4bb0b) could not dismiss them because the dismiss and
resolve endpoints required a Pro license.

Changes:
- Remove Pro license requirement from /api/ai/patrol/dismiss endpoint
- Remove Pro license requirement from /api/ai/patrol/resolve endpoint
- Add ClearAll() method to FindingsStore for bulk clearing
- Add DELETE /api/ai/patrol/findings endpoint for clearing all findings
- Add "Clear All" button to AI Insights UI

Users can now dismiss or resolve any findings they can see, and admins
can clear all findings at once if needed.
2025-12-25 05:06:26 +00:00
rcourtman
9cebf9cd21 fix: Immediately broadcast backup/snapshot updates to frontend
Backup and snapshot polling runs asynchronously and could take 20-45 seconds to complete, but WebSocket broadcasts happened on a separate fixed-interval timer. This caused frontend to show stale data until a broadcast happened to coincide with completed polling - which could take hours.

Now broadcasts state immediately after backup/snapshot polling completes, ensuring users see changes within seconds.

Related to #895
2025-12-25 00:09:07 +00:00
rcourtman
0a25da05d3 fix: VERSION file should not have v prefix 2025-12-24 23:15:09 +00:00
rcourtman
da0e0495ad fix: Remove agent should delete all types, not just first (#898)
When removing a unified agent that has both host and docker types,
clicking Remove only deleted the first type (host), leaving docker
behind.

Also fix: Host stats now greyed out when offline (#899)

On the Hosts page, CPU/Memory/Disk/Uptime now show a placeholder
dash when the host is offline, matching the Proxmox page behavior.
The entire row is also dimmed for visual consistency.
2025-12-24 22:34:38 +00:00
rcourtman
5b28ed6f50 chore: bump version to v5.0.3 2025-12-24 22:21:03 +00:00
rcourtman
106a78e810 fix: Managed Agents deduplicating by hostname instead of id
When multiple agents share the same hostname (e.g., 'px1'), the Managed
Agents view was showing only the last-added agent because it was using
hostname as the Map key.

Changed keying from hostname to id so that each agent shows separately.
The host+docker type merging now only happens when agents share the same
id (indicating the same physical machine).

Related to #891
2025-12-24 21:28:01 +00:00
rcourtman
a56a6c392d fix: Group VMs by instance instead of node for duplicate hostname support
When multiple Proxmox instances share the same hostname (e.g., 'px1'),
VMs were incorrectly grouped together under a single heading.

Changed grouping key from guest.node (raw hostname) to guest.instance
(disambiguated name like 'px1 (10.0.2.224)') to properly separate VMs
from different Proxmox instances.

Related to #891
2025-12-24 21:26:11 +00:00
rcourtman
d85cca3ace fix: Host Agents alert toggle button not working. Fixes #893
The toggleDisabled function was missing hostAgentsWithOverrides() in the
allResources array and 'hostAgent' in the allowed resource types check,
causing the toggle button to silently return without doing anything.
2025-12-24 19:42:41 +00:00
rcourtman
0eb512f90d feat: Add SysV init support for legacy systems. Related to #894
Adds support for systems that use SysV init (like Asustor NAS) that don't have
systemd, OpenRC, or launchd. The installer now:

- Detects /etc/init.d as a fallback when no other init system is found
- Creates an LSB-compliant init script with start/stop/restart/status
- Uses update-rc.d (Debian) or chkconfig (RHEL) to enable on boot
- Falls back to manual rc.d symlink creation if neither tool is available
- Properly cleans up on uninstall
2025-12-24 19:40:23 +00:00
rcourtman
422301a2dc Auto-update Helm chart version to 5.0.2 2025-12-24 18:36:23 +00:00
rcourtman
ee504eb328 Auto-update Helm chart documentation 2025-12-24 18:36:23 +00:00
rcourtman
3b318e78e8 chore: bump version to 5.0.2 2025-12-24 17:46:47 +00:00
rcourtman
2420c2affb feat: Commands disabled by default, require --enable-commands to opt-in
BREAKING CHANGE: AI command execution on agents is now disabled by default.
Users who want AI auto-fix must explicitly enable it with --enable-commands
flag or PULSE_ENABLE_COMMANDS=true environment variable.

Changes:
- Add --enable-commands flag (opt-in for command execution)
- Commands disabled by default for security (defense-in-depth)
- --disable-commands is now deprecated (logs warning, no longer needed)
- PULSE_DISABLE_COMMANDS deprecated in favor of PULSE_ENABLE_COMMANDS
- Update installer script to use --enable-commands
- Backwards compatibility: PULSE_DISABLE_COMMANDS=false still enables commands

This addresses community feedback about secure defaults for arbitrary
command execution on production infrastructure.

Related to #889
2025-12-24 17:36:44 +00:00
rcourtman
73a92813f5 feat: add --disable-commands flag to installer script. Related to #889 2025-12-24 17:09:48 +00:00
rcourtman
2c76cdaa43 docs: add backup permissions fix for v4→v5 upgrades
Users upgrading from v4 may have tokens that lack PVEDatastoreAdmin
permission on /storage, causing backups to not appear.

Added section to UPGRADE_v5.md with quick fix command and alternative
approach (re-run agent setup).

Related to #883
2025-12-24 16:33:01 +00:00
rcourtman
a9078e96d1 fix: apply duplicate hostname fix to HandleAddNode (manual UI)
Extended Issue #891 fix to cover manual node addition via the UI:

1. HandleAddNode now checks for duplicates by Host URL (not name)
2. Disambiguator applied to PVE, PBS, and PMG node creation
3. Error message updated: 'host URL already exists' instead of 'name already exists'

This ensures the fix works whether nodes are added via:
- Agent auto-registration ✓
- Manual UI setup ✓

All node creation paths now consistently:
- Match by Host URL only
- Disambiguate duplicate hostnames with IP: 'px1' → 'px1 (10.0.2.224)'
2025-12-24 16:17:37 +00:00
rcourtman
44b25b43ac fix: handle DHCP IP changes without creating duplicates
Follow-up to #891 fix - also match by name+tokenID to handle the case
where the same physical host gets a new IP (DHCP). This ensures:

1. Same hostname + DIFFERENT token = different physical hosts → create separate nodes
2. Same hostname + SAME token = same host with new IP → update existing node

Also updates the host URL when an existing node is matched, so IP changes
are properly reflected in the saved configuration.
2025-12-24 16:09:22 +00:00
rcourtman
92988ae0e6 fix: allow duplicate hostnames for different Proxmox hosts. Related to #891
PROBLEM:
When two Proxmox hosts have the same hostname (e.g., 'px1' on different networks),
the auto-registration was matching by name and overwriting the first with the second.
This has been a recurring issue (#104) with at least 3 prior fix attempts.

ROOT CAUSE:
The auto-register handler matched existing nodes by BOTH Host URL and Name.
Matching by name is incorrect - different physical hosts can share hostnames.

FIXES:
1. Remove name-based matching in auto-registration - match by Host URL only
2. Add disambiguateNodeName() to append IP when duplicate hostnames exist
3. Add regression tests to prevent this from breaking again

Now when registering two hosts named 'px1':
- First becomes: px1
- Second becomes: px1 (10.0.2.224)
Both are stored as separate nodes with their own credentials.
2025-12-24 16:05:07 +00:00
rcourtman
e86998ec58 fix: AI Patrol only runs when AI is enabled. Related to #885
Users who haven't enabled AI were seeing AI patrol findings from
heuristic analysis that they couldn't dismiss (license-gated).

- IsPatrolEnabled() now checks if Enabled is true
- IsAlertTriggeredAnalysisEnabled() also checks Enabled
- Updated tests to reflect new behavior

AI patrol and alert-triggered analysis require AI to be enabled
as a master switch. This prevents confusing UX where users see
AI features without having configured them.
2025-12-24 16:05:07 +00:00
rcourtman
e5c7cf7d1e fix: AI request timeout setting not persisting. Related to #884
Added request_timeout_seconds field to:
- AISettingsResponse struct (for GET responses)
- AISettingsUpdateRequest struct (for PUT requests)
- HandleUpdateAISettings handler logic (validation + persistence)
- HandleGetAISettings response builder

The frontend was already sending request_timeout_seconds but the
backend was ignoring it. Now the setting persists correctly.
2025-12-24 16:05:07 +00:00
rcourtman
cc4ade7453 Auto-update Helm chart version to 5.0.1 2025-12-24 11:54:55 +00:00