skopeo/vendor/github.com/containers/image/v5/docker/daemon/client.go
renovate[bot] fa1762f52b fix(deps): update module github.com/containers/image/v5 to v5.33.0
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-11-12 20:34:31 +01:00

99 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package daemon
import (
"net/http"
"path/filepath"
"github.com/containers/image/v5/types"
dockerclient "github.com/docker/docker/client"
"github.com/docker/go-connections/tlsconfig"
)
// NewDockerClient initializes a new API client based on the passed SystemContext.
func newDockerClient(sys *types.SystemContext) (*dockerclient.Client, error) {
host := dockerclient.DefaultDockerHost
if sys != nil && sys.DockerDaemonHost != "" {
host = sys.DockerDaemonHost
}
opts := []dockerclient.Opt{
dockerclient.WithHost(host),
dockerclient.WithAPIVersionNegotiation(),
}
// 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, dont use WithHTTPClient for unix:// sockets at all.
//
// 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.
//
// 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
}
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.NewClientWithOpts(opts...)
}
func tlsConfig(sys *types.SystemContext) (*http.Client, error) {
options := tlsconfig.Options{}
if sys != nil && sys.DockerDaemonInsecureSkipTLSVerify {
options.InsecureSkipVerify = true
}
if sys != nil && sys.DockerDaemonCertPath != "" {
options.CAFile = filepath.Join(sys.DockerDaemonCertPath, "ca.pem")
options.CertFile = filepath.Join(sys.DockerDaemonCertPath, "cert.pem")
options.KeyFile = filepath.Join(sys.DockerDaemonCertPath, "key.pem")
}
tlsc, err := tlsconfig.Client(options)
if err != nil {
return nil, err
}
return &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: tlsc,
},
CheckRedirect: dockerclient.CheckRedirect,
}, nil
}
func httpConfig() *http.Client {
return &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: nil,
},
CheckRedirect: dockerclient.CheckRedirect,
}
}