diff --git a/docker/daemon/client.go b/docker/daemon/client.go index 7d2a98d68..2c245f54f 100644 --- a/docker/daemon/client.go +++ b/docker/daemon/client.go @@ -21,33 +21,49 @@ func newDockerClient(sys *types.SystemContext) (*dockerclient.Client, error) { host = sys.DockerDaemonHost } - // Sadly, unix:// sockets don't work transparently with dockerclient.NewClient. - // They work fine with a nil httpClient; with a non-nil httpClient, the transport’s - // TLSClientConfig must be nil (or the client will try using HTTPS over the PF_UNIX socket - // regardless of the values in the *tls.Config), and we would have to call sockets.ConfigureTransport. + opts := []dockerclient.Opt{ + dockerclient.WithHost(host), + dockerclient.WithVersion(defaultAPIVersion), + } + + // We conditionalize building the TLS configuration only to TLS sockets: + // + // The dockerclient.Client implementation differentiates between + // - Client.proto, which is ~how the connection is establishe (IP / AF_UNIX/Windows) + // - Client.scheme, which is what is sent over the connection (HTTP with/without TLS). + // + // Only Client.proto is set from the URL in dockerclient.WithHost(), + // Client.scheme is detected based on a http.Client.TLSClientConfig presence; + // dockerclient.WithHTTPClient with a client that has TLSClientConfig set + // will, by default, trigger an attempt to use TLS. + // + // So, don’t use WithHTTPClient for unix:// sockets at all. // - // We don't really want to configure anything for unix:// sockets, so just pass a nil *http.Client. + // Similarly, if we want to communicate over plain HTTP on a TCP socket (http://), + // we also should not set TLSClientConfig. We continue to use WithHTTPClient + // with our slightly non-default settings to avoid a behavior change on updates of c/image. // - // Similarly, if we want to communicate over plain HTTP on a TCP socket, we also need to set - // TLSClientConfig to nil. This can be achieved by using the form `http://` + // Alternatively we could use dockerclient.WithScheme to drive the TLS/non-TLS logic + // explicitly, but we would still want to set WithHTTPClient (differently) for https:// and http:// ; + // so that would not be any simpler. serverURL, err := dockerclient.ParseHostURL(host) if err != nil { return nil, err } - var httpClient *http.Client - if serverURL.Scheme != "unix" { - if serverURL.Scheme == "http" { - httpClient = httpConfig() - } else { - hc, err := tlsConfig(sys) - if err != nil { - return nil, err - } - httpClient = hc + switch serverURL.Scheme { + case "unix": // Nothing + case "http": + hc := httpConfig() + opts = append(opts, dockerclient.WithHTTPClient(hc)) + default: + hc, err := tlsConfig(sys) + if err != nil { + return nil, err } + opts = append(opts, dockerclient.WithHTTPClient(hc)) } - return dockerclient.NewClient(host, defaultAPIVersion, httpClient, nil) + return dockerclient.NewClientWithOpts(opts...) } func tlsConfig(sys *types.SystemContext) (*http.Client, error) { diff --git a/go.mod b/go.mod index 820b7d491..5ad70e3ca 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/containers/storage v1.46.1 github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7 github.com/docker/distribution v2.8.1+incompatible - github.com/docker/docker v23.0.4+incompatible + github.com/docker/docker v23.0.5+incompatible github.com/docker/docker-credential-helpers v0.7.0 github.com/docker/go-connections v0.4.0 github.com/go-openapi/strfmt v0.21.7 diff --git a/go.sum b/go.sum index 6098a08d4..39b324e7c 100644 --- a/go.sum +++ b/go.sum @@ -274,8 +274,8 @@ github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4Kfc github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v23.0.4+incompatible h1:Kd3Bh9V/rO+XpTP/BLqM+gx8z7+Yb0AA2Ibj+nNo4ek= -github.com/docker/docker v23.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.5+incompatible h1:DaxtlTJjFSnLOXVNUBU1+6kXGz2lpDoEAH6QoxaSg8k= +github.com/docker/docker v23.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=