NewDockerClient initializes a new API client based on the passed SystemContext.
(sys *types.SystemContext)
| 12 | |
| 13 | // NewDockerClient initializes a new API client based on the passed SystemContext. |
| 14 | func newDockerClient(sys *types.SystemContext) (*dockerclient.Client, error) { |
| 15 | host := dockerclient.DefaultDockerHost |
| 16 | if sys != nil && sys.DockerDaemonHost != "" { |
| 17 | host = sys.DockerDaemonHost |
| 18 | } |
| 19 | |
| 20 | opts := []dockerclient.Opt{ |
| 21 | dockerclient.WithHost(host), |
| 22 | dockerclient.WithAPIVersionNegotiation(), |
| 23 | } |
| 24 | |
| 25 | // We conditionalize building the TLS configuration only to TLS sockets: |
| 26 | // |
| 27 | // The dockerclient.Client implementation differentiates between |
| 28 | // - Client.proto, which is ~how the connection is establishe (IP / AF_UNIX/Windows) |
| 29 | // - Client.scheme, which is what is sent over the connection (HTTP with/without TLS). |
| 30 | // |
| 31 | // Only Client.proto is set from the URL in dockerclient.WithHost(), |
| 32 | // Client.scheme is detected based on a http.Client.TLSClientConfig presence; |
| 33 | // dockerclient.WithHTTPClient with a client that has TLSClientConfig set |
| 34 | // will, by default, trigger an attempt to use TLS. |
| 35 | // |
| 36 | // So, don’t use WithHTTPClient for unix:// sockets at all. |
| 37 | // |
| 38 | // Similarly, if we want to communicate over plain HTTP on a TCP socket (http://), |
| 39 | // we also should not set TLSClientConfig. We continue to use WithHTTPClient |
| 40 | // with our slightly non-default settings to avoid a behavior change on updates of c/image. |
| 41 | // |
| 42 | // Alternatively we could use dockerclient.WithScheme to drive the TLS/non-TLS logic |
| 43 | // explicitly, but we would still want to set WithHTTPClient (differently) for https:// and http:// ; |
| 44 | // so that would not be any simpler. |
| 45 | serverURL, err := dockerclient.ParseHostURL(host) |
| 46 | if err != nil { |
| 47 | return nil, err |
| 48 | } |
| 49 | switch serverURL.Scheme { |
| 50 | case "unix": // Nothing |
| 51 | case "npipe": // Nothing |
| 52 | case "http": |
| 53 | hc := httpConfig() |
| 54 | opts = append(opts, dockerclient.WithHTTPClient(hc)) |
| 55 | default: |
| 56 | hc, err := tlsConfig(sys) |
| 57 | if err != nil { |
| 58 | return nil, err |
| 59 | } |
| 60 | opts = append(opts, dockerclient.WithHTTPClient(hc)) |
| 61 | } |
| 62 | |
| 63 | return dockerclient.NewClientWithOpts(opts...) |
| 64 | } |
| 65 | |
| 66 | func tlsConfig(sys *types.SystemContext) (*http.Client, error) { |
| 67 | options := tlsconfig.Options{} |
searching dependent graphs…