@@ -42,8 +42,8 @@ For example, to list running containers (the equivalent of "docker ps"):
4242package client // import "github.com/docker/docker/client"
4343
4444import (
45- "errors"
4645 "fmt"
46+ "net"
4747 "net/http"
4848 "net/url"
4949 "os"
@@ -56,6 +56,7 @@ import (
5656 "github.com/docker/docker/api/types/versions"
5757 "github.com/docker/go-connections/sockets"
5858 "github.com/docker/go-connections/tlsconfig"
59+ "github.com/pkg/errors"
5960 "golang.org/x/net/context"
6061)
6162
@@ -103,18 +104,21 @@ func CheckRedirect(req *http.Request, via []*http.Request) error {
103104}
104105
105106// NewEnvClient initializes a new API client based on environment variables.
106- // Use DOCKER_HOST to set the url to the docker server.
107- // Use DOCKER_API_VERSION to set the version of the API to reach, leave empty for latest.
108- // Use DOCKER_CERT_PATH to load the TLS certificates from.
109- // Use DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default.
110- // deprecated: use NewClientWithOpts(FromEnv)
107+ // See FromEnv for a list of support environment variables.
108+ //
109+ // Deprecated: use NewClientWithOpts(FromEnv)
111110func NewEnvClient () (* Client , error ) {
112111 return NewClientWithOpts (FromEnv )
113112}
114113
115- // FromEnv enhance the default client with values from environment variables
114+ // FromEnv configures the client with values from environment variables.
115+ //
116+ // Supported environment variables:
117+ // DOCKER_HOST to set the url to the docker server.
118+ // DOCKER_API_VERSION to set the version of the API to reach, leave empty for latest.
119+ // DOCKER_CERT_PATH to load the TLS certificates from.
120+ // DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default.
116121func FromEnv (c * Client ) error {
117- var httpClient * http.Client
118122 if dockerCertPath := os .Getenv ("DOCKER_CERT_PATH" ); dockerCertPath != "" {
119123 options := tlsconfig.Options {
120124 CAFile : filepath .Join (dockerCertPath , "ca.pem" ),
@@ -127,30 +131,58 @@ func FromEnv(c *Client) error {
127131 return err
128132 }
129133
130- httpClient = & http.Client {
131- Transport : & http.Transport {
132- TLSClientConfig : tlsc ,
133- },
134+ c .client = & http.Client {
135+ Transport : & http.Transport {TLSClientConfig : tlsc },
134136 CheckRedirect : CheckRedirect ,
135137 }
136- WithHTTPClient (httpClient )(c )
137138 }
138139
139- host := os .Getenv ("DOCKER_HOST" )
140- if host != "" {
141- // WithHost will create an API client if it doesn't exist
140+ if host := os .Getenv ("DOCKER_HOST" ); host != "" {
142141 if err := WithHost (host )(c ); err != nil {
143142 return err
144143 }
145144 }
146- version := os . Getenv ( "DOCKER_API_VERSION" )
147- if version != "" {
145+
146+ if version := os . Getenv ( "DOCKER_API_VERSION" ); version != "" {
148147 c .version = version
149148 c .manualOverride = true
150149 }
151150 return nil
152151}
153152
153+ // WithTLSClientConfig applies a tls config to the client transport.
154+ func WithTLSClientConfig (cacertPath , certPath , keyPath string ) func (* Client ) error {
155+ return func (c * Client ) error {
156+ opts := tlsconfig.Options {
157+ CAFile : cacertPath ,
158+ CertFile : certPath ,
159+ KeyFile : keyPath ,
160+ ExclusiveRootPools : true ,
161+ }
162+ config , err := tlsconfig .Client (opts )
163+ if err != nil {
164+ return errors .Wrap (err , "failed to create tls config" )
165+ }
166+ if transport , ok := c .client .Transport .(* http.Transport ); ok {
167+ transport .TLSClientConfig = config
168+ return nil
169+ }
170+ return errors .Errorf ("cannot apply tls config to transport: %T" , c .client .Transport )
171+ }
172+ }
173+
174+ // WithDialer applies the dialer.DialContext to the client transport. This can be
175+ // used to set the Timeout and KeepAlive settings of the client.
176+ func WithDialer (dialer * net.Dialer ) func (* Client ) error {
177+ return func (c * Client ) error {
178+ if transport , ok := c .client .Transport .(* http.Transport ); ok {
179+ transport .DialContext = dialer .DialContext
180+ return nil
181+ }
182+ return errors .Errorf ("cannot apply dialer to transport: %T" , c .client .Transport )
183+ }
184+ }
185+
154186// WithVersion overrides the client version with the specified one
155187func WithVersion (version string ) func (* Client ) error {
156188 return func (c * Client ) error {
@@ -159,8 +191,7 @@ func WithVersion(version string) func(*Client) error {
159191 }
160192}
161193
162- // WithHost overrides the client host with the specified one, creating a new
163- // http client if one doesn't exist
194+ // WithHost overrides the client host with the specified one.
164195func WithHost (host string ) func (* Client ) error {
165196 return func (c * Client ) error {
166197 hostURL , err := ParseHostURL (host )
@@ -171,17 +202,10 @@ func WithHost(host string) func(*Client) error {
171202 c .proto = hostURL .Scheme
172203 c .addr = hostURL .Host
173204 c .basePath = hostURL .Path
174- if c .client == nil {
175- client , err := defaultHTTPClient (host )
176- if err != nil {
177- return err
178- }
179- return WithHTTPClient (client )(c )
180- }
181205 if transport , ok := c .client .Transport .(* http.Transport ); ok {
182206 return sockets .ConfigureTransport (transport , c .proto , c .addr )
183207 }
184- return fmt .Errorf ("cannot apply host to http transport" )
208+ return errors .Errorf ("cannot apply host to transport: %T" , c . client . Transport )
185209 }
186210}
187211
@@ -266,7 +290,7 @@ func defaultHTTPClient(host string) (*http.Client, error) {
266290// It won't send any version information if the version number is empty. It is
267291// highly recommended that you set a version or your client may break if the
268292// server is upgraded.
269- // deprecated : use NewClientWithOpts
293+ // Deprecated : use NewClientWithOpts
270294func NewClient (host string , version string , client * http.Client , httpHeaders map [string ]string ) (* Client , error ) {
271295 return NewClientWithOpts (WithHost (host ), WithVersion (version ), WithHTTPClient (client ), WithHTTPHeaders (httpHeaders ))
272296}
@@ -378,6 +402,7 @@ func (cli *Client) CustomHTTPHeaders() map[string]string {
378402}
379403
380404// SetCustomHTTPHeaders that will be set on every HTTP request made by the client.
405+ // Deprecated: use WithHTTPHeaders when creating the client.
381406func (cli * Client ) SetCustomHTTPHeaders (headers map [string ]string ) {
382407 cli .customHTTPHeaders = headers
383408}
0 commit comments