From ca3fbadb5111d07edeacc5dc3d589766376ae3da Mon Sep 17 00:00:00 2001 From: jszwedko Date: Wed, 29 Oct 2014 12:23:26 -0400 Subject: [PATCH 1/5] Adding support for TLS DOCKER_HOST Workarounds courtesy of https://github.com/fsouza/go-dockerclient/issues/173. They can likely be removed after better support for TLS docker connections is added to go-dockerclient. --- Godeps | 4 ++-- dclient/dclient.go | 58 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/Godeps b/Godeps index cc94e2b..52c4651 100644 --- a/Godeps +++ b/Godeps @@ -32,8 +32,8 @@ }, { "ImportPath": "github.com/fsouza/go-dockerclient", - "Comment": "0.2.1-210-g8d5447b", - "Rev": "8d5447b3350dcc7644c7021b3cd57224cbedfa79" + "Comment": "0.2.1-296-g71d1ae2", + "Rev": "71d1ae28d00b36c43105164bd9cad662cd056c7a" }, { "ImportPath": "github.com/go-martini/martini", diff --git a/dclient/dclient.go b/dclient/dclient.go index 919e35d..3a10b92 100644 --- a/dclient/dclient.go +++ b/dclient/dclient.go @@ -2,7 +2,10 @@ package dclient import ( "fmt" + "net" + "net/url" "os" + "path" "regexp" "sort" @@ -25,19 +28,29 @@ func NewDockerClient(logger *logrus.Logger, shouldBeReal bool) (DockerClient, er }, nil } - var endpoint string + endpoint, err := getEndpoint() + if err != nil { + return nil, err + } + fmt.Println(endpoint) + tlsVerify := os.Getenv("DOCKER_TLS_VERIFY") != "" + certPath := os.Getenv("DOCKER_CERT_PATH") + + var dclient *docker.Client + if tlsVerify { + if certPath == "" { + return nil, fmt.Errorf("DOCKER_TLS_VERIFY is set, but DOCKER_CERT_PATH is empty") + } - defaultHost := os.Getenv("DOCKER_HOST") + cert := path.Join(certPath, "cert.pem") + key := path.Join(certPath, "key.pem") + ca := path.Join(certPath, "ca.pem") - if defaultHost == "" { - endpoint = "unix:///var/run/docker.sock" + dclient, err = docker.NewTLSClient(endpoint, cert, key, ca) } else { - // tcp endpoints cause a panic with this version of the go/docker library - endpoint = defaultHost + dclient, err = docker.NewClient(endpoint) } - dclient, err := docker.NewClient(endpoint) - if err != nil { logger.WithFields(logrus.Fields{ "docker_host": endpoint, @@ -139,3 +152,32 @@ func (rtoo *realDockerClient) PushImage(opts docker.PushImageOptions, auth docke func (rtoo *realDockerClient) BuildImage(opts docker.BuildImageOptions) error { return rtoo.client.BuildImage(opts) } + +// Workaround since DOCKER_HOST typically is tcp:// but we need to vary whether +// we use HTTP/HTTPS when interacting with the API +// Can be removed if https://github.com/fsouza/go-dockerclient/issues/173 is +// resolved +func getEndpoint() (string, error) { + endpoint := os.Getenv("DOCKER_HOST") + if endpoint == "" { + endpoint = "unix:///var/run/docker.sock" + } + + u, err := url.Parse(endpoint) + if err != nil { + return "", fmt.Errorf("couldn't parse endpoint %s as URL", endpoint) + } + if u.Scheme == "tcp" { + _, port, err := net.SplitHostPort(u.Host) + if err != nil { + return "", fmt.Errorf("error parsing %s for port", u.Host) + } + + if port == "2376" { + u.Scheme = "https" + } else { + u.Scheme = "http" + } + } + return u.String(), nil +} From 522da1d4320ee8669546a3ec73bb4fed623ba244 Mon Sep 17 00:00:00 2001 From: jszwedko Date: Wed, 29 Oct 2014 14:04:01 -0400 Subject: [PATCH 2/5] Only verify TLS via CA if DOCKER_TLS_VERIFY is set --- dclient/dclient.go | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/dclient/dclient.go b/dclient/dclient.go index 3a10b92..0766c8f 100644 --- a/dclient/dclient.go +++ b/dclient/dclient.go @@ -32,23 +32,25 @@ func NewDockerClient(logger *logrus.Logger, shouldBeReal bool) (DockerClient, er if err != nil { return nil, err } - fmt.Println(endpoint) tlsVerify := os.Getenv("DOCKER_TLS_VERIFY") != "" certPath := os.Getenv("DOCKER_CERT_PATH") var dclient *docker.Client - if tlsVerify { + if endpoint.Scheme == "https" { if certPath == "" { - return nil, fmt.Errorf("DOCKER_TLS_VERIFY is set, but DOCKER_CERT_PATH is empty") + return nil, fmt.Errorf("Using TLS, but DOCKER_CERT_PATH is empty") } cert := path.Join(certPath, "cert.pem") key := path.Join(certPath, "key.pem") - ca := path.Join(certPath, "ca.pem") + ca := "" + if tlsVerify { + ca = path.Join(certPath, "ca.pem") + } - dclient, err = docker.NewTLSClient(endpoint, cert, key, ca) + dclient, err = docker.NewTLSClient(endpoint.String(), cert, key, ca) } else { - dclient, err = docker.NewClient(endpoint) + dclient, err = docker.NewClient(endpoint.String()) } if err != nil { @@ -62,7 +64,7 @@ func NewDockerClient(logger *logrus.Logger, shouldBeReal bool) (DockerClient, er return &realDockerClient{ client: dclient, - host: endpoint, + host: endpoint.String(), Logger: logger, }, nil } @@ -157,7 +159,7 @@ func (rtoo *realDockerClient) BuildImage(opts docker.BuildImageOptions) error { // we use HTTP/HTTPS when interacting with the API // Can be removed if https://github.com/fsouza/go-dockerclient/issues/173 is // resolved -func getEndpoint() (string, error) { +func getEndpoint() (*url.URL, error) { endpoint := os.Getenv("DOCKER_HOST") if endpoint == "" { endpoint = "unix:///var/run/docker.sock" @@ -165,19 +167,20 @@ func getEndpoint() (string, error) { u, err := url.Parse(endpoint) if err != nil { - return "", fmt.Errorf("couldn't parse endpoint %s as URL", endpoint) + return nil, fmt.Errorf("couldn't parse endpoint %s as URL", endpoint) } if u.Scheme == "tcp" { _, port, err := net.SplitHostPort(u.Host) if err != nil { - return "", fmt.Errorf("error parsing %s for port", u.Host) + return nil, fmt.Errorf("error parsing %s for port", u.Host) } + // Only reliable way to determine if we should be using HTTPS appears to be via port if port == "2376" { u.Scheme = "https" } else { u.Scheme = "http" } } - return u.String(), nil + return u, nil } From 714c8c3f530413d65d18c2d5a2dc282cd1a7b5e7 Mon Sep 17 00:00:00 2001 From: Rafe Colton Date: Thu, 30 Oct 2014 14:52:17 -0700 Subject: [PATCH 3/5] Allowing host scheme to be overwritten by env var --- dclient/dclient.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dclient/dclient.go b/dclient/dclient.go index 0766c8f..f3e2ade 100644 --- a/dclient/dclient.go +++ b/dclient/dclient.go @@ -176,7 +176,9 @@ func getEndpoint() (*url.URL, error) { } // Only reliable way to determine if we should be using HTTPS appears to be via port - if port == "2376" { + if os.Getenv("DOCKER_HOST_SCHEME") != "" { + u.Scheme = os.Getenv("DOCKER_HOST_SCHEME") + } else if port == "2376" { u.Scheme = "https" } else { u.Scheme = "http" From 3e3abba5c899f9fb4052c65444192dd720be84c0 Mon Sep 17 00:00:00 2001 From: Rafe Colton Date: Thu, 30 Oct 2014 15:04:03 -0700 Subject: [PATCH 4/5] Adding documentation about TLS-related env vars --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a884ba..26394b5 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ $GOPATH/bin/docker-builder --help 0. Run`docker-builder --help` 0. Run `docker-builder help build` -### First, Install `docker-builder` +### Installing `docker-builder` #### Easiest @@ -56,6 +56,30 @@ curl -sL https://github.com/rafecolton/docker-builder/releases/download/v0.9.1/d To build from source, run `make build`. You may have to install some things first, such as `go` +### Using with TLS + +If you are using a version of `docker` with TLS enabled (supported in +`docker` `v1.3.0` and up, enabled by default with `boot2docker`), you +will need to use `docker-builder` `v0.9.2` or greater. + +Additionally, you must set the following environment variables: + +```bash +# all values are the boot2docker defaults +export DOCKER_CERT_PATH="$HOME/.boot2docker/certs/boot2docker-vm" +export DOCKER_TLS_VERIFY=1 +export DOCKER_HOST="tcp://127.0.0.1:2376" +``` + +**NOTE:** `docker-builder` will automatically set the correct url scheme +for TLS if you are using port 2376. If you are using another port and +wish to enable TLS, you must set the following additional environment +variable: + +```bash +export DOCKER_HOST_SCHEME="https" +``` + ## Contributing **Pull requests welcome!** From 3e3f0590801b4d5a5c9a201b1ab6fc3b120823c6 Mon Sep 17 00:00:00 2001 From: Rafe Colton Date: Thu, 30 Oct 2014 15:04:45 -0700 Subject: [PATCH 5/5] Bump version in README in anticipation of release --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 26394b5..b65a454 100644 --- a/README.md +++ b/README.md @@ -41,11 +41,11 @@ go get github.com/rafecolton/docker-builder ```bash # on Mac OS X -curl -sL https://github.com/rafecolton/docker-builder/releases/download/v0.9.1/docker-builder-v0.9.1-darwin-amd64 \ +curl -sL https://github.com/rafecolton/docker-builder/releases/download/v0.9.2/docker-builder-v0.9.2-darwin-amd64 \ -o /usr/local/bin/docker-builder && chmod +x /usr/local/bin/docker-builder # on Linux, note: you may need sudo -curl -sL https://github.com/rafecolton/docker-builder/releases/download/v0.9.1/docker-builder-v0.9.1-linux-amd64 \ +curl -sL https://github.com/rafecolton/docker-builder/releases/download/v0.9.2/docker-builder-v0.9.2-linux-amd64 \ -o /usr/local/bin/docker-builder && chmod +x /usr/local/bin/docker-builder ```