github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/client/options.go (about) 1 package client 2 3 import ( 4 "context" 5 "net" 6 "net/http" 7 "os" 8 "path/filepath" 9 "time" 10 11 "github.com/docker/go-connections/sockets" 12 "github.com/docker/go-connections/tlsconfig" 13 "github.com/pkg/errors" 14 ) 15 16 // Opt is a configuration option to initialize a client 17 type Opt func(*Client) error 18 19 // FromEnv configures the client with values from environment variables. 20 // 21 // Supported environment variables: 22 // DOCKER_HOST to set the url to the docker server. 23 // DOCKER_API_VERSION to set the version of the API to reach, leave empty for latest. 24 // DOCKER_CERT_PATH to load the TLS certificates from. 25 // DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default. 26 func FromEnv(c *Client) error { 27 if dockerCertPath := os.Getenv("DOCKER_CERT_PATH"); dockerCertPath != "" { 28 options := tlsconfig.Options{ 29 CAFile: filepath.Join(dockerCertPath, "ca.pem"), 30 CertFile: filepath.Join(dockerCertPath, "cert.pem"), 31 KeyFile: filepath.Join(dockerCertPath, "key.pem"), 32 InsecureSkipVerify: os.Getenv("DOCKER_TLS_VERIFY") == "", 33 } 34 tlsc, err := tlsconfig.Client(options) 35 if err != nil { 36 return err 37 } 38 39 c.client = &http.Client{ 40 Transport: &http.Transport{TLSClientConfig: tlsc}, 41 CheckRedirect: CheckRedirect, 42 } 43 } 44 45 if host := os.Getenv("DOCKER_HOST"); host != "" { 46 if err := WithHost(host)(c); err != nil { 47 return err 48 } 49 } 50 51 if version := os.Getenv("DOCKER_API_VERSION"); version != "" { 52 if err := WithVersion(version)(c); err != nil { 53 return err 54 } 55 } 56 return nil 57 } 58 59 // WithDialer applies the dialer.DialContext to the client transport. This can be 60 // used to set the Timeout and KeepAlive settings of the client. 61 // Deprecated: use WithDialContext 62 func WithDialer(dialer *net.Dialer) Opt { 63 return WithDialContext(dialer.DialContext) 64 } 65 66 // WithDialContext applies the dialer to the client transport. This can be 67 // used to set the Timeout and KeepAlive settings of the client. 68 func WithDialContext(dialContext func(ctx context.Context, network, addr string) (net.Conn, error)) Opt { 69 return func(c *Client) error { 70 if transport, ok := c.client.Transport.(*http.Transport); ok { 71 transport.DialContext = dialContext 72 return nil 73 } 74 return errors.Errorf("cannot apply dialer to transport: %T", c.client.Transport) 75 } 76 } 77 78 // WithHost overrides the client host with the specified one. 79 func WithHost(host string) Opt { 80 return func(c *Client) error { 81 hostURL, err := ParseHostURL(host) 82 if err != nil { 83 return err 84 } 85 c.host = host 86 c.proto = hostURL.Scheme 87 c.addr = hostURL.Host 88 c.basePath = hostURL.Path 89 if transport, ok := c.client.Transport.(*http.Transport); ok { 90 return sockets.ConfigureTransport(transport, c.proto, c.addr) 91 } 92 return errors.Errorf("cannot apply host to transport: %T", c.client.Transport) 93 } 94 } 95 96 // WithHTTPClient overrides the client http client with the specified one 97 func WithHTTPClient(client *http.Client) Opt { 98 return func(c *Client) error { 99 if client != nil { 100 c.client = client 101 } 102 return nil 103 } 104 } 105 106 // WithTimeout configures the time limit for requests made by the HTTP client 107 func WithTimeout(timeout time.Duration) Opt { 108 return func(c *Client) error { 109 c.client.Timeout = timeout 110 return nil 111 } 112 } 113 114 // WithHTTPHeaders overrides the client default http headers 115 func WithHTTPHeaders(headers map[string]string) Opt { 116 return func(c *Client) error { 117 c.customHTTPHeaders = headers 118 return nil 119 } 120 } 121 122 // WithScheme overrides the client scheme with the specified one 123 func WithScheme(scheme string) Opt { 124 return func(c *Client) error { 125 c.scheme = scheme 126 return nil 127 } 128 } 129 130 // WithTLSClientConfig applies a tls config to the client transport. 131 func WithTLSClientConfig(cacertPath, certPath, keyPath string) Opt { 132 return func(c *Client) error { 133 opts := tlsconfig.Options{ 134 CAFile: cacertPath, 135 CertFile: certPath, 136 KeyFile: keyPath, 137 ExclusiveRootPools: true, 138 } 139 config, err := tlsconfig.Client(opts) 140 if err != nil { 141 return errors.Wrap(err, "failed to create tls config") 142 } 143 if transport, ok := c.client.Transport.(*http.Transport); ok { 144 transport.TLSClientConfig = config 145 return nil 146 } 147 return errors.Errorf("cannot apply tls config to transport: %T", c.client.Transport) 148 } 149 } 150 151 // WithVersion overrides the client version with the specified one. If an empty 152 // version is specified, the value will be ignored to allow version negotiation. 153 func WithVersion(version string) Opt { 154 return func(c *Client) error { 155 if version != "" { 156 c.version = version 157 c.manualOverride = true 158 } 159 return nil 160 } 161 } 162 163 // WithAPIVersionNegotiation enables automatic API version negotiation for the client. 164 // With this option enabled, the client automatically negotiates the API version 165 // to use when making requests. API version negotiation is performed on the first 166 // request; subsequent requests will not re-negotiate. 167 func WithAPIVersionNegotiation() Opt { 168 return func(c *Client) error { 169 c.negotiateVersion = true 170 return nil 171 } 172 }