Previously the workflow ran install.sh without --version, which caused it
to download the latest stable release instead of the target release tag.
This was causing the demo server to downgrade from RC versions to stable
when triggered via workflow_dispatch.
Skip arm64 QEMU emulation in preflight tests - staging images are only
used for integration tests which run on amd64. This cuts ~20-30 minutes
off the release pipeline.
Multi-arch Docker images are still built in the final release job via
publish-docker.yml.
The PULSE_SENSOR_PROXY_SELFHEAL env var is set to "1", but the check
was only looking for "true", causing selfheal to regenerate itself on
every run. This meant the cached installer would overwrite the selfheal
script with its (potentially older) version, defeating any fixes in
the selfheal script.
Now correctly checks for both "true" and "1".
Related to #849
The selfheal timer was running the full installer every 5 minutes even when
the service was already running and healthy. This caused unnecessary:
- Pulse service restarts
- Config migrations
- Socket setup
- 172MB memory spikes and 15s CPU usage per run
Now the selfheal exits early after checking service health, only proceeding
to reinstall logic if the service is actually failing.
Fixes#849
When a user configures only Ollama (or any single provider) via the
multi-provider UI without explicitly selecting a model, GetModel() now
returns that provider's default model instead of falling back to the
legacy Provider field which defaults to "anthropic".
This fixes "API key is required for anthropic" errors when enabling AI
with only Ollama configured.
Related to #847
The selfheal timer was downloading prerelease versions (e.g., v5.0.0-rc.1)
even when users had the stable channel selected. This happened because
fetch_latest_release_tag() didn't filter out prereleases from the GitHub
releases API response.
Now both the Python-based parser and the grep fallback skip prereleases:
- Python: checks `release.get("prerelease")` field
- Grep fallback: filters out -rc, -alpha, -beta patterns
Related to #849
The form pre-fills the Ollama URL field with http://localhost:11434 but
compared it against that same default value to detect changes. This meant
users configuring Ollama with the default URL never actually saved it.
Also shows actual backend error messages instead of generic "Failed to update"
when toggling the AI enable switch.
Related to #847
The enable validation was using the legacy single-provider model which
checked settings.Provider and settings.APIKey. Users configuring Ollama
via the new multi-provider UI (setting ollama_base_url) couldn't enable
AI because settings.Provider defaulted to "anthropic" which required an
API key.
Now checks GetConfiguredProviders() first - if any provider is configured
(Anthropic, OpenAI, DeepSeek, or Ollama), AI can be enabled.
Related to #847
Fixes#819
The installer was hanging at 'Pending control-plane sync detected' because
systemctl start ran synchronously, waiting for the selfheal service to complete.
If the control-plane sync failed or took a long time (e.g., Proxmox node not
configured in Pulse yet), the installer would hang indefinitely.
Changed to use 'systemctl start --no-block' to run the selfheal service
asynchronously in the background. The sync will still be attempted, but the
installer will complete immediately and show the success message.
The container config backup and pct commands could hang indefinitely
when the Proxmox cluster filesystem (pmxcfs) is slow or unresponsive.
This caused the installer to appear to hang after printing
"Configuring socket bind mount..." with no further output.
Added timeout protection to:
- Container config backup cp operation
- pct status check
- pct config verification
- Config rollback cp operation
Related to #738
On TrueNAS, the runtime binary may be in /root/bin or /var/tmp while
the install script only checked INSTALL_DIR (/data/pulse-agent).
This left the running process using the binary when the script tried
to copy a new version, causing "Text file busy" errors.
Now explicitly stop the service and kill any pulse-agent processes
before modifying binaries on TrueNAS systems.
Related to #846
The standalone installer creates the socket at /mnt/pulse-proxy on the host,
not /run/pulse-sensor-proxy. Updated documentation to show the correct mount:
/mnt/pulse-proxy:/run/pulse-sensor-proxy:ro
Related to #822
LXC containers share the host's /sys/class/dmi/id/product_uuid, which
causes gopsutil to return identical HostIDs for all LXC containers on
the same physical host. This results in agent ID collisions where
multiple LXC containers appear as a single host in Pulse.
The fix detects LXC containers and prefers /etc/machine-id (which is
unique per container) over gopsutil's HostID.
Related to #773
Fixes#828
Memory bars were always showing green regardless of usage percentage.
Added getMemoryColor() function that applies threshold-based coloring:
- Green: Below 70%
- Yellow/Orange: 70-90%
- Red: Above 90%
This matches the existing disk bar behavior and restores the expected
visual warning for high memory usage.
Fixes#825
Long Docker image names (like Immich postgres containers) were expanding
the entire table row, requiring horizontal scrolling to see CPU/Memory.
Changed the image cell to use:
- Inline style max-width (more reliable in table layouts)
- Block span with truncate class
- overflow-hidden on parent container
Images now truncate with ellipsis at 200px, with full name in tooltip.
Fixes#773
The type badge order was flapping between 'Host Docker' and 'Docker Host'
because Array.from(new Set([...])) doesn't preserve insertion order reliably.
Added a sortTypes helper that ensures types are always displayed in a
consistent order: 'host' before 'docker'. This prevents visual flapping
even when the underlying data sources update at slightly different times.
Addresses #827
- Added 3-retry logic with 2-second delays between attempts
- Increased timeout from 15s to 30s for slower connections
- Show actual curl error instead of suppressing stderr
- Provide workaround instructions (download manually then run)
- Show the URL being downloaded for easier debugging
Closes#826
The error messages suggested using --proxy-url but the flag was never
implemented. This adds the flag so users can manually specify the
proxy URL when:
- Auto IP detection produces malformed results
- The desired IP is not the primary IP
- Multi-homed hosts need a specific interface
Related to #823
- Log payload size (in KB and bytes) at debug level
- Warn when payload approaches 400KB (512KB limit)
- Helps diagnose 'request body too large' errors
The Quick tips banner on the Alerts page said "Set any threshold to 0" but
the actual code uses -1 to disable alerts. The tooltips on individual fields
were correct; only the top-of-page banner was wrong.
Related to #843
- Remove 'release: published' triggers from publish-docker, promote-floating-tags, and helm-pages workflows
- All these workflows now only run via workflow_dispatch, triggered by create-release.yml in sequence
- Add image availability check in promote-floating-tags to wait for Docker images
- create-release.yml now dispatches: publish-docker, promote-floating-tags, helm-pages, update-demo-server
- This prevents the race condition where workflows triggered by release event run before Docker images are ready
- Update VERSION to 5.0.0-rc.1
- Add prerelease detection to create-release workflow
- Mark RC releases as prereleases on GitHub (not 'latest')
- Update publish-docker workflow to skip :latest tag for RCs
- Support -rc.N, -alpha.N, and -beta.N version suffixes
- Install script now auto-detects Docker, Kubernetes, and Proxmox
- Platform monitoring is enabled automatically when detected
- Users can override with --disable-* or --enable-* flags
- Allow same token to register multiple hosts (one per hostname)
- Update tests to reflect new multi-host token behavior
- Improve CompleteStep and UnifiedAgents UI components
- Update UNIFIED_AGENT.md documentation
- Add cluster-aware guest ID generation (clusterName-VMID instead of instanceName-VMID)
to prevent duplicate VMs/containers when multiple cluster nodes are monitored
- Add cluster deduplication at registration time - when a node is added that belongs
to an already-configured cluster, merge as endpoint instead of creating duplicate
- Add startup consolidation to automatically merge duplicate cluster instances
- Change host agent token binding from agent GUID to hostname, allowing:
- Multiple host agents to share a token (each bound by hostname)
- Agent reinstalls on same host without token conflicts
- Remove 12-character password minimum requirement
- Remove emoji from auto-registration success message
- Fix grouped view node lookup to support both cluster-aware node IDs
(clusterName-nodeName) and legacy guest grouping keys (instance-nodeName)
Fixes duplicate guests appearing when agents are installed on multiple
cluster nodes. Also improves multi-agent UX by allowing shared tokens.
- NodeGroupHeader shows '+ Host Agent' badge when node has linked agent
- NodeSummaryTable shows '+Agent' badge in the node row
- Filter out linked hosts from Managed Agents list (prevents duplication)
This provides visual feedback when a PVE node has enhanced monitoring
via an installed host agent.
- Added linkedHostAgentId to Node interface
- Added linkedNodeId/linkedVmId/linkedContainerId to Host interface
- Filter out linked hosts from 'Managed Agents' list (they show merged with nodes)
Next: Update Dashboard to display linked entity badges
When a host agent registers, it now searches for a PVE node with a
matching hostname and links them together. Similarly, when PVE nodes
are discovered, they check for existing host agents with matching hostnames.
This prevents the confusion of seeing duplicate entries when users install
agents on PVE cluster nodes that were already discovered via the cluster API.
- Added LinkedHostAgentID field to Node struct
- Added LinkedNodeID/LinkedVMID/LinkedContainerID fields to Host struct
- Added findLinkedProxmoxEntity() to match by hostname (with domain stripping)
- Updated UpdateNodesForInstance() to preserve and auto-set links
Users no longer need to manually click 'New Token' - a fresh token is
automatically generated after each copy. The command shown is always
ready for the next host.
- Setup wizard now clearly states 'Use a different token for each host'
- New Token button is always visible and more prominent (blue styling)
- WebSocket store now clears stale agents (>60s since lastSeen) immediately
when receiving empty host arrays, instead of waiting for 3 consecutive updates
The anti-flapping logic previously required 3 consecutive empty updates
before clearing stale agents from the UI. Now if all existing hosts/dockerHosts
have lastSeen > 60 seconds ago, empty updates are applied immediately.
This fixes the issue where removed agents stayed visible for too long.
The previous fix added legacy cleanup for systemd/macOS but missed the
Unraid-specific section. Now removes pulse-host-agent and pulse-docker-agent
entries from /boot/config/go and cleans up /boot/config/pulse directory.
Changed misleading 'Each copy uses a unique token' to 'Use the same
command on multiple servers'. Also toned down the 'Different Token'
button since it's rarely needed.
The --uninstall flag now removes:
- Unified pulse-agent (service, binary, logs)
- Legacy pulse-host-agent (service, binary, logs)
- Legacy pulse-docker-agent (service, binary, logs)
- Agent state directory (/var/lib/pulse-agent)
- All related log files
Works on Linux (systemd), macOS (launchd), and other supported platforms.