- Add comprehensive test coverage for alerts package with 285+ new tests
- Implement ThresholdsTable component with metric thresholds display
- Enhance Alerts page UI with improved layout and metric filtering
- Add frontend component tests for Alerts page and ThresholdsTable
- Set up Vitest testing infrastructure for SolidJS components
- Improve config persistence with better validation
- Expand discovery tests with 333+ test cases
- Update API, configuration, and Docker monitoring documentation
Fixed a fmt.Sprintf argument alignment issue in the PVE setup script that
caused a bash syntax error at the end of script execution. The error
manifested as "syntax error near unexpected token EXTRA" followed by the
serverHost URL.
Root cause: 23 arguments were provided for 22 %s placeholders. An extra
tokenName at position 15 pushed all subsequent arguments off by one,
leaving the final serverHost with no placeholder to fill.
Fix: Removed duplicate tokenName at position 15 and ensured serverHost
is correctly positioned at position 22 for the "Host URL" placeholder.
The REGISTER_JSON template at line 3311 was getting storagePerms instead of tokenName
for the tokenId field, causing 'Missing required fields' errors during auto-registration.
Added tokenName parameter before storagePerms to shift all subsequent parameters.
Fixes #<issue-number>
Fixes two issues found in v4.24.0-rc.1:
1. Setup script menu now uses numbered options [1/2/3] instead of
[I/r/c] for better UX (maintains backward compatibility)
2. Temperature verification endpoint now requires authentication
(wraps HandleVerifyTemperatureSSH with RequireAuth middleware)
These fixes address user feedback and prepare for v4.24.0-rc.2.
The router's handleDownloadAgent searches for /opt/pulse/bin/pulse-docker-agent
as a fallback when arch-specific binaries are not found or requested. In v4.23.0,
this fallback binary was missing from the Docker image, causing 404 errors for
linux-amd64 downloads.
The Dockerfile now explicitly copies the fallback binary to /opt/pulse/bin/pulse-docker-agent
alongside the arch-specific binaries (linux-amd64, linux-arm64, linux-armv7).
Verified with local build - all four binaries now exist in /opt/pulse/bin/.
Addresses #528
Addresses user concern about technical debt: detection code exists only
to handle migration from SSH-in-container to proxy architecture, not to
serve functional purpose of the application.
Changes:
- Add PULSE_LEGACY_DETECTION env var to disable detection without redeployment
- Add explicit removal criteria: v5.0 or <1% detection rate for 30+ days
- Mark all detection code with "MIGRATION SCAFFOLDING" warnings
- Create MIGRATION_SCAFFOLDING.md to track temporary code across codebase
- Document removal instructions for when migration period ends
Backend:
- internal/api/router.go: detectLegacySSH() checks env var and has removal plan
- internal/api/types.go: HealthResponse fields documented as temporary
Frontend:
- src/components/LegacySSHBanner.tsx: Component marked with removal criteria
- src/App.tsx: Banner integration (will be removed with component)
This approach balances user safety during migration (auto-detection catches
rushed admins who skip changelogs) with long-term code cleanliness (explicit
removal plan prevents indefinite technical debt).
Added automatic detection to alert users when they're using the old
SSH-in-container method for temperature monitoring so they can upgrade
to the secure proxy architecture.
**Detection Logic:**
- Checks if Pulse is running in a container (Docker or LXC)
- Checks if SSH keys exist in data directory (/etc/pulse/.ssh)
- Checks if pulse-sensor-proxy socket is NOT available
- Sets legacySSHDetected and recommendProxyUpgrade flags in health endpoint
**API Changes:**
- Added fields to HealthResponse:
- legacySSHDetected: true when old method detected
- recommendProxyUpgrade: true when upgrade is recommended
- proxyInstallScriptAvailable: always true
**Use Case:**
Users who set up temperature monitoring before the proxy feature
won't know they should upgrade. This detection allows the frontend
to show a banner prompting them to re-run the setup script to
migrate to the secure proxy architecture.
**Frontend Integration (to be added):**
Frontend can poll /api/health and show a dismissible banner similar
to UpdateBanner when legacySSHDetected is true, with a button to
view the setup script.
Addresses #123
Codex caught an edge case in the authorized_keys removal logic:
**Problem:**
When authorized_keys contains ONLY pulse-managed keys, `grep -vF` returns
exit code 1 (no lines matched the inverse filter). The previous code only
executed the rewrite on exit 0, leaving managed keys in place when they
should have been removed.
**Solution:**
- Capture grep exit code explicitly
- Treat both exit 0 (lines remain) and exit 1 (all removed) as success
- Only treat exit codes > 1 as actual errors
- Properly handles the "remove all keys" scenario
This ensures complete removal works even when the file contains nothing
but Pulse-managed entries.
Addresses #123
Fixed three remaining issues from Codex's final review:
**1. nullglob State Management (line 3124)**
- Replaced shopt -s/u nullglob with compgen -G check
- Prevents changing global shell behavior that could affect later globs
- More explicit and safer pattern matching
**2. authorized_keys Permission Preservation (lines 3116-3117)**
- Now uses chmod/chown --reference to preserve original ownership/perms
- Falls back gracefully if --reference not available
- Proper cleanup on mv failure to prevent temp file leaks
- Aborts atomically if operations fail, leaving original untouched
**3. Multi-Address Container Detection (lines 3750-3761)**
- Iterates over ALL IPs from hostname -I, not just first one
- Handles dual-stack (IPv4 + IPv6) and multi-IP containers
- Uses break 2 to exit both loops when match found
- Prevents false negatives when Pulse IP is not the first address
All operations now handle edge cases properly: non-root accounts,
dual-stack networking, empty directories, and partial failures.
Addresses #123