diff --git a/cmd/pulse-agent/main.go b/cmd/pulse-agent/main.go index 0ea4d9d..c4a1aa2 100644 --- a/cmd/pulse-agent/main.go +++ b/cmd/pulse-agent/main.go @@ -6,6 +6,7 @@ import ( "fmt" "net/http" "os" + "os/exec" "os/signal" "strconv" "strings" @@ -146,6 +147,20 @@ func main() { }) } + // Auto-detect Docker/Podman if not explicitly configured + if !cfg.EnableDocker && !cfg.DockerConfigured { + // Check for docker binary + if _, err := exec.LookPath("docker"); err == nil { + logger.Info().Msg("Auto-detected Docker binary, enabling Docker monitoring") + cfg.EnableDocker = true + } else if _, err := exec.LookPath("podman"); err == nil { + logger.Info().Msg("Auto-detected Podman binary, enabling Docker monitoring") + cfg.EnableDocker = true + } else { + logger.Debug().Msg("Docker/Podman not found, skipping Docker monitoring") + } + } + // 9. Start Docker Agent (if enabled) var dockerAgent *dockeragent.Agent if cfg.EnableDocker { @@ -324,6 +339,7 @@ type Config struct { // Module flags EnableHost bool EnableDocker bool + DockerConfigured bool EnableKubernetes bool EnableProxmox bool ProxmoxType string // "pve", "pbs", or "" for auto-detect @@ -460,6 +476,16 @@ func loadConfig() Config { kubeIncludeNamespaces := gatherCSV(envKubeIncludeNamespaces, kubeIncludeNamespaceFlags) kubeExcludeNamespaces := gatherCSV(envKubeExcludeNamespaces, kubeExcludeNamespaceFlags) + // Check if Docker was explicitly configured via flag or env + dockerConfigured := envEnableDocker != "" + if !dockerConfigured { + flag.Visit(func(f *flag.Flag) { + if f.Name == "enable-docker" { + dockerConfigured = true + } + }) + } + return Config{ PulseURL: pulseURL, APIToken: token, @@ -471,6 +497,7 @@ func loadConfig() Config { LogLevel: logLevel, EnableHost: *enableHostFlag, EnableDocker: *enableDockerFlag, + DockerConfigured: dockerConfigured, EnableKubernetes: *enableKubernetesFlag, EnableProxmox: *enableProxmoxFlag, ProxmoxType: strings.TrimSpace(*proxmoxTypeFlag), diff --git a/frontend-modern/src/App.tsx b/frontend-modern/src/App.tsx index 6cc8e96..4d93f78 100644 --- a/frontend-modern/src/App.tsx +++ b/frontend-modern/src/App.tsx @@ -268,6 +268,7 @@ function App() { vms: [], containers: [], dockerHosts: [], + removedDockerHosts: [], hosts: [], storage: [], cephClusters: [], diff --git a/frontend-modern/src/stores/websocket.ts b/frontend-modern/src/stores/websocket.ts index 020f17a..f7782c8 100644 --- a/frontend-modern/src/stores/websocket.ts +++ b/frontend-modern/src/stores/websocket.ts @@ -11,6 +11,7 @@ import type { DockerHost, Host, KubernetesCluster, + RemovedDockerHost, RemovedKubernetesCluster, } from '@/types/api'; import type { ActivationState as ActivationStateType } from '@/types/alerts'; @@ -32,6 +33,7 @@ export function createWebSocketStore(url: string) { vms: [], containers: [], dockerHosts: [], + removedDockerHosts: [], kubernetesClusters: [], removedKubernetesClusters: [], hosts: [], @@ -579,6 +581,12 @@ export function createWebSocketStore(url: string) { setState('hosts', reconcile(processedHosts, { key: 'id' })); } } + if (message.data.removedDockerHosts !== undefined) { + const removed = Array.isArray(message.data.removedDockerHosts) + ? (message.data.removedDockerHosts as RemovedDockerHost[]) + : []; + setState('removedDockerHosts', reconcile(removed, { key: 'id' })); + } if (message.data.kubernetesClusters !== undefined) { const clusters = Array.isArray(message.data.kubernetesClusters) ? (message.data.kubernetesClusters as KubernetesCluster[]) diff --git a/internal/api/docker_agents.go b/internal/api/docker_agents.go index 2fa9cb6..00d61a6 100644 --- a/internal/api/docker_agents.go +++ b/internal/api/docker_agents.go @@ -338,6 +338,9 @@ func (h *DockerAgentHandlers) HandleAllowReenroll(w http.ResponseWriter, r *http return } + // Broadcast updated state to ensure the frontend reflects the change + go h.wsHub.BroadcastState(h.monitor.GetState().ToFrontend()) + if err := utils.WriteJSONResponse(w, map[string]any{ "success": true, "hostId": hostID, diff --git a/internal/config/config.go b/internal/config/config.go index 3920dec..24dd1c5 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1230,6 +1230,14 @@ func Load() (*Config, error) { log.Debug().Str("key_file", tlsKeyFile).Msg("TLS key file from env var") } + // Support PULSE_AGENT_URL as an alias for PULSE_AGENT_CONNECT_URL + // (Check this first so standard PULSE_AGENT_CONNECT_URL takes precedence if both set) + if agentURL := utils.GetenvTrim("PULSE_AGENT_URL"); agentURL != "" { + cfg.AgentConnectURL = agentURL + cfg.EnvOverrides["PULSE_AGENT_CONNECT_URL"] = true + log.Info().Str("url", agentURL).Msg("Using dedicated agent connect URL from PULSE_AGENT_URL") + } + if agentConnectURL := utils.GetenvTrim("PULSE_AGENT_CONNECT_URL"); agentConnectURL != "" { cfg.AgentConnectURL = agentConnectURL cfg.EnvOverrides["PULSE_AGENT_CONNECT_URL"] = true