Commit Graph

99 Commits

Author SHA1 Message Date
rcourtman c39ee99529 feat: add shared script library system and refactor docker-agent installer
Implements a comprehensive script improvement infrastructure to reduce code
duplication, improve maintainability, and enable easier testing of installer
scripts.

## New Infrastructure

### Shared Library System (scripts/lib/)
- common.sh: Core utilities (logging, sudo, dry-run, cleanup management)
- systemd.sh: Service management helpers with container-safe systemctl
- http.sh: HTTP/download helpers with curl/wget fallback and retry logic
- README.md: Complete API documentation for all library functions

### Bundler System
- scripts/bundle.sh: Concatenates library modules into single-file installers
- scripts/bundle.manifest: Defines bundling configuration for distributables
- Enables both modular development and curl|bash distribution

### Test Infrastructure
- scripts/tests/run.sh: Test harness for running all smoke tests
- scripts/tests/test-common-lib.sh: Common library validation (5 tests)
- scripts/tests/test-docker-agent-v2.sh: Installer smoke tests (4 tests)
- scripts/tests/integration/: Container-based integration tests (5 scenarios)
- All tests passing ✓

## Refactored Installer

### install-docker-agent-v2.sh
- Reduced from 1098 to 563 lines (48% code reduction)
- Uses shared libraries for all common operations
- NEW: --dry-run flag support
- Maintains 100% backward compatibility with original
- Fully tested with smoke and integration tests

### Key Improvements
- Sudo escalation: 100+ lines → 1 function call
- Download logic: 51 lines → 1 function call
- Service creation: 33 lines → 2 function calls
- Logging: Standardized across all operations
- Error handling: Improved with common library

## Documentation

### Rollout Strategy (docs/installer-v2-rollout.md)
- 3-phase rollout plan (Alpha → Beta → GA)
- Feature flag mechanism for gradual deployment
- Testing checklist and success metrics
- Rollback procedures and communication plan

### Developer Guides
- docs/script-library-guide.md: Complete library usage guide
- docs/CONTRIBUTING-SCRIPTS.md: Contribution workflow
- docs/installer-v2-quickref.md: Quick reference for operators

## Metrics

- Code reduction: 48% (1098 → 563 lines)
- Reusable functions: 0 → 30+
- Test coverage: 0 → 8 test scenarios
- Documentation: 0 → 5 comprehensive guides

## Testing

All tests passing:
- Smoke tests: 2/2 passed (8 test cases)
- Integration tests: 5/5 scenarios passed
- Bundled output: Syntax validated, dry-run tested

## Next Steps

This lays the foundation for migrating other installers (install.sh,
install-sensor-proxy.sh) to use the same pattern, reducing overall
maintenance burden and improving code quality across the project.
2025-10-20 15:13:38 +00:00
rcourtman 659575c1ce feat: implement priority queue-based task execution (Phase 2 Task 6)
Replaces immediate polling with queue-based scheduling:
- TaskQueue with min-heap (container/heap) for NextRun-ordered execution
- Worker goroutines that block on WaitNext() until tasks are due
- Tasks only execute when NextRun <= now, respecting adaptive intervals
- Automatic rescheduling after execution via scheduler.BuildPlan
- Queue depth tracking for backpressure-aware interval adjustments
- Upsert semantics for updating scheduled tasks without duplicates

Task 6 of 10 complete (60%). Ready for error/backoff policies.
2025-10-20 15:13:37 +00:00
rcourtman a66e5d04d5 feat: verify adaptive interval logic implementation (Phase 2 Task 5)
Confirms adaptive scheduling logic is fully operational:
- EMA smoothing (alpha=0.6) to prevent interval oscillations
- Staleness-based interpolation between min/max intervals
- Error penalty (0.6x per error) for faster recovery detection
- Queue depth stretch (0.1x per task) for backpressure handling
- ±5% jitter to prevent thundering herd effects
- Per-instance state tracking for smooth transitions

Task 5 of 10 complete. Scheduler foundation ready for queue-based execution.
2025-10-20 15:13:37 +00:00
rcourtman 8dc5c4758e security: complete Phase 1 sensor proxy hardening
Implements comprehensive security hardening for pulse-sensor-proxy:
- Privilege drop from root to unprivileged user (UID 995)
- Hash-chained tamper-evident audit logging with remote forwarding
- Per-UID rate limiting (0.2 QPS, burst 2) with concurrency caps
- Enhanced command validation with 10+ attack pattern tests
- Fuzz testing (7M+ executions, 0 crashes)
- SSH hardening, AppArmor/seccomp profiles, operational runbooks

All 27 Phase 1 tasks complete. Ready for production deployment.
2025-10-20 15:13:37 +00:00
rcourtman bc2f643b0e feat: add user-friendly explanation for socket bind mount
Added clear messaging to explain why the socket bind mount is configured,
focusing on the security benefits rather than technical implementation.

Changes:
- Add explanatory header "Secure Container Communication Setup"
- Explain the three key benefits:
  • Container communicates via Unix socket (not SSH)
  • No SSH keys exposed inside container (enhanced security)
  • Proxy on host manages all temperature collection
- Update technical messages to be more user-friendly:
  • "Configuring socket bind mount" instead of "Ensuring..."
  • "Restarting container to activate secure communication"
  • "Verifying secure communication channel"
  • "✓ Secure socket communication ready"
  • "Configuring Pulse to use proxy"

This helps users understand WHY the bind mount exists (security) rather
than just seeing technical implementation details.
2025-10-19 16:22:03 +00:00
rcourtman 4b0e113b67 fix: automatically restart container when proxy mount is configured
Instead of warning the user to restart the container manually, the script
now automatically restarts it when the socket mount configuration is
updated. This ensures the mount is immediately active and temperature
monitoring works right away without user intervention.

Uses 'pct restart' if running, 'pct start' if stopped.
2025-10-19 15:56:31 +00:00
rcourtman 3296c5e26f fix: fall back to Pulse server when GitHub download fails for pulse-sensor-proxy
The install-sensor-proxy.sh script now tries GitHub releases first, then falls
back to downloading from the Pulse server if GitHub fails or doesn't have the
binary (common when building from main).

The LXC installer sets PULSE_SENSOR_PROXY_FALLBACK_URL to point to the Pulse
server running inside the newly created LXC, ensuring the proxy binary can be
downloaded from /api/install/pulse-sensor-proxy.

This fixes the issue where installing with --main would fail to install
pulse-sensor-proxy on the host because GitHub releases don't include it yet.
2025-10-19 15:17:59 +00:00
rcourtman eb969bfbd5 feat: add turnkey Docker installer with automatic proxy setup
Adds a one-command Docker deployment flow that:
- Detects if running in LXC and installs Docker if needed
- Automatically installs pulse-sensor-proxy on the Proxmox host
- Configures bind mount for proxy socket into LXC
- Generates optimized docker-compose.yml with proxy socket
- Enables temperature monitoring via host-side proxy

The install-docker.sh script handles the complete setup including:
- Docker installation (if needed)
- ACL configuration for container UIDs
- Bind mount setup
- Automatic apparmor=unconfined for socket access

Accessible via: curl -sSL http://pulse:7655/api/install/install-docker.sh | bash
2025-10-19 15:03:24 +00:00
Pulse Automation Bot c3becc5272 Add Helm chart tooling, CI, and release packaging 2025-10-18 11:50:57 +00:00
Richard Courtman 74663d8cf7 fix: gracefully handle standalone node cleanup limitation
- Cleanup script now detects forced command restriction on standalone nodes
- Logs helpful message explaining limitation (security by design)
- Does not fail when standalone nodes cannot be cleaned up
- Documents that standalone node cleanup is limited by forced command security
- Automatic cleanup works fully for cluster nodes
- Manual cleanup command provided for standalone nodes if needed
2025-10-18 07:34:18 +00:00
Richard Courtman 8500c24dec fix: use proxy SSH key for cleanup of standalone nodes
- Cleanup script now tries proxy's SSH key first for standalone nodes
- Falls back to default SSH if proxy key not available
- Fixes cleanup failure when Proxmox host doesn't have direct SSH to standalone nodes
2025-10-18 07:27:15 +00:00
Richard Courtman ea1db9ed33 feat: add automatic SSH key cleanup when nodes are removed
- Create cleanup script that removes Pulse SSH keys from nodes
- Add systemd path unit to watch for cleanup requests
- Add systemd service to execute cleanup script
- Update install-sensor-proxy.sh to install cleanup system
- Handles both cluster nodes (pulse-managed-key) and standalone nodes (pulse-proxy-key)
- Cleanup is triggered automatically when nodes are deleted from Pulse
- All cleanup actions are logged via syslog for auditability
2025-10-18 07:03:05 +00:00
Richard Courtman e68015507a feat: add turnkey temperature monitoring for standalone nodes
Implements automatic temperature monitoring setup for standalone
Proxmox/Pimox nodes without manual SSH key configuration.

Changes:
- Add /api/system/proxy-public-key endpoint to expose proxy's SSH public key
- Setup script now detects standalone nodes (non-cluster)
- Auto-fetches and installs proxy SSH key with forced commands
- Add Raspberry Pi temperature support via cpu_thermal and /sys/class/thermal
- Enhance setup script with better error handling for lm-sensors installation
- Add RPi detection to skip lm-sensors and use native thermal interface

Security:
- Public key endpoint is safe (public keys are meant to be public)
- All installed keys use forced command="sensors -j" with full restrictions
- No shell access, port forwarding, or other SSH features enabled
2025-10-17 22:15:50 +00:00
rcourtman 018a1eaf2b fix: improve sensor proxy install script reliability
Fixes two issues with the sensor proxy installation:
1. Local node IP detection now uses exact matching instead of substring matching to avoid false negatives
2. Removes duplicate output filtering in the setup script wrapper

These changes ensure that the proxy SSH key is correctly configured on the local node during cluster installations.
2025-10-17 19:09:54 +00:00
rcourtman 0cd4599332 feat: add comprehensive node cleanup system
Implements automated cleanup workflow when nodes are deleted from Pulse, removing all monitoring footprint from the host. Changes include a new RPC handler in the sensor proxy for cleanup requests, enhanced node deletion modal with detailed cleanup explanations, and improved SSH key management with proper tagging for atomic updates.
2025-10-17 18:53:45 +00:00
rcourtman 38586fa17f fix: remove reference to deleted 'Ensure cluster keys' button in installer
The button was removed in previous commit, update error message to suggest
re-running the script instead.
2025-10-17 14:11:50 +00:00
rcourtman 2b6b596aa7 feat: enhance sensor proxy with improved cluster discovery and SSH management
Improvements to pulse-sensor-proxy:
- Fix cluster discovery to use pvecm status for IP addresses instead of node names
- Add standalone node support for non-clustered Proxmox hosts
- Enhanced SSH key push with detailed logging, success/failure tracking, and error reporting
- Add --pulse-server flag to installer for custom Pulse URLs
- Configure www-data group membership for Proxmox IPC access

UI and API cleanup:
- Remove unused "Ensure cluster keys" button from Settings
- Remove /api/diagnostics/temperature-proxy/ensure-cluster-keys endpoint
- Remove EnsureClusterKeys method from tempproxy client

The setup script already handles SSH key distribution during initial configuration,
making the manual refresh button redundant.
2025-10-17 11:43:26 +00:00
rcourtman f8ed75a8a0 Add guest agent caching and update doc hints (refs #560) 2025-10-16 08:15:49 +00:00
rcourtman 1b362efbd5 feat: add docker agent command handling 2025-10-15 19:27:19 +00:00
rcourtman 4838453305 Improve docker agent installer path handling 2025-10-14 16:39:30 +00:00
rcourtman bcfdf5d121 Adopt multi-token auth across docs, UI, and tooling 2025-10-14 15:47:49 +00:00
rcourtman 3860d565f2 Automate sensor proxy container mount and auth 2025-10-14 12:41:48 +00:00
rcourtman db1cfc75af Update Proxmox guest agent permissions docs and tooling (refs #548) 2025-10-14 10:21:52 +00:00
rcourtman 039a4d89fa feat: streamline docker agent onboarding 2025-10-14 09:45:32 +00:00
rcourtman 7fa01cafa6 polish: Clean up setup script output for professional presentation
Made the setup and installation output more concise and reassuring for users. Less verbosity, clearer messaging.

**Setup script improvements:**
- Changed "Container Detection" → "Enhanced Security"
- Simplified prompts: "Enable secure proxy? [Y/n]"
- Cleaned up success messages: "✓ Secure proxy architecture enabled"
- Removed verbose status messages (node-by-node cleanup output)
- Only show essential information users need to see

**install-sensor-proxy.sh improvements:**
- Added --quiet flag to suppress verbose output
- In quiet mode, only shows: "✓ pulse-sensor-proxy installed and running"
- Full output still available when run manually
- Removed redundant "Installation complete!" banners
- Cleaner legacy key cleanup messaging

**Result:**
Users see a clean, professional installation flow that builds confidence. Technical details are hidden unless needed. Messages are clear and reassuring rather than verbose.
2025-10-13 13:51:17 +00:00
rcourtman 71c5ee6e8a feat: Auto-cleanup legacy SSH keys when migrating to proxy
When pulse-sensor-proxy is installed, automatically remove old SSH keys that were stored in the container for security.

Changes:

**install-sensor-proxy.sh:**
- Checks container for SSH private keys (id_rsa, id_ed25519, etc.)
- Removes any found keys from container
- Warns user that legacy keys were cleaned up
- Explains proxy now handles SSH

**Setup script (config_handlers.go):**
- After successful proxy install, removes old SSH keys from all cluster nodes
- Cleans up authorized_keys entries that match the old container-based key
- Keeps only proxy-managed keys (pulse-sensor-proxy comment)

This provides a clean migration path from the old direct-SSH method to the secure proxy architecture. Users upgrading from pre-v4.24 versions get automatic cleanup of insecure container-stored keys.
2025-10-13 13:47:19 +00:00
rcourtman eb7272582e refactor: Rename install-temp-proxy.sh to install-sensor-proxy.sh
Complete the pulse-sensor-proxy rename by updating the installer script name and all references to it.

Updated:
- Renamed scripts/install-temp-proxy.sh → scripts/install-sensor-proxy.sh
- Updated all documentation references
- Updated install.sh references
- Updated build-release.sh comments
2025-10-13 13:23:53 +00:00
rcourtman ce499245a0 refactor: Rename pulse-temp-proxy to pulse-sensor-proxy
The name "temp-proxy" implied a temporary or incomplete implementation. The new name better reflects its purpose as a secure sensor data bridge for containerized Pulse deployments.

Changes:
- Renamed cmd/pulse-temp-proxy/ to cmd/pulse-sensor-proxy/
- Updated all path constants and binary references
- Renamed environment variables: PULSE_TEMP_PROXY_* to PULSE_SENSOR_PROXY_*
- Updated systemd service and service account name
- Updated installation, rotation, and build scripts
- Renamed hardening documentation
- Maintained backward compatibility for key removal during upgrades
2025-10-13 13:17:05 +00:00
rcourtman 61078e697b fix: Change RuntimeDirectoryMode to 0775 for container access
The pulse user in the container (UID 1001) needs to access the
/run/pulse-temp-proxy directory owned by root:root. Changed from
0770 (owner+group only) to 0775 (add world read+execute) so the
pulse user can access the socket.

Related to #528
2025-10-12 22:39:18 +00:00
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 ae2ed00744 feat: Add --local-binary flag to install-temp-proxy.sh for pre-release testing
Allows testing the proxy installation with a locally-built binary instead
of requiring a GitHub release. This enables proper E2E testing before
shipping a release.

Usage:
  ./install-temp-proxy.sh --ctid 112 --local-binary /path/to/pulse-temp-proxy

The script will:
- Use the provided binary instead of downloading from GitHub
- Still handle all setup (systemd service, SSH keys, bind mounts)
- Allow full integration testing without a release

This solves the chicken-and-egg problem of needing a release to test
the installation process.

Related to #528
2025-10-12 22:25:49 +00:00
rcourtman a580ca0cf9 build: Add pulse-temp-proxy to release build process
Updates build script and release checklist to include pulse-temp-proxy binaries:
- Build pulse-temp-proxy for all architectures (amd64, arm64, armv7)
- Include in tarballs alongside pulse and pulse-docker-agent
- Copy standalone binaries to release/ for install-temp-proxy.sh
- Update release checklist to upload standalone binaries as assets

This ensures install-temp-proxy.sh can download binaries from GitHub releases.
2025-10-12 21:46:48 +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 29d98ad010 Fix docker agent installer for BusyBox wget (#255) 2025-10-12 10:57:19 +00:00
rcourtman 8701d8bb30 feat: capture Proxmox memory snapshots in diagnostics 2025-10-12 10:25:43 +00:00
rcourtman 4ad53f27fe Implement data isolation between mock and production modes
Adds automatic data directory separation to prevent mock data from contaminating production alerts and configuration:

- hot-dev.sh: Explicitly sets PULSE_DATA_DIR based on PULSE_MOCK_MODE
  - Production: /etc/pulse (real, persistent data)
  - Mock: /opt/pulse/tmp/mock-data (isolated, throwaway data)
- clean-mock-alerts.sh: New utility to remove mock contamination from production alerts
- Auto-creates mock data directory when switching to mock mode

This prevents issues where mock alerts appear in production alert history after switching between modes.
2025-10-11 19:09:15 +00:00
rcourtman 26e52b531e Add success icon and fix mock/production data separation
Add green checkmark icon to "No active alerts" empty state for better visual feedback. Separate mock and production data directories to prevent contamination. Mock mode now uses /opt/pulse/tmp/mock-data while production uses /etc/pulse. Update toggle script to dynamically set data directory based on mode.
2025-10-11 18:43:13 +00:00
rcourtman 9c21d86212 Add multi-target Docker agent support and update installer 2025-10-11 16:34:33 +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 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 bf1e1ecaff chore: prepare v4.22.0-rc.1 2025-10-08 16:52:06 +00:00
rcourtman 5693560ddd Improve powered-off alerts toggle layout and fix dev config sync
- Consolidate powered-off alerts toggle into single compact row
- Fix encryption key mismatch between dev and production environments
- Always sync production encryption key to prevent decryption errors
- Add sync command to toggle-mock.sh for manual config updates
2025-10-05 20:17:47 +00:00
rcourtman bb312ed022 Add Docker monitoring integration with agent-based architecture
Implements comprehensive Docker monitoring with a dedicated agent that collects
container metrics and reports them to the main Pulse server. Adds Docker-specific
alert rules and threshold management with a redesigned UI.

Backend changes:
- Add Docker agent binary with container metrics collection
- Implement Docker host and container models with CPU/memory tracking
- Add Docker-specific alert types (offline, state, health)
- Extend threshold system to support Docker resources
- Add WebSocket message types for Docker agent communication
- Implement Docker agent API endpoints for registration and metrics

Frontend changes:
- Add Docker monitoring page with host/container views
- Add Docker agent settings panel for configuration
- Reorganize thresholds page with Proxmox/Docker tabs
- Add Docker-specific alert threshold management
- Improve layout consistency with vertical stacking
- Fix defensive null checks and TypeScript errors

This change enables monitoring of Docker containers across multiple hosts
with the same alerting and threshold capabilities as Proxmox resources.
2025-10-05 17:51:16 +00:00
rcourtman d9079f7bbb Refine dashboard disk column layout 2025-10-02 12:08:19 +00:00
rcourtman ad10d43542 refactor: create reusable NodeGroupHeader component and improve styling
- 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
2025-10-02 08:29:29 +00:00
rcourtman 49311b1e39 fix: resolve multiple issues from #485
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
2025-10-01 15:53:42 +00:00
rcourtman 1c2431fcf6 refactor: add mock.env to repository with local override support
Make mock mode configuration part of the repository instead of a local-only
file. This ensures consistent mock mode behavior across all environments
(development, CI/CD, demo server) and makes it work out of the box for
new contributors.

Changes:
- Add mock.env to repository with sensible defaults (mock mode OFF by default)
- Support mock.env.local for personal overrides (gitignored)
- Update .gitignore to allow mock.env but exclude .local variants
- Backend loads mock.env then merges mock.env.local overrides
- hot-dev.sh loads both files in correct order

Benefits:
- New developers can clone and use mock mode immediately
- Demo server gets consistent mock configuration
- Personal preferences stay private in .local file
- No surprises - mock mode disabled by default in fresh clones
- CI/CD can use mock mode without custom configuration

Documentation:
- Updated README.md to explain mock.env is in repo
- Enhanced MOCK_MODE.md with local override instructions
- Updated claude.md with new configuration strategy
- Added mock.env.local.example for quick setup

Example workflow:
  git clone <repo>
  npm run mock:on        # Works immediately with repo defaults
  # Or create personal config:
  cp docs/development/mock.env.local.example mock.env.local
  # Edit mock.env.local with your preferences
2025-10-01 13:38:39 +00:00
rcourtman 6f2b6268a4 perf: optimize mock mode state retrieval and JSON encoding
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
2025-10-01 13:35:49 +00:00
rcourtman 67fc5977d1 feat: add hot-reloadable mock mode with auto-detection
Implement a hot-reloadable mock mode system that works seamlessly in both
development and production environments without requiring manual restarts
or port changes.

Key Features:
- Backend watches mock.env and auto-reloads when changed (via fsnotify + polling)
- npm commands for easy toggling: mock:on, mock:off, mock:status, mock:edit
- Works in both hot-dev mode and systemd deployments
- Reload completes in 2-5 seconds with no manual intervention
- No port changes or process restarts required

Implementation:
- Extended ConfigWatcher to monitor both .env and mock.env
- Added callback system to trigger ReloadableMonitor.Reload()
- Enhanced toggle-mock.sh to support both hot-dev and systemd modes
- Updated hot-dev.sh banner to show mock status and commands
- Created comprehensive documentation in docs/development/MOCK_MODE.md

Testing:
- Backend builds successfully
- Watcher initializes and monitors both files
- npm run mock:on/off toggles successfully
- mock.env updates correctly
- Scripts work in both hot-dev and systemd modes

Documentation:
- Added Mock Mode section to README.md
- Created detailed guide in docs/development/MOCK_MODE.md
- Updated claude.md with mock mode architecture and usage

Mock mode continues to return cached data instantly from memory
(no API calls, no locks, no timeouts), ensuring fast /api/state responses.
2025-10-01 13:35:17 +00:00
rcourtman ec1d8b3303 fix: ensure PULSE_DATA_DIR is exported in dev mode and improve sync validation
Additional safeguards to prevent dev/production config conflicts:

1. **hot-dev.sh**: Explicitly export PULSE_DATA_DIR before starting backend
   - Ensures backend always uses /opt/pulse/tmp/dev-config in dev mode
   - Prevents accidental fallback to /etc/pulse
   - Adds logging to show which config directory is being used

2. **sync-production-config.sh**: Smart encryption key handling
   - Never overwrites existing dev encryption key
   - Warns if production key is newer (unusual scenario)
   - Keeps dev key to avoid breaking encrypted configs
   - Adds detailed logging of sync decisions

These changes ensure that when Vite restarts:
- Backend always uses the correct dev-config directory
- Sync script never breaks working dev configuration
- All decisions are logged clearly for debugging

Related to previous commit fixing nodes.enc corruption.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-01 07:33:20 +00:00