From 731b194e7ec88f3cfafcaa9e58325244157fb427 Mon Sep 17 00:00:00 2001 From: Justin Lewis Salmon Date: Fri, 30 Mar 2018 15:08:41 +1100 Subject: [PATCH] Support host configuration for docker-daemon sources and destinations This PR adds CLI support for overriding the default docker daemon host when using the `docker-daemon` transport. Additionally, to support daemons listening on plain HTTP only, it is possible to specify the scheme as part of the host URL, e.g. `http+tcp://localhost:2375` I'm not sure if this is a good idea - I needed a way to stop the httpClient from trying to use TLS, and this seemed like a reasonable approach, similar to how the python docker client behaves. Happy to discuss and iterate on this. I'm guessing that I'd need to sumbit that part upstream to `containers/image` anyway. Fixes #244 --- cmd/skopeo/copy.go | 10 ++++++++++ cmd/skopeo/utils.go | 3 +++ .../containers/image/docker/daemon/client.go | 10 ++++++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/cmd/skopeo/copy.go b/cmd/skopeo/copy.go index 5a425d66e9..e42a29ac6b 100644 --- a/cmd/skopeo/copy.go +++ b/cmd/skopeo/copy.go @@ -160,5 +160,15 @@ var copyCmd = cli.Command{ Name: "dest-compress", Usage: "Compress tarball image layers when saving to directory using the 'dir' transport. (default is same compression type as source)", }, + cli.StringFlag{ + Name: "src-daemon-host", + Value: "", + Usage: "use docker daemon host at `HOST` (docker-daemon sources only)", + }, + cli.StringFlag{ + Name: "dest-daemon-host", + Value: "", + Usage: "use docker daemon host at `HOST` (docker-daemon destinations only)", + }, }, } diff --git a/cmd/skopeo/utils.go b/cmd/skopeo/utils.go index d2653dd383..e25466882d 100644 --- a/cmd/skopeo/utils.go +++ b/cmd/skopeo/utils.go @@ -22,6 +22,9 @@ func contextFromGlobalOptions(c *cli.Context, flagPrefix string) (*types.SystemC OCISharedBlobDirPath: c.String(flagPrefix + "shared-blob-dir"), DirForceCompress: c.Bool(flagPrefix + "compress"), AuthFilePath: c.String("authfile"), + DockerDaemonHost: c.String(flagPrefix + "daemon-host"), + DockerDaemonCertPath: c.String(flagPrefix + "cert-dir"), + DockerDaemonInsecureSkipTLSVerify: !c.BoolT(flagPrefix + "tls-verify"), } if c.IsSet(flagPrefix + "tls-verify") { ctx.DockerInsecureSkipTLSVerify = !c.BoolT(flagPrefix + "tls-verify") diff --git a/vendor/github.com/containers/image/docker/daemon/client.go b/vendor/github.com/containers/image/docker/daemon/client.go index 82fab4b19a..55b1870c7e 100644 --- a/vendor/github.com/containers/image/docker/daemon/client.go +++ b/vendor/github.com/containers/image/docker/daemon/client.go @@ -33,7 +33,7 @@ func newDockerClient(ctx *types.SystemContext) (*dockerclient.Client, error) { } var httpClient *http.Client if proto != "unix" { - hc, err := tlsConfig(ctx) + hc, err := tlsConfig(ctx, proto) if err != nil { return nil, err } @@ -43,7 +43,7 @@ func newDockerClient(ctx *types.SystemContext) (*dockerclient.Client, error) { return dockerclient.NewClient(host, defaultAPIVersion, httpClient, nil) } -func tlsConfig(ctx *types.SystemContext) (*http.Client, error) { +func tlsConfig(ctx *types.SystemContext, proto string) (*http.Client, error) { options := tlsconfig.Options{} if ctx != nil && ctx.DockerDaemonInsecureSkipTLSVerify { options.InsecureSkipVerify = true @@ -60,6 +60,12 @@ func tlsConfig(ctx *types.SystemContext) (*http.Client, error) { return nil, err } + // If the host explicitly specifies HTTP, setting the TLSClientConfig to + // nil will suffice to disable TLS completely + if ctx != nil && proto == "http+tcp" { + tlsc = nil + } + return &http.Client{ Transport: &http.Transport{ TLSClientConfig: tlsc,