Commit graph

1138 commits

Author SHA1 Message Date
rcourtman
e2cdcb7b3e Match original sublabel style for CPU core count display 2025-11-29 21:49:00 +00:00
rcourtman
46f90e1585 Show CPU core count on EnhancedCPUBar progress bar 2025-11-29 21:47:22 +00:00
rcourtman
0dd65c5db2 Add unit tests for TaskQueue Upsert and Remove methods 2025-11-29 21:38:33 +00:00
rcourtman
02d8d8a9f9 Use left-aligned headers consistently in Docker table 2025-11-29 21:31:44 +00:00
rcourtman
f2983634e5 Center CPU and Memory cells in Docker container/service rows 2025-11-29 21:27:25 +00:00
rcourtman
c7184a1327 Center CPU and Memory column headers in Docker table 2025-11-29 21:25:08 +00:00
rcourtman
f32d22dc41 Convert data tables from CSS Grid to HTML tables
- Replace CSS Grid with native <table> elements across all data tables
- HTML tables naturally align columns based on widest content in each column
- Add min-width on CPU/Memory/Disk columns for proper progress bar display
- Remove responsive column header abbreviations (show full labels always)
- Remove icon components from NodeSummaryTable headers
- Simplify TemperatureGauge to text-only display (no progress bar)

Tables converted: Dashboard guest table, NodeSummaryTable, HostsOverview,
DockerUnifiedTable, DockerHostSummaryTable
2025-11-29 21:20:02 +00:00
rcourtman
a5fea152e8 Add unit tests for HandleLookup hostname matching
Tests cover the hostname lookup paths in HandleLookup:
- Exact hostname match (case-insensitive)
- DisplayName match (case-insensitive)
- Short hostname match (before first dot)
- Priority of exact over short match
- Sorted iteration order behavior
- Not-found cases

12 test cases covering all hostname matching code paths.
2025-11-29 20:20:15 +00:00
rcourtman
7704a18e52 ADA: Add unit tests for isDirectLoopbackRequest 2025-11-29 20:07:59 +00:00
rcourtman
9393574f05 ADA: Add unit tests for Ceph helper functions
Test coverage for isCephStorageType, countServiceDaemons,
extractCephCheckSummary, and summarizeCephHealth functions.
These parse Ceph storage types and health status JSON.
2025-11-29 19:49:43 +00:00
rcourtman
5eb793f4bb ADA: Add unit tests for TaskQueue.Snapshot 2025-11-29 19:38:54 +00:00
rcourtman
277ec7e9da ADA: Add unit tests for validateSystemSettings 2025-11-29 19:08:58 +00:00
rcourtman
4e05285567 Fix cluster degraded status not recovering after transient failures
The previous fix (6db4ee7a) cleared stale error messages but didn't mark
endpoints as healthy again after successful operations. This caused
clusters to remain in "degraded" state permanently once any endpoint had
a temporary issue, even if all endpoints were actually working.

The fix now marks endpoints healthy in clearEndpointError() after
successful operations, ensuring degraded clusters recover automatically.

Related to #659
2025-11-29 19:04:11 +00:00
rcourtman
fbabace023 Fix SolidJS proxy error in batched WebSocket updates
Using reconcile() inside produce() is invalid - reconcile returns a
function that creates a new proxy, but produce expects direct mutations.
Use batch() from solid-js instead to atomically batch the two setState
calls without proxy conflicts.
2025-11-29 18:54:22 +00:00
rcourtman
8bc8a98bb8 Remove unused usagePercent variable in Storage.tsx 2025-11-29 18:46:14 +00:00
rcourtman
712541d5d8 Fix indentation in cleanup section after pvesh refactor
The previous commit left broken indentation and an orphaned else block
in the cleanup section. This fixes the structure to properly handle
the cluster nodes vs standalone node cases.

Related to #738
2025-11-29 18:41:59 +00:00
rcourtman
ce47e8ca9d ADA: Add unit tests for sanitizeInstallerURL and sanitizeSetupAuthToken
Add comprehensive test coverage for security-critical URL and token
sanitization functions in config_handlers.go. These functions protect
the setup script endpoint from injection attacks.

TestSanitizeInstallerURL (23 cases): empty/whitespace handling, valid
http/https URLs, fragment stripping, query preservation, control character
rejection, invalid scheme rejection (ftp/file/javascript/data), and
missing host validation.

TestSanitizeSetupAuthToken (19 cases): empty/whitespace handling, valid
hex tokens of various lengths (32-128 chars), mixed case hex, control
character rejection, non-hex character rejection, and length validation.
2025-11-29 18:35:27 +00:00
rcourtman
2de2dc36c2 Use pvesh API for cluster node discovery in install-sensor-proxy.sh
Replace brittle pvecm nodes CLI parsing with pvesh API calls. The old
approach used awk field positions ($4) which breaks across Proxmox
versions, locales, or output format changes.

Added get_cluster_node_names() helper that:
- Prefers pvesh get /cluster/status --output-format json (structured)
- Falls back to pvecm nodes CLI parsing if pvesh unavailable
- Uses python3 for JSON parsing (always available on Proxmox)

Related to #738
2025-11-29 18:33:27 +00:00
rcourtman
e5db4f01c3 Fix pvecm nodes parsing to correctly extract hostname field
The awk was using $NF which returns "(local)" on the local node's line
instead of the hostname. Changed to $4 which is the actual hostname field.

Related to #738
2025-11-29 18:24:44 +00:00
rcourtman
67519304f9 Fix agent type flapping in Settings/Agents page
When a unified agent reports both host and docker data, the WebSocket
handler was calling setState separately for dockerHosts and hosts.
This caused the UnifiedAgents component's allHosts memo to recalculate
twice - first seeing only the updated dockerHosts (showing "Docker"),
then seeing both (showing "Host & Docker").

Batch both updates into a single setState call using produce() when
both are present in the same message, ensuring the component always
sees consistent data.

Related to #778
2025-11-29 18:06:41 +00:00
rcourtman
fce4168f82 ADA: Add unit tests for validateBcryptHash helper function
Tests cover valid bcrypt hash formats ($2a$, $2b$, $2y$), truncated/too-long
hashes, empty input, and invalid prefixes (md5-style, $2x$, no prefix).
2025-11-29 18:06:19 +00:00
rcourtman
9647313570 ADA: Fix redactSecretsFromURL bug and add unit tests
The Telegram bot token redaction had an off-by-one bug: it searched for
the next "/" starting from the "/bot" position, which found the "/" in
"/bot" itself (offset 0) instead of the next "/" after the token.

Result: tokens were not properly redacted and the URL got corrupted with
duplicated path segments, potentially leaking secrets to logs/API responses.

Fix: search from idx+4 (after "/bot") and handle edge cases where there's
no trailing slash (token at end of URL or before query string).

Added 20 comprehensive test cases covering:
- No secrets (passthrough)
- Telegram bot tokens (various patterns)
- Query parameter secrets (token, apikey, api_key, key, secret, password)
- Multiple parameters and edge cases
2025-11-29 17:36:32 +00:00
courtmanr@gmail.com
a8911b0f32 Add EnhancedStorageBar component with ZFS status visualization
- Create EnhancedStorageBar component to show storage usage with ZFS integration
- Animated overlay for active scrubbing/resilvering operations
- Red pulse border indicator for pools with errors
- Detailed tooltip showing ZFS state, scan status, and error counts
- Replace static progress bar in Storage.tsx with EnhancedStorageBar
- Remove unused getProgressBarColor function
2025-11-29 17:32:54 +00:00
rcourtman
f4cfe96943 ADA: Add normalizeCommandStatus helper with unit tests
Extract command status normalization logic from HandleCommandAck into
a dedicated helper function. This improves testability and makes the
status alias handling explicit and documented.

The function accepts client-provided status strings and maps them to
internal status constants:
- acknowledged: "", "ack", "acknowledged"
- completed: "success", "completed", "complete"
- failed: "fail", "failed", "error"

Adds 25 table-driven test cases covering all aliases, case insensitivity,
whitespace handling, and invalid inputs.
2025-11-29 17:06:18 +00:00
rcourtman
5201bd7087 Add unit tests for metrics.go helper functions
Test normalizeLabel, normalizeNodeLabel, splitInstanceKey,
breakerStateToValue, sanitizeInstanceLabels, makeMetricKey,
and makeNodeMetricKey with 36 test cases covering edge cases
like empty strings, whitespace, and invalid inputs.
2025-11-29 16:44:37 +00:00
rcourtman
61bb124692 Extract filesystem filtering logic into pkg/fsfilters
Move the inline filesystem skip logic from pollVMsAndContainersEfficient
into a reusable ShouldSkipFilesystem function. This consolidates filtering
for virtual filesystems (tmpfs, cgroup, etc.), network mounts (nfs, cifs,
fuse), and special mountpoints (/dev, /proc, /snap, etc.) into one tested
location.

Reduces cyclomatic complexity of pollVMsAndContainersEfficient and adds
28 test cases covering virtual fs types, network mounts, special mounts,
Windows paths, and edge cases.
2025-11-29 16:38:08 +00:00
rcourtman
69a7d96e4b Merge branch 'ada/20241129-parseversion-test' 2025-11-29 16:32:33 +00:00
rcourtman
affe0d2c47 Merge branch 'ada/20241129-normalizeversion-test' 2025-11-29 16:32:33 +00:00
rcourtman
a4ef95ef9e Add unit tests for ParseVersion function
Tests basic version parsing, v prefix stripping, prerelease,
build metadata, and error cases for invalid input.
2025-11-29 16:00:44 +00:00
rcourtman
ac5992b6c6 Add regression test for normalizeVersion
Prevents recurrence of the infinite update loop bug fixed in 1b866598
where version prefix mismatch caused continuous self-updates.
2025-11-29 15:22:05 +00:00
courtmanr@gmail.com
3ed190e8bc Add EnhancedCPUBar component with Load Average visualization
- Create EnhancedCPUBar component to show CPU usage with Load Average overlay
- Add vertical marker indicating 1-minute Load Average relative to core count
- Purple glow indicator when Load > Cores (system overload)
- Detailed tooltip showing Usage, Load, and Capacity metrics
- Full sparkline mode support for historical view
- Integrate into NodeSummaryTable for Proxmox nodes
- Integrate into DockerHostSummaryTable for Docker hosts
- Integrate into HostsOverview for standalone hosts
2025-11-29 15:15:38 +00:00
rcourtman
ea18aad96c Use pvecm nodes for cluster discovery to prefer management IPs
For multi-network Proxmox clusters (e.g., separate corosync and
management networks), the installer now uses `pvecm nodes` to get
hostnames and resolves them via /etc/hosts. This automatically
prefers management IPs when the cluster has proper /etc/hosts
configuration.

Falls back to the previous `pvecm status` IP extraction if hostname
resolution doesn't yield results.

Related to #738
2025-11-29 15:07:42 +00:00
rcourtman
3ef101049b Remove triage rules from repo
Move to local-only location outside the codebase.
2025-11-29 14:29:44 +00:00
rcourtman
11093951ec Use New-Service for Windows service creation
Switch from sc.exe create to PowerShell's New-Service cmdlet for
creating the Windows service. New-Service provides better error
handling and is more reliable. Keep sc.exe only for configuring
service recovery options (restart on failure), which New-Service
doesn't support.

Related to #776
2025-11-29 14:09:30 +00:00
rcourtman
e29fda5e5a Rebuild agent token bindings on API token config reload
When api_tokens.json is modified on disk, the ConfigWatcher reloads
the tokens into memory. However, the Monitor's dockerTokenBindings and
hostTokenBindings maps were not synchronized with the new token set,
causing orphaned bindings when agents reconnect after reinstall.

Add SetAPITokenReloadCallback to ConfigWatcher that triggers Monitor's
new RebuildTokenBindings method after token reload. This method
reconstructs the binding maps from current Docker host and host agent
state, keeping only bindings for tokens that still exist in config.

Related to #773
2025-11-29 14:09:30 +00:00
courtmanr@gmail.com
ae3a349124 Refine memory visualization with StackedMemoryBar component
- Add StackedMemoryBar component to visualize Active/Balloon/Swap memory
- Integrate StackedMemoryBar into NodeSummaryTable, GuestRow, HostsOverview, and DockerUnifiedTable
- Add TemperatureGauge component for temperature visualization
- Standardize replication job status indicators with StatusDot
- Fix mock data generator to use realistic balloon memory values (0 by default, small % when active)
- Add StackedContainerBar for Docker container status visualization
- Add ZFSHealthMap component for storage pool health visualization
2025-11-29 13:48:30 +00:00
rcourtman
c3a5aacd21 Fix standalone docker agent version comparison prefix mismatch
The unified agent got the version normalization fix (1b866598), but the
standalone docker agent's checkForUpdates() still used direct string
comparison. When server returns "4.34.0" and agent has "v4.34.0", this
caused an infinite self-update loop.

Apply the same normalizeVersion() function used in the unified agent.

Related to #773
2025-11-29 00:04:43 +00:00
courtmanr@gmail.com
6852004ffb feat: add stacked disk bar to hosts overview and fix tooltip positioning
- Replace standard disk metric bar with StackedDiskBar in HostsOverview
    - Show detailed per-disk usage breakdown on hover
    - Use Portal for tooltips to ensure correct positioning and z-index
    - Add class prop support to MetricBar
2025-11-28 22:10:15 +00:00
rcourtman
1d0c8b3ce1 Make demo server trigger non-fatal in release workflow
GITHUB_TOKEN cannot dispatch workflows in the same repo. Mark the step
as continue-on-error so the release succeeds even if demo update fails.

Related to v4.34.1 release failure.
2025-11-28 21:32:36 +00:00
rcourtman
89605277e6 Add jq dependency and fix secondary node support in sensor-proxy installer
Related to #738

Fixes two issues discovered by k5madsen:

1. Missing jq dependency: The sensor wrapper script uses jq extensively to
   parse SMART data JSON from smartctl but the installer never checked if
   jq was installed. Added jq to REQUIRED_CMDS list.

2. Secondary node support: When running on a secondary Proxmox cluster node
   where the container doesn't exist locally, the script now:
   - Warns instead of failing with "Container does not exist"
   - Continues installation for host temperature monitoring
   - Skips container-specific socket mount configuration

This allows users to run the installer on all cluster nodes (as intended)
to ensure the sensor-proxy service is available when containers migrate.
2025-11-28 21:08:43 +00:00
rcourtman
b39a3dd9a3 Bump version to 4.34.1 2025-11-28 20:59:54 +00:00
rcourtman
4de209b8a1 Fix TypeScript errors in Login.tsx and UnifiedAgents.tsx 2025-11-28 20:16:31 +00:00
rcourtman
f5f88faac5 Add workflow_dispatch to publish-docker.yml for manual triggers
Allows manual triggering when release.published webhook fails.
Related to #774
2025-11-28 20:01:08 +00:00
rcourtman
5a43ab4e57 Fix Windows agent SC CREATE binPath quoting
The binPath parameter value needs outer quotes when it contains
embedded quotes and spaces. Without this, SC.EXE parses the value
incorrectly and fails to create the service.

Related to #776
2025-11-28 18:04:24 +00:00
rcourtman
806cdd2d87 Fix Docker CPU calculation on systemUsage counter reset
When systemUsage counter goes backward (common in unprivileged LXC
containers), the previous code used the absolute value as systemDelta.
This created an artificially small denominator, inflating CPU to ~100%.

Now leaves systemDelta as 0 on counter reset, falling through to the
time-based calculation which produces accurate results.

Related to #770
2025-11-28 15:07:49 +00:00
rcourtman
d93e17e898 Fix settings sidebar width causing status icons to wrap
Revert expanded width from w-64 (256px) to w-72 (288px) and min/max
from 16rem to 18rem. The reduction in commit 6333a445 caused PVE node
status icons to wrap to two lines.

Related to #764
2025-11-28 15:07:42 +00:00
rcourtman
f9bd09a2b4 Add UI for removed Docker hosts re-enrollment
Adds a "Removed Docker Hosts" section to Settings -> Agents that displays
hosts blocked from re-enrolling and provides an "Allow re-enroll" button.
The backend API already existed; this adds the missing frontend component.

Related to #773
2025-11-28 12:07:28 +00:00
rcourtman
3e2715d3f5 Fix macOS unified agent binary naming in Makefile
Makefile was building macOS unified agent binaries with 'macos-' prefix
(e.g., pulse-agent-macos-amd64) but the download endpoint and agent's
determineArch() function use 'darwin-' prefix (e.g., pulse-agent-darwin-amd64).

This mismatch could cause macOS agent self-updates to fail because the
server would look for the darwin-prefixed binary that doesn't exist.

Note: The release build script (scripts/build-release.sh) already uses
the correct 'darwin-' prefix, so this only affects local development builds.

Related to #768
2025-11-28 11:36:24 +00:00
rcourtman
71580181d0 Add stacked bar visualization for multiple disks
Show individual disk usage segments as a stacked bar in the dashboard
table. Each segment represents one disk's used space proportional to
total capacity. Multi-disk systems display a count badge [N] and
hovering shows a tooltip with per-disk breakdown (name, used/total, %).

Single-disk and aggregate fallback still work as before.

Related to #489
2025-11-28 10:36:23 +00:00
rcourtman
bfce323e41 Fix silent sc.exe delete failures in install.ps1
- Add error handling for sc.exe delete in uninstall logic
- Add error handling for legacy agent service deletion
- Add error handling for existing service deletion before reinstall
- Show warnings when service deletion fails instead of silently continuing

Related to #735
2025-11-28 09:58:47 +00:00