From 74ea90e4b3a2ffabc8b0faccc8cbbafe38406f43 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Tue, 6 Jan 2026 10:56:37 +0000 Subject: [PATCH] fix: Podman sockets not prioritized when --docker-runtime=podman When --docker-runtime=podman is explicitly set, the agent should try Podman-specific sockets first before falling back to environment defaults (which try /var/run/docker.sock). Also adds /var/run/podman/podman.sock as a candidate socket path, which is used by CoreOS and some Fedora configurations. Related to #1045 --- internal/dockeragent/agent.go | 52 +++++++++++++++++---- internal/dockeragent/agent_internal_test.go | 15 ++++-- 2 files changed, 55 insertions(+), 12 deletions(-) diff --git a/internal/dockeragent/agent.go b/internal/dockeragent/agent.go index a3309f25b..e7f741ba4 100644 --- a/internal/dockeragent/agent.go +++ b/internal/dockeragent/agent.go @@ -407,7 +407,7 @@ func tryRuntimeCandidate(opts []client.Opt) (dockerClient, systemtypes.Info, err } func buildRuntimeCandidates(preference RuntimeKind) []runtimeCandidate { - candidates := make([]runtimeCandidate, 0, 6) + candidates := make([]runtimeCandidate, 0, 8) seen := make(map[string]struct{}) add := func(candidate runtimeCandidate) { @@ -422,6 +422,35 @@ func buildRuntimeCandidates(preference RuntimeKind) []runtimeCandidate { candidates = append(candidates, candidate) } + // When podman is explicitly requested, try podman-specific sockets FIRST + // before falling back to environment defaults (which try /var/run/docker.sock) + if preference == RuntimePodman { + if host := utils.GetenvTrim("PODMAN_HOST"); host != "" { + add(runtimeCandidate{ + host: host, + label: "PODMAN_HOST", + }) + } + + rootless := fmt.Sprintf("unix:///run/user/%d/podman/podman.sock", os.Getuid()) + add(runtimeCandidate{ + host: rootless, + label: "podman rootless socket", + }) + + add(runtimeCandidate{ + host: "unix:///run/podman/podman.sock", + label: "podman system socket", + }) + + // Some distros (CoreOS, Fedora) use /var/run/podman instead of /run/podman + add(runtimeCandidate{ + host: "unix:///var/run/podman/podman.sock", + label: "podman system socket (var/run)", + }) + } + + // Environment defaults (uses Docker client defaults) add(runtimeCandidate{ label: "environment defaults", applyDockerEnv: true, @@ -442,14 +471,15 @@ func buildRuntimeCandidates(preference RuntimeKind) []runtimeCandidate { }) } - if host := utils.GetenvTrim("PODMAN_HOST"); host != "" { - add(runtimeCandidate{ - host: host, - label: "PODMAN_HOST", - }) - } + // For auto mode, check podman after environment defaults + if preference == RuntimeAuto { + if host := utils.GetenvTrim("PODMAN_HOST"); host != "" { + add(runtimeCandidate{ + host: host, + label: "PODMAN_HOST", + }) + } - if preference == RuntimePodman || preference == RuntimeAuto { rootless := fmt.Sprintf("unix:///run/user/%d/podman/podman.sock", os.Getuid()) add(runtimeCandidate{ host: rootless, @@ -460,6 +490,12 @@ func buildRuntimeCandidates(preference RuntimeKind) []runtimeCandidate { host: "unix:///run/podman/podman.sock", label: "podman system socket", }) + + // Some distros (CoreOS, Fedora) use /var/run/podman instead of /run/podman + add(runtimeCandidate{ + host: "unix:///var/run/podman/podman.sock", + label: "podman system socket (var/run)", + }) } if preference == RuntimeDocker || preference == RuntimeAuto { diff --git a/internal/dockeragent/agent_internal_test.go b/internal/dockeragent/agent_internal_test.go index 9c9a8ad9e..783befc11 100644 --- a/internal/dockeragent/agent_internal_test.go +++ b/internal/dockeragent/agent_internal_test.go @@ -937,7 +937,7 @@ func TestBuildRuntimeCandidates(t *testing.T) { { name: "podman preference includes podman sockets", preference: RuntimePodman, - wantMin: 3, // at least env defaults + podman rootless + podman system + wantMin: 4, // at least podman rootless + podman system + podman (var/run) + env defaults }, } @@ -948,9 +948,16 @@ func TestBuildRuntimeCandidates(t *testing.T) { t.Errorf("buildRuntimeCandidates(%v) returned %d candidates, want at least %d", tt.preference, len(candidates), tt.wantMin) } - // Verify first candidate is always "environment defaults" - if len(candidates) > 0 && candidates[0].label != "environment defaults" { - t.Errorf("first candidate should be 'environment defaults', got %q", candidates[0].label) + // When podman is explicitly requested, podman sockets should be tried first. + // For auto/docker modes, environment defaults should be first. + if len(candidates) > 0 { + if tt.preference == RuntimePodman { + if candidates[0].label != "podman rootless socket" { + t.Errorf("podman preference: first candidate should be 'podman rootless socket', got %q", candidates[0].label) + } + } else if candidates[0].label != "environment defaults" { + t.Errorf("first candidate should be 'environment defaults', got %q", candidates[0].label) + } } // Verify no duplicates