Commit Graph

607 Commits

Author SHA1 Message Date
rcourtman 69c158b5bb fix: Switch proxy socket to directory-level bind mount for stability
Fixes LXC bind mount issue where socket-level mounts break when the
socket is recreated by systemd. Following Codex's recommendation to
bind mount the directory instead of the file.

Changes:
- Socket path: /run/pulse-temp-proxy/pulse-temp-proxy.sock
- Systemd: RuntimeDirectory=pulse-temp-proxy (auto-creates /run/pulse-temp-proxy)
- Systemd: RuntimeDirectoryMode=0770 for group access
- LXC mount: Bind entire /run/pulse-temp-proxy directory
- Install script: Upgrades old socket-level mounts to directory-level
- Install script: Detects and handles bind mount changes

This survives socket recreations and container restarts. The directory
mount persists even when systemd unlinks/recreates the socket file.

Related to #528
2025-10-12 22:33:53 +00:00
rcourtman 7917461b37 docs: Update temperature monitoring security notice for proxy architecture
Replaced outdated security warnings with accurate information about
the pulse-temp-proxy architecture:

- Removed scary 'legacy feature' and 'compromised container' warnings
- Explains secure proxy architecture for containerized deployments
- Notes that SSH keys are stored on Proxmox host (not in container)
- Clarifies container compromise does not expose credentials
- Includes information for both containerized and native installs
- More factual and less alarmist tone

The old message implied temperature monitoring was insecure for
containers, which is no longer true with pulse-temp-proxy.

Related to #528
2025-10-12 22:11:12 +00:00
rcourtman b93d8ef205 fix: Remove duplicate sshPublicKey argument in PVE setup script
The setup script generator was passing sshPublicKey twice but only
using it once, causing a Go fmt.Sprintf formatting error that leaked
into the generated bash script as '%!(EXTRA string=...)'.

This resulted in bash syntax errors when running the setup script.

Fixes #528
2025-10-12 22:01:16 +00:00
rcourtman cdaeeb1782 feat: Implement secure temperature proxy for containerized deployments
Addresses #528

Introduces pulse-temp-proxy architecture to eliminate SSH key exposure in containers:

**Architecture:**
- pulse-temp-proxy runs on Proxmox host (outside LXC/Docker)
- SSH keys stored on host filesystem (/var/lib/pulse-temp-proxy/ssh/)
- Pulse communicates via unix socket (bind-mounted into container)
- Proxy handles cluster discovery, key rollout, and temperature fetching

**Components:**
- cmd/pulse-temp-proxy: Standalone Go binary with unix socket RPC server
- internal/tempproxy: Client library for Pulse backend
- scripts/install-temp-proxy.sh: Idempotent installer for existing deployments
- scripts/pulse-temp-proxy.service: Systemd service for proxy

**Integration:**
- Pulse automatically detects and uses proxy when socket exists
- Falls back to direct SSH for native installations
- Installer automatically configures proxy for new LXC deployments
- Existing LXC users can upgrade by running install-temp-proxy.sh

**Security improvements:**
- Container compromise no longer exposes SSH keys
- SSH keys never enter container filesystem
- Maintains forced command restrictions
- Transparent to users - no workflow changes

**Documentation:**
- Updated TEMPERATURE_MONITORING.md with new architecture
- Added verification steps and upgrade instructions
- Preserved legacy documentation for native installs
2025-10-12 21:35:35 +00:00
rcourtman 3c4193c43a fix: Add security gates for containerized temperature monitoring
Addresses #528

- Added opt-in confirmation prompt to setup script with security notice
- Added runtime warning when containerized Pulse uses SSH temperature monitoring
- Documented security considerations and hardening recommendations
- Users must explicitly confirm understanding before enabling in containers
2025-10-12 21:01:25 +00:00
rcourtman b8ae1d681b fix: Setup script now verifies temperature SSH connectivity from Pulse
When Pulse runs in a container (LXC/Docker), the setup script would claim
temperature monitoring was enabled on cluster nodes, but Pulse couldn't
actually SSH to them. The script ran on the Proxmox host which could SSH
fine, but didn't verify connectivity from Pulse itself.

Changes:
- Added /api/system/verify-temperature-ssh endpoint that tests SSH from Pulse
- Setup script now calls this endpoint after configuring cluster nodes
- Detects when Pulse is containerized and provides ProxyJump config instructions
- Shows clear success/failure status for each node

Addresses #528
2025-10-12 20:36:48 +00:00
rcourtman d3ca954d0e fix: Prevent caching of Docker agent install script and binaries
Add no-cache headers to both the install script and agent binary download endpoints to prevent browsers and curl from serving stale cached versions. This ensures users always get the latest install script with URL normalization fixes for trailing slash issues.

Fixes #528
2025-10-12 18:04:57 +00:00
rcourtman d8638abea4 Fix node config API to preserve fields on partial updates
The PUT /api/config/nodes/{id} endpoint was corrupting node configurations
when making partial updates (e.g., updating just monitorPhysicalDisks):

- Authentication fields (tokenName, tokenValue, password) were being cleared
  when updating unrelated settings
- Name field was being blanked when not included in request
- Monitor* boolean fields were defaulting to false

Changes:
- Only update name field if explicitly provided in request
- Only switch authentication method when auth fields are explicitly provided
- Preserve existing auth credentials on non-auth updates
- Applied fix to all node types (PVE, PBS, PMG)

Also enables physical disk monitoring by default (opt-out instead of opt-in)
and preserves disk data between polling intervals.
2025-10-12 17:50:55 +00:00
rcourtman 8373e0af2f chore: bump version to v4.23.0 2025-10-12 16:35:48 +00:00
rcourtman a9377e20d6 Improve NVMe temperature handling 2025-10-12 16:06:55 +00:00
rcourtman e387648ef8 Use guest meminfo available for VM memory usage 2025-10-12 11:03:56 +00:00
rcourtman f97237cae7 Improve dashboard responsiveness and temperature handling 2025-10-12 10:34:06 +00:00
rcourtman 8701d8bb30 feat: capture Proxmox memory snapshots in diagnostics 2025-10-12 10:25:43 +00:00
rcourtman 8ac6641950 chore: bump version to v4.22.0 2025-10-11 22:45:06 +00:00
rcourtman 29e8b560be Handle GitHub update check rate limits 2025-10-11 22:41:32 +00:00
rcourtman abe3d22a5d Revert "chore: bump version to v4.22.0"
This reverts commit 44fa8b6b51274664e2c0a7cf49a0494d54f215bc.
2025-10-11 22:37:05 +00:00
rcourtman 6038067a23 chore: bump version to v4.22.0 2025-10-11 22:22:52 +00:00
rcourtman df70775066 docs: Update API docs and feature descriptions for Ceph, Docker, and updates 2025-10-11 22:21:51 +00:00
rcourtman 72aa60107d Enhance Docker page with simplified sidebar and focused metrics
Simplified host sidebar to show only essential monitoring info (name, status, alerts, container count). Moved detailed metrics (CPU, memory, uptime) to host detail view when selected to eliminate duplication. Added alert highlighting with visual indicators for hosts with container alerts. Fixed double 'v' prefix in agent version display.
2025-10-11 20:44:28 +00:00
rcourtman f783fef716 Fix frontend performance issues by caching system settings
Backend was loading system settings from disk on every HTTP request
causing massive log spam and UI responsiveness issues. System settings
are now cached at startup and reloaded only when updated.

Also fixed tab cursor showing text cursor instead of pointer cursor.

Changes:
- Cache system settings in Router struct with mutex protection
- Load settings once at startup instead of on every request
- Add reloadSystemSettings() method to refresh cache when settings change
- Hook up cache reload in config handlers after successful save
- Add cursor-pointer to tab CSS classes for proper hover cursor
2025-10-11 17:22:22 +00:00
rcourtman 9c21d86212 Add multi-target Docker agent support and update installer 2025-10-11 16:34:33 +00:00
rcourtman 6e6d2dec6c Add quiet hours category suppression 2025-10-11 13:23:27 +00:00
rcourtman 11e80bbcbb chore: bump version to v4.22.0-rc.6 2025-10-11 12:44:33 +00:00
rcourtman 1ffcfbeaf6 Guard storage backups from failed polls 2025-10-11 10:00:05 +00:00
rcourtman 96b6454463 Sync alert configuration updates 2025-10-11 07:36:54 +00:00
rcourtman d7cc972265 Improve LXC disk usage reporting 2025-10-11 07:35:44 +00:00
rcourtman 80b4f50532 fix: improve update experience and handle missing releases gracefully
Backend:
- Handle 'no releases found' error gracefully instead of returning 500
- Return proper response indicating no updates available for the channel
- Fixes the 500 error when checking for updates on development versions

Frontend:
- Detect when backend enters 'restarting' phase during updates
- Show 'Pulse is restarting...' message instead of getting stuck on 'Initializing...'
- Implement health check polling with exponential backoff (2s → 15s max)
- Auto-reload page when backend becomes healthy again
- Improve messaging: inform users page will reload automatically

This fixes the stuck update modal issue where users would see
'Initializing...' forever when the backend restarted during updates.
2025-10-10 21:31:36 +00:00
rcourtman b250febcdd refactor: remove update history tracking from Manager
The update history infrastructure (history.go, UI panel) already exists
and is used by InstallShAdapter. However, for a home lab monitoring tool,
tracking every update in the Manager is overkill.

Removed:
- History field and initialization from Manager
- Event tracking in ApplyUpdate function
- Update history population on success/failure

The history.go file and UI panel remain for InstallShAdapter usage,
but the main Manager update path is now simpler and more focused.
2025-10-10 20:43:25 +00:00
rcourtman f05f47f935 fix: comprehensive update system improvements
Fixed 12 critical issues in the update system:

Critical bugs:
- Cache invalidation when channel auto-detected vs explicitly provided
- Data race on cache access (added proper RWMutex locking)
- Incorrect error handling when already on latest version

Security improvements:
- Command injection prevention with version string validation
- Symlink vulnerabilities in backup/restore (replaced cp with safe Go implementations)
- SHA256 checksum verification for downloads
- Improved backup completeness (now includes binary and VERSION file)

Quality improvements:
- Channel-keyed cache map instead of single cache value
- Update history tracking with event IDs and rollback support
- Cleanup of old temp directories (24+ hours)
- Proper resource cleanup with Close() method
2025-10-10 20:35:11 +00:00
rcourtman fe1518457a fix: auto-detect update channel from current version and add background checker
- Auto-detect update channel from current version when config is empty
  (RC users automatically get RC updates, stable users get stable)
- Add background update checker that runs on startup and hourly
- Add GetCachedUpdateInfo() method to return cached update info
- Update /api/version endpoint to include updateAvailable from cache
- Fixes issue where RC users on rc.4 weren't seeing rc.5 updates

This ensures RC testers continue receiving RC notifications while
stable users stay on the stable channel, all without explicit config.
2025-10-10 19:46:52 +00:00
rcourtman 64df42c62c chore: bump version to v4.22.0-rc.5 2025-10-10 19:07:09 +00:00
rcourtman 3ad41829ab revert: undo version bump to 4.22.0-rc.5 2025-10-10 18:51:15 +00:00
rcourtman 07d9e389bd chore: bump version to v4.22.0-rc.5 2025-10-10 18:43:15 +00:00
rcourtman d6e61e73ec fix: resolve Docker container permission and path errors in v4.22.0-rc.4
- Fix update history using hardcoded /var/lib/pulse instead of configured data dir
- Skip mock.env watching in Docker environments to avoid 'no such file' errors

Fixes issue #529

Update History Path:
- Modified NewUpdateHandlers to accept dataDir parameter
- Pass r.config.DataPath from router (honors PULSE_DATA_DIR=/data in Docker)
- Maintains backward compatibility with default /var/lib/pulse when empty

Mock Env Watcher:
- Check PULSE_DOCKER env var and skip mock.env watching if true
- Only watch /opt/pulse/mock.env if directory exists (not in containers)
- Guard all mock.env operations to prevent errors when path is empty
- Clean up log messages to only show mock_env_path when actually watching
2025-10-10 18:17:38 +00:00
rcourtman 81f96537e2 fix: resolve docker-agent-install 401 error from trailing slash in PULSE_URL
- Strip trailing slash from PULSE_URL in install script to prevent double-slash URLs
- Add path normalization in router for defense-in-depth on public endpoint matching
- Fixes issue #528 where users copying URLs with trailing slashes got 401 errors

The install script now normalizes PULSE_URL with ${PULSE_URL%/} before concatenating
with /download/pulse-docker-agent, preventing https://example.com//download URLs.

The router normalization provides additional resilience for path matching, though the
existing path traversal check already blocks double slashes at ServeHTTP level.
2025-10-10 18:09:55 +00:00
rcourtman 91222face7 fix: comprehensive Docker agent token security improvements
This commit addresses 6 critical security and UX issues in Docker agent
token handling identified through code review:

**High Priority Fixes:**
1. Fix stale token in command preview - Changed DockerAgents to use
   getInstallCommandTemplate() that always returns placeholder, allowing
   CommandBuilder to handle all token substitution reactively. Command
   preview now updates live as user types.

2. Fix misleading "multiple tokens" messaging - Updated token generation
   modal to accurately reflect single-token backend model with red warning:
   "This will immediately invalidate your existing token". Prevents operators
   from unknowingly breaking active Docker agents.

3. Close proxy auth bypass vulnerability - Both HandleRegenerateAPIToken
   and HandleValidateAPIToken now explicitly reject requests when proxy auth
   is configured but validation fails (returns 401). Prevents unauthenticated
   access when proxy auth is enabled.

**Medium Priority Fixes:**
4. Disable buttons when no stored token - "Use This Token" and "Copy" buttons
   now properly disabled with contextual tooltips when browser hasn't saved
   a token, eliminating confusing silent no-ops.

5. Improve frontend error handling - Token validation now distinguishes
   between authentication errors (401/403), rate limiting (429), network
   failures, and actual invalid tokens. No longer mislabels auth failures
   as "invalid token".

**Low Priority Fixes:**
6. Add authentication to validate-token endpoint - Endpoint now requires
   admin authentication (same as regenerate-token), preventing unauthenticated
   token guessing oracle despite rate limiting.

**New Component:**
- CommandBuilder.tsx: Interactive command builder with live preview,
  state-based visual cues, inline token generation, and validation

**Security Impact:**
- Closes unauthenticated validation surface
- Enforces proper proxy auth gating
- Prevents accidental exposure of security model
- Rate limiting maintained (10 attempts/min)

**UX Impact:**
- Clear, accurate error messages
- Live-updating command preview
- Contextual token management
- Disabled states prevent confusion

Reviewed and verified by both Claude Code and Codex with no regressions found.
2025-10-10 17:54:53 +00:00
rcourtman a1649d2e03 fix: resolve test failures and TypeScript errors
- Add missing postfix queue endpoint to PMG test mock server
- Add 'pmg' to DiscoveredServer type in Settings.tsx
- Fix potentially undefined object in UpdateBanner.tsx
- Remove unused imports and variables in Dashboard.tsx, MailGateway.tsx, NodeSummaryTable.tsx
2025-10-10 16:08:09 +00:00
rcourtman 3aa8e387e4 chore: bump version to v4.22.0-rc.4 2025-10-10 16:04:27 +00:00
rcourtman 5294ed8e4e feat: integrate update system with API endpoints
Wire up the adapter-based update system to HTTP API:

**Enhanced UpdateHandlers:**
- Initialize UpdateHistory and UpdaterRegistry
- Register all deployment adapters (systemd, proxmoxve, docker, aur)
- Handlers now have access to history and updater registry

**New API Endpoints:**
- GET /api/updates/plan?version=X - Get update plan for deployment
  * Returns canAutoUpdate, instructions, prerequisites, estimated time
  * Deployment-specific based on detected type
- GET /api/updates/history?limit=N&status=X - List update history
  * Supports filtering by status (success/failed/in_progress)
  * Returns audit log entries with full metadata
- GET /api/updates/history/entry?id=X - Get specific history entry
  * Retrieve detailed information about past update

**Existing Endpoints Still Work:**
- GET /api/updates/check - Check for available updates
- POST /api/updates/apply - Apply update (legacy manager)
- GET /api/updates/status - Get current update status

The system now supports both:
- Legacy update flow (existing install.sh wrapper in manager.go)
- New adapter-based flow (prepared for frontend integration)

Next: Frontend components to consume new endpoints.
2025-10-10 15:42:21 +00:00
rcourtman 2408d8004c feat: add update system foundation with adapter pattern
Add infrastructure for deployment-agnostic update management:

**Update History (Audit Log):**
- JSONL-based audit log (/var/lib/pulse/update-history.jsonl)
- Tracks all update attempts with full metadata
- In-memory cache for fast queries
- Schema designed for future DB migration

**Updater Interface:**
- Defines contract for deployment-specific update logic
- SupportsApply(), PrepareUpdate(), Execute(), Rollback()
- Registry pattern for managing multiple adapters
- Progress callbacks for real-time UI updates

**Adapters Implemented:**
- InstallShAdapter: Wraps install.sh (systemd/LXC)
  * Full automation support
  * Captures stdout/stderr to log files
  * Parses backup paths from output
  * Maintains install.sh as single source of truth
- DockerUpdater: Instruction-only (manual)
- AURUpdater: Instruction-only (package manager)

Key design decisions:
- install.sh remains unchanged (backward compatible)
- All update mechanisms funnel through adapters
- Audit log records all updates (manual + automated)
- Thin wrapper approach - no logic duplication

Next: Wire up API endpoints and frontend integration.
2025-10-10 15:39:47 +00:00
rcourtman fb21f4c909 feat: add version-aware update notifications for RC releases
Implement smart update checking that shows appropriate updates based on user's current version:
- RC users now see both newer RC releases AND newer stable releases
- Stable users continue to see only stable releases (RCs filtered out)
- Both channels use version-aware filtering (only show updates > current version)

Key changes:
- Modified getLatestReleaseForChannel to accept currentVer parameter
- Removed /releases/latest shortcut; both channels now fetch all releases
- RC channel tracks both newest RC and newest stable, returns highest
- Stable channel filters prereleases and returns first stable > currentVer
- Added comprehensive test suite with 15 test cases

Respects semver ordering where 4.22.0 > 4.22.0-rc.3 per RFC.

Consulted with Codex for architectural direction.
2025-10-10 15:20:34 +00:00
rcourtman 30fa3fd810 feat: add complete Proxmox Mail Gateway (PMG) monitoring support
Add comprehensive PMG monitoring with mail statistics, queue depth tracking,
spam distribution analysis, and quarantine monitoring. Includes full discovery
support and UI consistency improvements across all Proxmox products.

Backend:
- Add pkg/pmg package with complete API client for PMG operations
- Implement mail statistics collection (inbound/outbound, spam, virus, bounces)
- Add queue depth monitoring (active, deferred, hold, incoming queues)
- Support spam score distribution and quarantine totals
- Add PMG-specific discovery logic to differentiate from PVE on port 8006
- Extend mock data generator with realistic PMG instances and metrics
- Add PMG node configuration support in config system

Frontend:
- Create MailGateway.tsx component with detailed PMG dashboard
- Display mail flow statistics with time-series charts
- Show queue depth with color-coded warnings (>50 messages or >30min age)
- Add spam distribution histogram and quarantine status
- Support cluster node status with individual queue monitoring
- Add PMG to network discovery with purple branding and mail icon
- Implement conditional navigation (hide PMG tab when no instances configured)
- Standardize discovery UI controls across PVE/PBS/PMG settings pages

API:
- Add /api/config/pmg endpoints for node configuration
- Support PMG-specific monitoring toggles (mail stats, queues, quarantine)
- Extend system settings with PMG configuration options

Discovery:
- Detect PMG vs PVE on shared port 8006 using /api2/json/statistics/mail endpoint
- Return 'pmg' type for mail gateway servers in discovery results
- Update DiscoveryModal to display PMG servers with appropriate styling

This completes ecosystem monitoring support for all three Proxmox products:
Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
2025-10-10 14:30:51 +00:00
rcourtman ba7a1df8aa chore: bump version to v4.22.0-rc.3 2025-10-09 23:24:03 +00:00
rcourtman 7427a75117 feat: support standard Authorization header for API authentication
Add support for Authorization: Bearer <token> header as a fallback
for environments that strip custom headers like X-API-Token. Docker
agent now sends both headers for maximum compatibility.
2025-10-09 23:03:46 +00:00
rcourtman 95f99767e5 Surface shared storage on all nodes refs #522 2025-10-09 22:55:27 +00:00
rcourtman 53012f73ca Improve snapshot polling resiliency 2025-10-09 22:13:06 +00:00
rcourtman 6e3c77b609 fix: properly fix test and remove unused variables
- Bypass UpdateConfig in test to allow TimeThreshold=0
- Remove unused helper functions and variables completely
2025-10-09 16:20:56 +00:00
rcourtman 75ac4d6699 fix: resolve test failures and unused variables
- Fix TestAcknowledgePersistsThroughCheckMetric by setting TimeThreshold to 0
- Prefix unused variables with underscore in ThresholdsTable.tsx
2025-10-09 16:18:45 +00:00
rcourtman 44f52b5718 chore: bump version to v4.22.0-rc.2 2025-10-09 16:16:10 +00:00
rcourtman 667590519a feat: add per-metric alert delay configuration
Add sophisticated alert delay system with per-metric overrides:
- Global delay defaults per resource type (guest/node/storage/pbs)
- Per-metric delay overrides with UI controls
- Dynamic tooltips showing effective delay values
- Clear buttons to reset metric-specific overrides
- Temperature threshold defaults for nodes (80°C/75°C)
- Improved delay configuration persistence and normalization
2025-10-09 16:14:39 +00:00