// NewDockerCli returns a DockerCli instance with IO output and error streams set by in, out and err. // The key file, protocol (i.e. unix) and address are passed in as strings, along with the tls.Config. If the tls.Config // is set the client scheme will be set to https. // The client will be given a 32-second timeout (see https://github.com/docker/docker/pull/8035). func NewDockerCli(in io.ReadCloser, out, err io.Writer, keyFile string, proto, addr string, tlsConfig *tls.Config) *DockerCli { var ( inFd uintptr outFd uintptr isTerminalIn = false isTerminalOut = false scheme = "http" ) if tlsConfig != nil { scheme = "https" } if in != nil { inFd, isTerminalIn = term.GetFdInfo(in) } if out != nil { outFd, isTerminalOut = term.GetFdInfo(out) } if err == nil { err = out } // The transport is created here for reuse during the client session. tr := &http.Transport{ TLSClientConfig: tlsConfig, } sockets.ConfigureTCPTransport(tr, proto, addr) configFile, e := cliconfig.Load(cliconfig.ConfigDir()) if e != nil { fmt.Fprintf(err, "WARNING: Error loading config file:%v\n", e) } return &DockerCli{ proto: proto, addr: addr, configFile: configFile, in: in, out: out, err: err, keyFile: keyFile, inFd: inFd, outFd: outFd, isTerminalIn: isTerminalIn, isTerminalOut: isTerminalOut, tlsConfig: tlsConfig, scheme: scheme, transport: tr, } }
// NewClient creates a new plugin client (http). func NewClient(addr string, tlsConfig tlsconfig.Options) (*Client, error) { tr := &http.Transport{} c, err := tlsconfig.Client(tlsConfig) if err != nil { return nil, err } tr.TLSClientConfig = c protoAndAddr := strings.Split(addr, "://") sockets.ConfigureTCPTransport(tr, protoAndAddr[0], protoAndAddr[1]) return &Client{&http.Client{Transport: tr}, protoAndAddr[1]}, nil }
// NewClient initializes a new API client for the given host and API version. // It won't send any version information if the version number is empty. // It uses the tlsOptions to decide whether to use a secure connection or not. // It also initializes the custom http headers to add to each request. func NewClient(host string, version string, tlsOptions *tlsconfig.Options, httpHeaders map[string]string) (*Client, error) { var ( basePath string tlsConfig *tls.Config scheme = "http" protoAddrParts = strings.SplitN(host, "://", 2) proto, addr = protoAddrParts[0], protoAddrParts[1] ) if proto == "tcp" { parsed, err := url.Parse("tcp://" + addr) if err != nil { return nil, err } addr = parsed.Host basePath = parsed.Path } if tlsOptions != nil { scheme = "https" var err error tlsConfig, err = tlsconfig.Client(*tlsOptions) if err != nil { return nil, err } } // The transport is created here for reuse during the client session. transport := &http.Transport{ TLSClientConfig: tlsConfig, } sockets.ConfigureTCPTransport(transport, proto, addr) return &Client{ proto: proto, addr: addr, basePath: basePath, scheme: scheme, tlsConfig: tlsConfig, httpClient: &http.Client{Transport: transport}, version: version, customHTTPHeaders: httpHeaders, }, nil }
func (d *Daemon) getClientConfig() (*clientConfig, error) { var ( transport *http.Transport scheme string addr string proto string ) if d.useDefaultTLSHost { option := &tlsconfig.Options{ CAFile: "fixtures/https/ca.pem", CertFile: "fixtures/https/client-cert.pem", KeyFile: "fixtures/https/client-key.pem", } tlsConfig, err := tlsconfig.Client(*option) if err != nil { return nil, err } transport = &http.Transport{ TLSClientConfig: tlsConfig, } addr = fmt.Sprintf("%s:%d", opts.DefaultHTTPHost, opts.DefaultTLSHTTPPort) scheme = "https" proto = "tcp" } else if d.useDefaultHost { addr = opts.DefaultUnixSocket proto = "unix" scheme = "http" transport = &http.Transport{} } else { addr = filepath.Join(d.folder, "docker.sock") proto = "unix" scheme = "http" transport = &http.Transport{} } sockets.ConfigureTCPTransport(transport, proto, addr) return &clientConfig{ transport: transport, scheme: scheme, addr: addr, }, nil }
//docker client 创建函数 // NewDockerCli returns a DockerCli instance with IO output and error streams set by in, out and err. // The key file, protocol (i.e. unix) and address are passed in as strings, along with the tls.Config. If the tls.Config // is set the client scheme will be set to https. // The client will be given a 32-second timeout (see https://github.com/docker/docker/pull/8035). func NewDockerCli(in io.ReadCloser, out, err io.Writer, clientFlags *cli.ClientFlags) *DockerCli { cli := &DockerCli{ in: in, out: out, err: err, keyFile: clientFlags.Common.TrustKey, } cli.init = func() error { clientFlags.PostParse() hosts := clientFlags.Common.Hosts switch len(hosts) { case 0: hosts = []string{os.Getenv("DOCKER_HOST")} case 1: // only accept one host to talk to default: return errors.New("Please specify only one -H") } defaultHost := opts.DefaultTCPHost if clientFlags.Common.TLSOptions != nil { defaultHost = opts.DefaultTLSHost } var e error if hosts[0], e = opts.ParseHost(defaultHost, hosts[0]); e != nil { return e } protoAddrParts := strings.SplitN(hosts[0], "://", 2) cli.proto, cli.addr = protoAddrParts[0], protoAddrParts[1] if cli.proto == "tcp" { // error is checked in pkg/parsers already parsed, _ := url.Parse("tcp://" + cli.addr) cli.addr = parsed.Host cli.basePath = parsed.Path } if clientFlags.Common.TLSOptions != nil { cli.scheme = "https" //启用HTTPS var e error cli.tlsConfig, e = tlsconfig.Client(*clientFlags.Common.TLSOptions) if e != nil { return e } } else { cli.scheme = "http" } if cli.in != nil { cli.inFd, cli.isTerminalIn = term.GetFdInfo(cli.in) } if cli.out != nil { cli.outFd, cli.isTerminalOut = term.GetFdInfo(cli.out) } // The transport is created here for reuse during the client session. cli.transport = &http.Transport{ TLSClientConfig: cli.tlsConfig, } sockets.ConfigureTCPTransport(cli.transport, cli.proto, cli.addr) configFile, e := cliconfig.Load(cliconfig.ConfigDir()) if e != nil { fmt.Fprintf(cli.err, "WARNING: Error loading config file:%v\n", e) } cli.configFile = configFile return nil } return cli }