- Create shared NodeGroupHeader component to eliminate code duplication
- Replace vertical line indicator with circular dot matching guest rows
- Update online indicator to use bg-green-500 (matching guest indicators)
- Reduce node row padding from py-2 to py-1 for more compact layout
- Set background to dark:bg-gray-900 to match search bar styling
- Apply changes consistently across Dashboard and Storage tabs
This commit addresses all issues reported in GitHub issue #485:
1. **SMART Status Recognition**
- Fix disk health check to accept both "PASSED" and "OK" status
- Previously only "PASSED" was recognized as healthy
- Location: internal/monitoring/monitor.go:1255
2. **ZFS Spare Device False Alerts**
- Skip ZFS SPARE devices unless they have actual errors
- SPARE devices are intentional and should not trigger alerts
- Updated in two locations:
- pkg/proxmox/zfs.go:154 (device filtering)
- internal/alerts/alerts.go:1077 (alert generation)
3. **Memory Display Granularity**
- Increase byte formatting precision from 0 to 1 decimal place
- Improves accuracy (e.g., "1.7 GB" instead of "1 GB" for 86% of 2GB)
- Location: frontend-modern/src/utils/format.ts:3
4. **Custom Alert Rules Evaluation**
- Add ReevaluateGuestAlert() method for proper threshold reevaluation
- Add comments explaining custom rules evaluation limitations
- Next poll cycle will properly clear stale alerts with new thresholds
Additional improvements:
- Fix ZFS pool alert locking to prevent deadlocks
- Prevent discovery service from running in mock mode
- Restore discovery service when exiting mock mode
Fixes#485
Improve performance when serving /api/state in mock mode by optimizing
alert handling and JSON serialization.
Changes:
- Add UpdateAlertSnapshots() to cache alerts without blocking
- Use lazy population of alert snapshots to avoid lock contention
- Switch to json.Marshal for better performance with large payloads
- Add debug logging to track /api/state performance
- Simplify GetState() logic in mock mode
Performance improvements:
- Eliminates alert manager lock during /api/state requests
- Reduces JSON encoding overhead for large mock datasets
- Ensures sub-second response times even with 7 nodes and 90+ guests
Testing:
- Mock mode returns state instantly without blocking
- Alert snapshots populate correctly on first request
- Debug logs confirm fast execution path
addresses #476
added Instance field to StorageBackup and GuestSnapshot structs in both
backend and frontend to properly handle nodes with duplicate hostnames.
updated backup and snapshot counting logic to use instance ID instead of
hostname, consistent with the VM/container/storage count fixes.
this completes the fix for #476 - all counts and groupings now use unique
instance IDs instead of hostnames.
addresses #101
- Implement SSH-based temperature collector using lm-sensors
- Add Temperature struct to node models (CPU package, cores, NVMe)
- Collect temps during node polling (5s timeout, non-blocking)
- Display temperature in node cards with color coding:
- Green: <60°C
- Yellow: 60-80°C
- Red: >80°C
- Shows CPU temp or falls back to load average if unavailable
- Tooltip includes NVMe drive temps when present
- Uses root SSH access (no additional auth setup needed for now)
- Temperature data only collected for online nodes
addresses #477
Expanded the timezone dropdown from 11 options to 70+ common IANA
timezones covering all major regions (Africa, Americas, Asia,
Australia, Europe, Pacific).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Corrected widespread misinformation claiming API tokens cannot access guest agent data on Proxmox 9.
Changes:
- Rewrote VM_DISK_MONITORING.md with accurate technical explanation
- Deleted VM_DISK_STATS_TROUBLESHOOTING.md (contained false information)
- Updated FAQ.md with correct quick reference and troubleshooting link
- Added comprehensive VM disk troubleshooting section to TROUBLESHOOTING.md
- Fixed README.md troubleshooting reference
- Updated frontend tooltip to show accurate permission requirements
- Corrected backend log messages to remove "known limitation" language
- Updated test-vm-disk.sh diagnostic script with accurate guidance
Key corrections:
- API tokens work fine for guest agent queries on both PVE 8 and 9
- Proxmox API returning disk=0 is normal behavior, not a bug
- Both tokens and passwords work equally well
- Only requirements: guest agent installed + proper permissions
- Permission issues are config problems, not authentication method limitations
Documentation now provides clear user journey: FAQ → Troubleshooting → Full Guide
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The aggressive use of cluster/resources was breaking storage collection
for setups with multiple standalone nodes or improperly clustered nodes.
Now only uses cluster/resources when explicitly configured as a cluster,
falling back to traditional node-by-node polling otherwise.
This should fix the missing storage issue where one node's storage
wasn't showing after upgrading to rc5.
The issue was that when a node was successfully polled but returned empty storage
(e.g., due to API permissions), it was still marked as 'successfully polled'.
This prevented the preservation logic from keeping existing storage data.
Now if a node returns empty storage but we have existing storage for that node,
we don't mark it as polled, allowing the preservation logic to keep the data.
This should fix the issue where storage disappears from one node in #448.
- Send error result to channel when storage query times out so preservation logic works
- Ensures storage data is preserved for nodes that experience timeouts
- Fixes issue where storage/backups would disappear when a node times out
When a node's storage query times out, don't return empty storage which would wipe out existing data. Instead, skip the node entirely so the preservation logic can maintain the existing storage information.
- Always try cluster/resources endpoint first (works on standalone nodes too)
- Only fall back to traditional polling for very old Proxmox versions
- Confirmed working on standalone nodes like pimox
- Significantly reduces API calls and improves performance
- Addresses efficiency concerns from #447
PVE polling is hardcoded to 10s since Proxmox cluster/resources endpoint only updates every 10s internally. Setting faster polling intervals was wasteful and provided no benefit.
Removed:
- POLLING_INTERVAL env variable and all references
- pollingInterval from config structs and API responses
- UI settings for polling interval (already removed)
- Dynamic polling interval updates via SIGHUP
- Legacy persistence code for saving polling settings
The monitoring loop now uses a hardcoded 10s interval matching Proxmox's update frequency.
- Add debug logging to guest agent filesystem API responses
- Better handle Windows drive mountpoints (C:\, D:\, etc.)
- Improve empty filesystem list detection and logging
- Add specific handling for Windows filesystems that may report differently
This should help diagnose why some VMs with guest agents installed still show 0% or missing disk usage, particularly on Windows systems.
- Add specific warning for permission errors (401/403)
- Add info message for nodes without disk monitoring support
- Elevate error logging from debug to warn level for visibility
- Helps users understand why disks might not appear for certain nodes
- Increase WebSocket buffer sizes from 64KB to 4MB to handle large mock data
- Add robust reconnection logic with exponential backoff
- Implement heartbeat mechanism to detect stale connections faster
- Add manual reconnect button in UI when connection fails
- Fix unused variable warnings in monitor code
- Add debug logging to trace WebSocket state initialization
This resolves the issue where the frontend would hang after code changes
during hot-reload, especially when using mock mode with many nodes.
- Storage polling now preserves existing data when nodes are temporarily offline
- Backup polling preserves existing backups for unpolled nodes
- Prevents storage and backups from disappearing when nodes have connectivity issues
- Similar to the physical disk preservation fix
When a node is temporarily offline or has connectivity issues, preserve its last known physical disk data instead of removing it from the table. This prevents nodes from disappearing from the Physical Disks table when they have transient connection problems.
- Limit alert checking to 50 guests per cycle to prevent blocking
- Remove unnecessary state broadcast when alerts are resolved
- Fix deadlock in GetActiveAlerts by releasing lock quickly
- Enable handling of 800+ mock guests with sub-10ms response times
This allows Pulse to handle large-scale deployments efficiently for testing and production use.
The alert acknowledgment endpoints were hanging because GetState() was called
synchronously to broadcast updates via WebSocket, which could take significant
time with many nodes/guests. This caused the HTTP response to timeout, showing
an error to users even though the alert was successfully acknowledged.
Fixed by:
- Sending HTTP response immediately after acknowledging the alert
- Moving WebSocket broadcast to a goroutine to avoid blocking
- Applied fix to all alert endpoints (acknowledge, unacknowledge, clear, bulk ops)
This resolves the issue where users saw 'Failed to acknowledge alert' errors
but the alert was actually acknowledged (disappeared on refresh).
- handle PBS node status endpoint permission errors gracefully (returns nil instead of error for 403s)
- add required cf and timeframe parameters to RRD endpoint calls
- properly handle nil nodeStatus returns in monitor.go
these API calls now fail silently as PBS API tokens often lack the required permissions for these endpoints, which is expected behavior
- Add retry logic with delays to detectPVECluster function to handle API permission propagation
- Periodically re-check standalone nodes to detect if they're actually part of a cluster
- Increase timeout from 3 to 5 seconds for cluster detection attempts
- Skip retries for definitively standalone nodes (501 not implemented errors)
This addresses the issue where adding a PVE cluster doesn't detect it properly on first attempt,
requiring deletion and re-adding to work correctly. The retry mechanism gives time for
API permissions to fully propagate in Proxmox.
- Add Available field to MemoryStatus struct to capture memory available for allocation
- Update node memory calculation to use Available memory when present
- This excludes non-reclaimable cache/buffers from used memory calculation
- Provides more accurate memory pressure indication, avoiding false alerts
- Falls back to traditional used memory if Available field is missing (older Proxmox versions)
- Changed logic to always query guest agent when available, not just when disk is 0
- This fixes issue where Proxmox returns incorrect non-zero values from cluster/resources
- Guest agent data is now preferred over cluster/resources data for all running VMs
- Improved logging to show when we're replacing cluster data with guest agent data
This should resolve the issue reported by FaboulousSan where VMs were showing
host disk space instead of actual VM disk usage.
- Add comprehensive filtering for network filesystems (NFS, CIFS, SMB, FUSE, 9p)
- Skip Docker volumes, snap mounts, and other special mountpoints
- Add detailed logging to track which filesystems are included/excluded
- Add sanity check to detect when reported disk is way larger than allocated
- Improve logging with GB values and more context for debugging
This should prevent Pulse from accidentally including host disk space or
network shares when calculating VM disk usage. Users can use the existing
diagnostics system in the UI to troubleshoot VM disk issues.
The disk monitoring backend was working but frontend wasn't updating because the WebSocket store was missing the handler for physicalDisks data. Also added physicalDisks count to broadcast logging for better debugging.
- Added disk polling to monitoring cycle using Proxmox API
- Created CheckDiskHealth() alert manager for failing drives and low SSD life
- Added PhysicalDisk model to state with proper serialization
- Implemented DiskList component with health indicators and SSD wearout bars
- Added Physical Disks tab to Storage page with toggle between pools and disks
- Added ZFS health badges to storage cards for degraded/failed pools
- Alerts trigger for health != PASSED and SSD wearout < 10%
- Frontend displays disk model, type, temperature, and usage information
- Always query guest agent for running VMs instead of only when disk is 0
- Add duplicate mount point detection to prevent inflated disk totals
- Show allocated disk size as fallback when guest agent unavailable
- Add comprehensive logging for guest agent disk queries
- Include diagnostic script for troubleshooting VM disk issues
- Always query guest agent for running VMs (cluster/resources API always returns 0)
- Show allocated disk size when guest agent unavailable (instead of misleading 0%)
- Fix duplicate mount point counting issue (#425)
- Add comprehensive logging for guest agent queries
- Include diagnostic script for troubleshooting VM disk issues
- Update both monitor.go and monitor_optimized.go for consistency
The parallel optimization introduced in commit 634e0dd37 accidentally removed
all guest agent filesystem fetching logic from the optimized monitor code.
This caused VMs with guest agents to show no disk stats after v4.12.1.
Added back the guest agent fetching logic to pollVMsWithNodesOptimized:
- Fetches filesystem info when VM disk stats are 0
- Aggregates disk usage from all valid filesystems
- Skips special filesystems and Windows System Reserved partitions
- Uses guest agent data when available to show accurate disk usage
This restores disk stats display for VMs with working QEMU guest agents.
- Added debug mode: localStorage.setItem('debug-pmg', 'true')
- Robust VMID=0 detection handles string and number types
- Debug logging shows exactly what's happening with PMG backups
- Created test suite that verifies all PMG backup scenarios
- All test cases pass including PBS 'ct' type with VMID='0'
Users experiencing issues can enable debug mode to help diagnose:
1. Open browser console
2. Run: localStorage.setItem('debug-pmg', 'true')
3. Reload page and check for [PMG Debug] messages
4. Share debug output if still showing as LXC
Test results:
✓ PBS PMG backup (ct type with VMID 0) → Host
✓ PBS PMG backup (ct type with numeric VMID 0) → Host
✓ Storage PMG backup (host type) → Host
✓ Storage PMG backup (lxc type with VMID 0) → Host
✓ Regular LXC backup → LXC
- Add PULSE_ENABLE_ZFS_MONITORING env var (disabled by default)
- Fix API field mapping (health vs state, cksum vs checksum)
- Add proper API endpoint structures for list and detail
- Mark feature as experimental due to API complexity
- Simplify conversion to handle basic health status only
This is a safer approach until we can fully test with real Proxmox nodes
- Add ZFS pool status data structures to models
- Implement ZFS pool data collection via Proxmox API
- Add ZFS pool health alerts for degraded/faulted states
- Add ZFS device error detection and alerting
- Display ZFS pool status in Storage tab when issues detected
- Add mock data generation for testing ZFS monitoring
- Alert on read/write/checksum errors for pools and devices
- Reduced storage API timeout from 120s to 15s to prevent blocking when storage mounts are unavailable
- Added graceful error handling for storage timeouts - continues with partial data instead of failing
- Improved error messages to clarify when timeouts are likely due to unavailable storage (e.g., NFS mounts)
This prevents Pulse from marking nodes as unhealthy when storage endpoints timeout due to temporarily unavailable network storage.
- Use main host for cluster operations when node endpoints lack FQDNs/IPs
- Skip initial health check for single-endpoint clusters (main host routing)
- Return empty lists instead of errors when cluster nodes are unreachable
- Prevent VMs/containers from disappearing when cluster has connectivity issues
- Fix the 'Instance marked as cluster but is actually standalone' false warning
PBS storage should respect Proxmox's shared configuration. When PBS
storage is configured without node restrictions in Proxmox, it appears
as shared storage accessible by all nodes. Updated mock data to match
real cluster behavior where PBS entries appear under 'cluster' group.
PBS storage was being marked as shared when it shouldn't be. Each PBS
namespace is node-specific even when connecting to the same PBS server.
Now PBS storage correctly shows under its respective node instead of
all being assigned to the last node.
When some cluster nodes are offline but the main node can still reach others,
show a yellow status dot instead of red to indicate partial connectivity.
This better represents the actual cluster health state.
- Added PULSE_PUBLIC_URL config option to specify the full URL to access Pulse
- Updated notification manager to use publicURL when constructing webhook payloads
- Modified prepareWebhookData to construct full URLs instead of just paths
- Fixed test webhooks to use configured publicURL instead of hardcoded values
- Gotify and ntfy notifications now include clickable links that work properly
- Windows System Reserved partitions now excluded from disk usage
- Added better handling for filesystems with zero total bytes
- Improved debug logging for skipped filesystems
- Prevents incorrect disk usage display for Windows VMs
- Fixed shared storage jumping between nodes on each update by using consistent deduplication
- Shared storage now displays with node="cluster" to indicate it's cluster-wide
- Improved error logging when storage API calls fail to help diagnose permission issues
- Added specific warning when all nodes fail to retrieve storage (helps with #385, #411)
The jumping storage issue (#410) was caused by a race condition where parallel goroutines
would report shared storage under whichever node completed first, causing it to randomly
"jump" between nodes on each polling cycle.