1package docker
2
3import (
4 "net"
5 "os"
6 "strings"
7 "time"
8)
9
10// DetectionResult holds the result of runtime socket detection.
11type DetectionResult struct {
12 SocketPath string
13 Source string
14 RuntimeName string
15}
16
17var defaultSocketPaths = []string{
18 "/var/run/docker.sock",
19 "/run/podman/podman.sock",
20}
21
22// DetectRuntimeSocket detects the container runtime socket to use.
23// If explicit is non-empty, it is used directly. Otherwise, DOCKER_HOST is
24// checked, then well-known socket paths are probed.
25func DetectRuntimeSocket(explicit string) DetectionResult {
26 if explicit != "" {
27 return DetectionResult{
28 SocketPath: explicit,
29 Source: "explicit",
30 RuntimeName: guessRuntimeName(explicit),
31 }
32 }
33
34 dockerHost := os.Getenv("DOCKER_HOST")
35 if dockerHost != "" {
36 if path, ok := parseUnixSocketPath(dockerHost); ok {
37 return DetectionResult{
38 SocketPath: path,
39 Source: "DOCKER_HOST",
40 RuntimeName: guessRuntimeName(path),
41 }
42 }
43 return DetectionResult{
44 Source: "DOCKER_HOST_passthrough",
45 }
46 }
47
48 for _, path := range defaultSocketPaths {
49 if socketResponds(path) {
50 return DetectionResult{
51 SocketPath: path,
52 Source: "probed",
53 RuntimeName: guessRuntimeName(path),
54 }
55 }
56 }
57
58 xdg := os.Getenv("XDG_RUNTIME_DIR")
59 if xdg != "" {
60 podmanPath := xdg + "/podman/podman.sock"
61 if socketResponds(podmanPath) {
62 return DetectionResult{
63 SocketPath: podmanPath,
64 Source: "probed",
65 RuntimeName: "podman",
66 }
67 }
68 }
69
70 return DetectionResult{Source: "none"}
71}
72
73func parseUnixSocketPath(value string) (string, bool) {
74 if strings.HasPrefix(value, "unix://") {
75 return strings.TrimPrefix(value, "unix://"), true
76 }
77 if strings.HasPrefix(value, "/") {
78 return value, true
79 }
80 return "", false
81}
82
83func socketResponds(path string) bool {
84 conn, err := net.DialTimeout("unix", path, 2*time.Second)
85 if err != nil {
86 return false
87 }
88 conn.Close()
89 return true
90}
91
92func guessRuntimeName(path string) string {
93 if strings.Contains(path, "podman") {
94 return "podman"
95 }
96 return "docker"
97}