From e5f4243dad39f882e6752347cb8e68312fb22b71 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 28 Apr 2015 11:17:44 -0700 Subject: [PATCH] support pulling private images from docker pull Signed-off-by: Victor Vieux --- api/handlers.go | 8 +++++++- cluster/cluster.go | 5 +++-- cluster/engine.go | 6 +++--- cluster/swarm/cluster.go | 4 ++-- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/api/handlers.go b/api/handlers.go index 9e242d7fde..43d44ce3b5 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -2,6 +2,7 @@ package api import ( "bytes" + "encoding/base64" "encoding/json" "fmt" "io/ioutil" @@ -251,6 +252,11 @@ func postImagesCreate(c *context, w http.ResponseWriter, r *http.Request) { wf := NewWriteFlusher(w) if image := r.Form.Get("fromImage"); image != "" { //pull + authConfig := dockerclient.AuthConfig{} + buf, err := base64.URLEncoding.DecodeString(r.Header.Get("X-Registry-Auth")) + if err == nil { + json.Unmarshal(buf, &authConfig) + } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) @@ -264,7 +270,7 @@ func postImagesCreate(c *context, w http.ResponseWriter, r *http.Request) { fmt.Fprintf(wf, "{%q:%q,%q:\"Pulling %s... : %s\",%q:{}}", "id", what, "status", image, status, "progressDetail") } } - c.cluster.Pull(image, callback) + c.cluster.Pull(image, &authConfig, callback) } else { //import httpError(w, "Not supported in clustering mode.", http.StatusNotImplemented) } diff --git a/cluster/cluster.go b/cluster/cluster.go index bdddf80898..b6031e48db 100644 --- a/cluster/cluster.go +++ b/cluster/cluster.go @@ -1,8 +1,9 @@ package cluster import ( - "github.com/samalba/dockerclient" "io" + + "github.com/samalba/dockerclient" ) // Cluster is exported @@ -32,7 +33,7 @@ type Cluster interface { // `callback` can be called multiple time // `what` is what is being pulled // `status` is the current status, like "", "in progress" or "downloaded - Pull(name string, callback func(what, status string)) + Pull(name string, authConfig *dockerclient.AuthConfig, callback func(what, status string)) // Load images // `callback` can be called multiple time diff --git a/cluster/engine.go b/cluster/engine.go index 47cfef4e2b..a9e6eabf7f 100644 --- a/cluster/engine.go +++ b/cluster/engine.go @@ -367,7 +367,7 @@ func (e *Engine) Create(config *dockerclient.ContainerConfig, name string, pullI return nil, err } // Otherwise, try to pull the image... - if err = e.Pull(config.Image); err != nil { + if err = e.Pull(config.Image, nil); err != nil { return nil, err } // ...And try agaie. @@ -402,11 +402,11 @@ func (e *Engine) Destroy(container *Container, force bool) error { } // Pull an image on the engine -func (e *Engine) Pull(image string) error { +func (e *Engine) Pull(image string, authConfig *dockerclient.AuthConfig) error { if !strings.Contains(image, ":") { image = image + ":latest" } - if err := e.client.PullImage(image, nil); err != nil { + if err := e.client.PullImage(image, authConfig); err != nil { return err } diff --git a/cluster/swarm/cluster.go b/cluster/swarm/cluster.go index 33431eb8e9..9ac1b34719 100644 --- a/cluster/swarm/cluster.go +++ b/cluster/swarm/cluster.go @@ -212,7 +212,7 @@ func (c *Cluster) RemoveImage(image *cluster.Image) ([]*dockerclient.ImageDelete } // Pull is exported -func (c *Cluster) Pull(name string, callback func(what, status string)) { +func (c *Cluster) Pull(name string, authConfig *dockerclient.AuthConfig, callback func(what, status string)) { var wg sync.WaitGroup c.RLock() @@ -225,7 +225,7 @@ func (c *Cluster) Pull(name string, callback func(what, status string)) { if callback != nil { callback(nn.Name, "") } - err := nn.Pull(name) + err := nn.Pull(name, authConfig) if callback != nil { if err != nil { callback(nn.Name, err.Error())