diff --git a/README.md b/README.md index e077752..c0c0b56 100644 --- a/README.md +++ b/README.md @@ -471,7 +471,7 @@ See [Reverse Proxy Configuration Guide](docs/REVERSE_PROXY.md) for nginx, Caddy, ### Connection Issues - Check Proxmox API is accessible (port 8006/8007) -- Verify credentials have PVEAuditor role minimum +- Verify credentials have PVEAuditor role plus VM.GuestAgent.Audit (PVE 9) or VM.Monitor (PVE 8); the setup script applies these via the PulseMonitor role (adds Sys.Audit when available) - For PBS: ensure API token has Datastore.Audit permission ### High CPU/Memory diff --git a/docs/DOCKER_HUB_README.md b/docs/DOCKER_HUB_README.md index 50bc714..c55cd69 100644 --- a/docs/DOCKER_HUB_README.md +++ b/docs/DOCKER_HUB_README.md @@ -264,7 +264,7 @@ docker run -d -p 7655:7655 \ ### Connection Issues - Check Proxmox API is accessible (port 8006/8007) -- Verify credentials have PVEAuditor role minimum +- Verify credentials have PVEAuditor role plus VM.GuestAgent.Audit (PVE 9) or VM.Monitor (PVE 8); the setup script applies these via the PulseMonitor role (adds Sys.Audit when available) - For PBS: ensure API token has Datastore.Audit permission ### Logs diff --git a/docs/FAQ.md b/docs/FAQ.md index 11d03be..2fa072f 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -33,8 +33,8 @@ If a setting is disabled with an amber warning, it's being overridden by an envi Remove the env var (check `sudo systemctl show pulse | grep Environment`) and restart to enable UI configuration. ### What permissions needed? -- PVE: `PVEAuditor` minimum (includes VM.GuestAgent.Audit for disk usage in PVE 9+) -- PVE 8: Also needs `VM.Monitor` permission for VM disk usage via QEMU agent +- PVE core API access: `PVEAuditor` +- PVE guest metrics: `VM.GuestAgent.Audit` (PVE 9+) or `VM.Monitor` (PVE 8) plus `Sys.Audit` for Ceph — Pulse setup script adds these to the `PulseMonitor` role automatically - PBS: `DatastoreReader` minimum ### API tokens vs passwords? @@ -123,9 +123,10 @@ VMs show "-" because the QEMU Guest Agent is not installed or not working. This ``` 5. **Check Pulse has permissions:** - - Proxmox 9: `PVEAuditor` role (includes `VM.GuestAgent.Audit`) - - Proxmox 8: `VM.Monitor` permission - - The setup script adds these automatically + - Proxmox 9: `VM.GuestAgent.Audit` privilege (Pulse setup adds via `PulseMonitor`) + - Proxmox 8: `VM.Monitor` privilege (Pulse setup adds via `PulseMonitor`) + - `Sys.Audit` is recommended for Ceph metrics and included when available + - The setup script applies all of the above automatically **Note:** Container (LXC) disk usage always works without guest agent because containers share the host kernel. diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index 452559b..396c3aa 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -279,8 +279,9 @@ pveum user permissions pulse-monitor@pam ``` **Required permissions:** -- **Proxmox 9:** `PVEAuditor` role (includes `VM.GuestAgent.Audit`) -- **Proxmox 8:** `VM.Monitor` permission +- **Proxmox 9:** `VM.GuestAgent.Audit` privilege (Pulse setup adds this via the `PulseMonitor` role) +- **Proxmox 8:** `VM.Monitor` privilege (Pulse setup adds this via the `PulseMonitor` role) +- **All versions:** `Sys.Audit` is recommended for Ceph metrics and applied when available **Fix permissions:** @@ -291,12 +292,48 @@ curl -sSL https://raw.githubusercontent.com/rcourtman/Pulse/main/scripts/setup-p Or manually: ```bash -# Proxmox 9 +# Shared read-only access pveum aclmod / -user pulse-monitor@pam -role PVEAuditor -# Proxmox 8 -pveum role add PulseMonitor -privs VM.Monitor -pveum aclmod / -user pulse-monitor@pam -role PulseMonitor +# Extra privileges for guest metrics and Ceph +EXTRA_PRIVS=() + +# Sys.Audit (Ceph, cluster status) +if pveum role list 2>/dev/null | grep -q "Sys.Audit"; then + EXTRA_PRIVS+=(Sys.Audit) +else + if pveum role add PulseTmpSysAudit -privs Sys.Audit 2>/dev/null; then + EXTRA_PRIVS+=(Sys.Audit) + pveum role delete PulseTmpSysAudit 2>/dev/null + fi +fi + +# VM guest agent / monitor privileges +VM_PRIV="" +if pveum role list 2>/dev/null | grep -q "VM.Monitor"; then + VM_PRIV="VM.Monitor" +elif pveum role list 2>/dev/null | grep -q "VM.GuestAgent.Audit"; then + VM_PRIV="VM.GuestAgent.Audit" +else + if pveum role add PulseTmpVMMonitor -privs VM.Monitor 2>/dev/null; then + VM_PRIV="VM.Monitor" + pveum role delete PulseTmpVMMonitor 2>/dev/null + elif pveum role add PulseTmpGuestAudit -privs VM.GuestAgent.Audit 2>/dev/null; then + VM_PRIV="VM.GuestAgent.Audit" + pveum role delete PulseTmpGuestAudit 2>/dev/null + fi +fi + +if [ -n "$VM_PRIV" ]; then + EXTRA_PRIVS+=("$VM_PRIV") +fi + +if [ ${#EXTRA_PRIVS[@]} -gt 0 ]; then + PRIV_STRING="${EXTRA_PRIVS[*]}" + pveum role delete PulseMonitor 2>/dev/null + pveum role add PulseMonitor -privs "$PRIV_STRING" + pveum aclmod / -user pulse-monitor@pam -role PulseMonitor +fi ``` **Important:** Both API tokens and passwords work fine for guest agent access. If you see permission errors, it's a permission configuration issue, not an authentication method limitation. diff --git a/docs/VM_DISK_MONITORING.md b/docs/VM_DISK_MONITORING.md index 6ee1f3b..dce6bb7 100644 --- a/docs/VM_DISK_MONITORING.md +++ b/docs/VM_DISK_MONITORING.md @@ -79,25 +79,62 @@ qm agent get-fsinfo Pulse needs the right permissions to query the guest agent: **Proxmox VE 8 and below:** -- Requires `VM.Monitor` permission -- Setup script automatically adds this +- Requires `VM.Monitor` for guest agent access +- `Sys.Audit` adds Ceph/cluster metrics and is applied when available +- Pulse setup script creates a `PulseMonitor` role with these privileges automatically **Proxmox VE 9+:** -- Requires `VM.GuestAgent.Audit` permission (included in `PVEAuditor` role) -- Setup script automatically configures this +- Requires `VM.GuestAgent.Audit` for guest agent access +- `Sys.Audit` remains recommended for Ceph/cluster metrics +- Pulse setup script applies both via the `PulseMonitor` role (even if `PVEAuditor` lacks them) **Both API tokens and passwords work** - tokens do NOT have any limitation accessing guest agent data. When you run the Pulse setup script, it automatically detects your Proxmox version and sets the correct permissions. If setting up manually: ```bash -# Proxmox 9+ +# Shared read-only access pveum aclmod / -user pulse-monitor@pam -role PVEAuditor -# PVEAuditor includes VM.GuestAgent.Audit in PVE 9+ -# Proxmox 8 and below -pveum role add PulseMonitor -privs VM.Monitor -pveum aclmod / -user pulse-monitor@pam -role PulseMonitor +# Extra privileges for guest metrics and Ceph +EXTRA_PRIVS=() + +# Sys.Audit (Ceph, cluster status) +if pveum role list 2>/dev/null | grep -q "Sys.Audit"; then + EXTRA_PRIVS+=(Sys.Audit) +else + if pveum role add PulseTmpSysAudit -privs Sys.Audit 2>/dev/null; then + EXTRA_PRIVS+=(Sys.Audit) + pveum role delete PulseTmpSysAudit 2>/dev/null + fi +fi + +# VM guest agent / monitor privileges +VM_PRIV="" +if pveum role list 2>/dev/null | grep -q "VM.Monitor"; then + VM_PRIV="VM.Monitor" +elif pveum role list 2>/dev/null | grep -q "VM.GuestAgent.Audit"; then + VM_PRIV="VM.GuestAgent.Audit" +else + if pveum role add PulseTmpVMMonitor -privs VM.Monitor 2>/dev/null; then + VM_PRIV="VM.Monitor" + pveum role delete PulseTmpVMMonitor 2>/dev/null + elif pveum role add PulseTmpGuestAudit -privs VM.GuestAgent.Audit 2>/dev/null; then + VM_PRIV="VM.GuestAgent.Audit" + pveum role delete PulseTmpGuestAudit 2>/dev/null + fi +fi + +if [ -n "$VM_PRIV" ]; then + EXTRA_PRIVS+=("$VM_PRIV") +fi + +if [ ${#EXTRA_PRIVS[@]} -gt 0 ]; then + PRIV_STRING="${EXTRA_PRIVS[*]}" + pveum role delete PulseMonitor 2>/dev/null + pveum role add PulseMonitor -privs "$PRIV_STRING" + pveum aclmod / -user pulse-monitor@pam -role PulseMonitor +fi ``` ## Troubleshooting @@ -168,11 +205,13 @@ If you see "permission denied" in Pulse logs when querying guest agent: pveum user permissions pulse-monitor@pam ``` -2. **For Proxmox 9+:** Ensure user has `PVEAuditor` role or `VM.GuestAgent.Audit` permission +2. **For Proxmox 9+:** Ensure user has the `VM.GuestAgent.Audit` privilege (PulseMonitor role handles this) -3. **For Proxmox 8:** Ensure user has `VM.Monitor` permission +3. **For Proxmox 8:** Ensure user has the `VM.Monitor` privilege (PulseMonitor role handles this) -4. **Re-run setup script** if you added the node before Pulse v4.7 (old scripts didn't add VM.Monitor) +4. **All versions:** Confirm `Sys.Audit` is present for Ceph metrics when applicable + +5. **Re-run setup script** if you added the node before Pulse v4.7 (old scripts didn't add VM.Monitor/guest agent privileges) ### Disk Usage Still Not Showing @@ -240,4 +279,4 @@ With QEMU Guest Agent disk monitoring: - **Better planning** - See actual growth trends - **Prevent surprises** - Know when VMs are actually running out of space - **Optimize storage** - Identify over-provisioned VMs -- **Consistent monitoring** - VMs and containers use the same metrics \ No newline at end of file +- **Consistent monitoring** - VMs and containers use the same metrics diff --git a/frontend-modern/src/components/Settings/NodeModal.tsx b/frontend-modern/src/components/Settings/NodeModal.tsx index 2b766d3..17270eb 100644 --- a/frontend-modern/src/components/Settings/NodeModal.tsx +++ b/frontend-modern/src/components/Settings/NodeModal.tsx @@ -924,7 +924,7 @@ export const NodeModal: Component = (props) => { { - '# Apply monitoring permissions - use built-in PVEAuditor role\npveum aclmod / -user pulse-monitor@pam -role PVEAuditor\n\n# For Proxmox 8 and below, also check if VM.Monitor is needed\nif pveum role list 2>/dev/null | grep -q "VM.Monitor" || \\\n pveum role add TestMonitor -privs VM.Monitor 2>/dev/null; then\n # VM.Monitor exists (PVE 8 or below) - create additional role\n pveum role delete TestMonitor 2>/dev/null\n pveum role delete PulseMonitor 2>/dev/null\n pveum role add PulseMonitor -privs VM.Monitor\n pveum aclmod / -user pulse-monitor@pam -role PulseMonitor\nfi' + '# Apply monitoring permissions - use built-in PVEAuditor role\npveum aclmod / -user pulse-monitor@pam -role PVEAuditor\n\n# Gather additional privileges for VM metrics\nEXTRA_PRIVS=()\n\n# Sys.Audit (Ceph, cluster status)\nif pveum role list 2>/dev/null | grep -q "Sys.Audit"; then\n EXTRA_PRIVS+=(\"Sys.Audit\")\nelse\n if pveum role add PulseTmpSysAudit -privs Sys.Audit 2>/dev/null; then\n EXTRA_PRIVS+=(\"Sys.Audit\")\n pveum role delete PulseTmpSysAudit 2>/dev/null\n fi\nfi\n\n# VM guest agent / monitor privileges\nVM_PRIV=\"\"\nif pveum role list 2>/dev/null | grep -q "VM.Monitor"; then\n VM_PRIV=\"VM.Monitor\"\nelif pveum role list 2>/dev/null | grep -q "VM.GuestAgent.Audit"; then\n VM_PRIV=\"VM.GuestAgent.Audit\"\nelse\n if pveum role add PulseTmpVMMonitor -privs VM.Monitor 2>/dev/null; then\n VM_PRIV=\"VM.Monitor\"\n pveum role delete PulseTmpVMMonitor 2>/dev/null\n elif pveum role add PulseTmpGuestAudit -privs VM.GuestAgent.Audit 2>/dev/null; then\n VM_PRIV=\"VM.GuestAgent.Audit\"\n pveum role delete PulseTmpGuestAudit 2>/dev/null\n fi\nfi\n\nif [ -n \"$VM_PRIV\" ]; then\n EXTRA_PRIVS+=(\"$VM_PRIV\")\nfi\n\nif [ ${#EXTRA_PRIVS[@]} -gt 0 ]; then\n PRIV_STRING=\"${EXTRA_PRIVS[*]}\"\n pveum role delete PulseMonitor 2>/dev/null\n pveum role add PulseMonitor -privs \"$PRIV_STRING\"\n pveum aclmod / -user pulse-monitor@pam -role PulseMonitor\nfi' } @@ -966,10 +966,10 @@ export const NodeModal: Component = (props) => {

- ℹ️ PVEAuditor gives read-only access including - VM.GuestAgent.Audit (required for disk usage on PVE 9+). - PulseMonitor adds VM.Monitor (PVE 8 only). PVEDatastoreAdmin - on /storage adds backup management. + ℹ️ PVEAuditor gives read-only API access. PulseMonitor adds + Sys.Audit plus either VM.Monitor (PVE 8) or VM.GuestAgent.Audit + (PVE 9+) for disk and guest metrics. PVEDatastoreAdmin on + /storage adds backup visibility.

diff --git a/internal/api/config_handlers.go b/internal/api/config_handlers.go index 246c82c..979eb86 100644 --- a/internal/api/config_handlers.go +++ b/internal/api/config_handlers.go @@ -3361,6 +3361,28 @@ if pveum role list 2>/dev/null | grep -q "VM.Monitor" || pveum role delete TestMonitor 2>/dev/null || true fi +# Detect availability of newer guest agent privileges (PVE 9+) +HAS_VM_GUEST_AGENT_AUDIT=false +if pveum role list 2>/dev/null | grep -q "VM.GuestAgent.Audit"; then + HAS_VM_GUEST_AGENT_AUDIT=true +else + if pveum role add TestGuestAgentAudit -privs VM.GuestAgent.Audit 2>/dev/null; then + HAS_VM_GUEST_AGENT_AUDIT=true + pveum role delete TestGuestAgentAudit 2>/dev/null || true + fi +fi + +# Detect availability of Sys.Audit (needed for Ceph metrics) +HAS_SYS_AUDIT=false +if pveum role list 2>/dev/null | grep -q "Sys.Audit"; then + HAS_SYS_AUDIT=true +else + if pveum role add TestSysAudit -privs Sys.Audit 2>/dev/null; then + HAS_SYS_AUDIT=true + pveum role delete TestSysAudit 2>/dev/null || true + fi +fi + # Method 2: Try to detect PVE version directly PVE_VERSION="" if command -v pveversion >/dev/null 2>&1; then @@ -3368,18 +3390,33 @@ if command -v pveversion >/dev/null 2>&1; then PVE_VERSION=$(pveversion --verbose 2>/dev/null | grep "pve-manager" | awk -F'/' '{print $2}' | cut -d'.' -f1) fi +echo "Setting up additional permissions..." +EXTRA_PRIVS=() + +if [ "$HAS_SYS_AUDIT" = true ]; then + EXTRA_PRIVS+=("Sys.Audit") +fi + if [ "$HAS_VM_MONITOR" = true ]; then # PVE 8 or below - VM.Monitor exists - echo "Setting up additional permissions..." + EXTRA_PRIVS+=("VM.Monitor") +elif [ "$HAS_VM_GUEST_AGENT_AUDIT" = true ]; then + # PVE 9+ - VM.Monitor removed, prefer VM.GuestAgent.Audit for guest data + EXTRA_PRIVS+=("VM.GuestAgent.Audit") +fi + +if [ ${#EXTRA_PRIVS[@]} -gt 0 ]; then + PRIV_STRING="${EXTRA_PRIVS[*]}" pveum role delete PulseMonitor 2>/dev/null || true - pveum role add PulseMonitor -privs VM.Monitor 2>/dev/null - pveum aclmod / -user pulse-monitor@pam -role PulseMonitor + if pveum role add PulseMonitor -privs "$PRIV_STRING" 2>/dev/null; then + pveum aclmod / -user pulse-monitor@pam -role PulseMonitor + echo " • Applied privileges: $PRIV_STRING" + else + echo " • Failed to create PulseMonitor role with: $PRIV_STRING" + echo " Assign these privileges manually if Pulse reports permission errors." + fi else - # PVE 9+ - VM.Monitor was removed, try to add Sys.Audit as replacement - echo "Setting up additional permissions..." - pveum role delete PulseMonitor 2>/dev/null || true - pveum role add PulseMonitor -privs "Sys.Audit" 2>/dev/null - pveum aclmod / -user pulse-monitor@pam -role PulseMonitor + echo " • No additional privileges detected. Pulse may show limited VM metrics." fi echo "" diff --git a/internal/api/diagnostics.go b/internal/api/diagnostics.go index 43f4182..a826bf9 100644 --- a/internal/api/diagnostics.go +++ b/internal/api/diagnostics.go @@ -462,9 +462,9 @@ func (r *Router) checkVMDiskMonitoring(ctx context.Context, client *proxmox.Clie ) } else if strings.Contains(errStr, "403") || strings.Contains(errStr, "401") { result.Recommendations = append(result.Recommendations, - "Ensure API token has PVEAuditor role", - "For PVE 9: PVEAuditor includes VM.GuestAgent.Audit", - "For PVE 8: May need additional VM.Monitor permission", + "Ensure API token has PVEAuditor role for baseline access", + "Add VM.GuestAgent.Audit (PVE 9) or VM.Monitor (PVE 8) privileges; Pulse setup adds these via the PulseMonitor role", + "Include Sys.Audit when available for Ceph metrics", ) } else { result.Recommendations = append(result.Recommendations, @@ -492,9 +492,9 @@ func (r *Router) checkVMDiskMonitoring(ctx context.Context, client *proxmox.Clie } else if strings.Contains(errStr, "403") || strings.Contains(errStr, "401") { result.TestResult = "Permission denied accessing guest agent" result.Recommendations = append(result.Recommendations, - "Ensure API token has PVEAuditor role", - "For PVE 9: PVEAuditor includes VM.GuestAgent.Audit", - "For PVE 8: May need additional VM.Monitor permission") + "Ensure API token has PVEAuditor role for baseline access", + "Add VM.GuestAgent.Audit (PVE 9) or VM.Monitor (PVE 8) privileges; Pulse setup adds these via the PulseMonitor role", + "Include Sys.Audit when available for Ceph metrics") } else if errors.Is(err, context.DeadlineExceeded) || strings.Contains(errStr, "context deadline exceeded") { result.TestResult = "Guest agent request timed out" result.Recommendations = append(result.Recommendations, diff --git a/internal/monitoring/monitor.go b/internal/monitoring/monitor.go index 9ddef92..cf3a7c9 100644 --- a/internal/monitoring/monitor.go +++ b/internal/monitoring/monitor.go @@ -2820,11 +2820,15 @@ func (m *Monitor) pollVMsAndContainersEfficient(ctx context.Context, instanceNam log.Info(). Str("instance", instanceName). Str("vm", res.Name). - Msg("• Proxmox 9: Ensure token/user has PVEAuditor role (includes VM.GuestAgent.Audit)") + Msg("• Proxmox 9: Ensure token/user has VM.GuestAgent.Audit privilege (Pulse setup adds this via PulseMonitor role)") log.Info(). Str("instance", instanceName). Str("vm", res.Name). - Msg("• Proxmox 8: Ensure token/user has VM.Monitor permission") + Msg("• Proxmox 8: Ensure token/user has VM.Monitor privilege (Pulse setup adds this via PulseMonitor role)") + log.Info(). + Str("instance", instanceName). + Str("vm", res.Name). + Msg("• All versions: Sys.Audit is recommended for Ceph metrics and applied when available") log.Info(). Str("instance", instanceName). Str("vm", res.Name). @@ -3536,11 +3540,15 @@ func (m *Monitor) pollVMsWithNodes(ctx context.Context, instanceName string, cli log.Info(). Str("instance", instanceName). Str("vm", vm.Name). - Msg("• Proxmox 9: Ensure token/user has PVEAuditor role (includes VM.GuestAgent.Audit)") + Msg("• Proxmox 9: Ensure token/user has VM.GuestAgent.Audit privilege (Pulse setup adds this via PulseMonitor role)") log.Info(). Str("instance", instanceName). Str("vm", vm.Name). - Msg("• Proxmox 8: Ensure token/user has VM.Monitor permission") + Msg("• Proxmox 8: Ensure token/user has VM.Monitor privilege (Pulse setup adds this via PulseMonitor role)") + log.Info(). + Str("instance", instanceName). + Str("vm", vm.Name). + Msg("• All versions: Sys.Audit is recommended for Ceph metrics and applied when available") log.Info(). Str("instance", instanceName). Str("vm", vm.Name). diff --git a/scripts/test-vm-disk.sh b/scripts/test-vm-disk.sh index 182e82b..4e7dc18 100755 --- a/scripts/test-vm-disk.sh +++ b/scripts/test-vm-disk.sh @@ -129,8 +129,9 @@ Next steps: • If the guest agent is disabled, enable it in the VM Options tab (set "QEMU Guest Agent" to "Enabled"). • Inside the guest OS, ensure the qemu-guest-agent service is installed, running, and has access to disk information. • Verify the pulse_monitor@pam user (or your service account) has proper permissions: - - Proxmox 9: PVEAuditor role (includes VM.GuestAgent.Audit) - - Proxmox 8: VM.Monitor permission + - Proxmox 9: VM.GuestAgent.Audit privilege (Pulse setup adds via PulseMonitor role) + - Proxmox 8: VM.Monitor privilege (Pulse setup adds via PulseMonitor role) + - Sys.Audit is recommended for Ceph metrics and included when available - Both API tokens and passwords work fine for guest agent access Diagnostics complete.