@@ -7,13 +7,13 @@ import (
77 "os/exec"
88 "runtime"
99 "strings"
10+ "time"
1011
1112 "github.com/docker/docker/api/types/container"
1213 "github.com/docker/docker/api/types/image"
1314 "github.com/docker/docker/client"
1415 "github.com/docker/docker/pkg/jsonmessage"
1516 "github.com/docker/go-connections/nat"
16- "github.com/microcks/microcks-cli/pkg/errors"
1717 "github.com/moby/term"
1818)
1919
@@ -64,26 +64,52 @@ func NewDockerClient() (*containerClient, error) {
6464 return & containerClient {cli : cli }, nil
6565}
6666
67- func NewPodmanClient () (* containerClient , error ) {
68- osName := runtime .GOOS
69- switch osName {
70- case "windows" :
71- remoteSocket , err := exec .Command ("podman" , "machine" , "inspect" , "--format" , "{{.ConnectionInfo.PodmanPipe.Path}}" ).Output ()
72- errors .CheckError (err )
73- socketPath := strings .TrimSpace (string (remoteSocket ))
74- err = os .Setenv ("DOCKER_HOST" , "npipe:////" + strings .TrimPrefix (socketPath , "\\ \\ " ))
75- errors .CheckError (err )
67+ // PingDockerHost verifies the Docker-API endpoint at DOCKER_HOST actually
68+ // answers. The raw client honors DOCKER_HOST with no fallback, so this catches
69+ // an unreachable endpoint (e.g. a stopped Podman machine) before testcontainers-go
70+ // silently resolves to a different runtime.
71+ func PingDockerHost () error {
72+ cli , err := client .NewClientWithOpts (client .FromEnv , client .WithAPIVersionNegotiation ())
73+ if err != nil {
74+ return err
75+ }
76+ defer cli .Close ()
7677
78+ ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
79+ defer cancel ()
80+
81+ _ , err = cli .Ping (ctx )
82+ return err
83+ }
84+
85+ func ConfigurePodmanHost () error {
86+ switch runtime .GOOS {
87+ case "windows" :
88+ out , err := exec .Command ("podman" , "machine" , "inspect" , "--format" , "{{.ConnectionInfo.PodmanPipe.Path}}" ).Output ()
89+ if err != nil {
90+ return fmt .Errorf ("resolving podman pipe path (is the podman machine running?): %w" , err )
91+ }
92+ socketPath := strings .TrimSpace (string (out ))
93+ return os .Setenv ("DOCKER_HOST" , "npipe:////" + strings .TrimPrefix (socketPath , "\\ \\ " ))
7794 case "darwin" :
78- remoteSocket , err := exec .Command ("podman" , "machine" , "inspect" , "--format" , "{{.ConnectionInfo.PodmanSocket.Path}}" ).Output ()
79- errors .CheckError (err )
80- err = os .Setenv ("DOCKER_HOST" , "unix://" + strings .TrimSpace (string (remoteSocket )))
81- errors .CheckError (err )
95+ out , err := exec .Command ("podman" , "machine" , "inspect" , "--format" , "{{.ConnectionInfo.PodmanSocket.Path}}" ).Output ()
96+ if err != nil {
97+ return fmt .Errorf ("resolving podman socket path (is the podman machine running?): %w" , err )
98+ }
99+ return os .Setenv ("DOCKER_HOST" , "unix://" + strings .TrimSpace (string (out )))
82100 case "linux" :
83- remoteSocket , err := exec .Command ("podman" , "info" , "--format" , "{{.Host.RemoteSocket.Path}}" ).Output ()
84- errors .CheckError (err )
85- err = os .Setenv ("DOCKER_HOST" , "unix://" + strings .TrimSpace (string (remoteSocket )))
86- errors .CheckError (err )
101+ out , err := exec .Command ("podman" , "info" , "--format" , "{{.Host.RemoteSocket.Path}}" ).Output ()
102+ if err != nil {
103+ return fmt .Errorf ("resolving podman socket path: %w" , err )
104+ }
105+ return os .Setenv ("DOCKER_HOST" , "unix://" + strings .TrimSpace (string (out )))
106+ }
107+ return nil
108+ }
109+
110+ func NewPodmanClient () (* containerClient , error ) {
111+ if err := ConfigurePodmanHost (); err != nil {
112+ return nil , err
87113 }
88114
89115 cli , err := client .NewClientWithOpts (client .FromEnv , client .WithAPIVersionNegotiation ())
0 commit comments