From 064e91cd23ee97c052d58ec3caaa857a1454e7d4 Mon Sep 17 00:00:00 2001 From: Xian Chaobo Date: Tue, 19 May 2015 05:21:14 -0400 Subject: [PATCH] fix image match and fix docker save Signed-off-by: Xian Chaobo --- api/handlers.go | 17 ++++++++++++++++- api/router.go | 2 +- cluster/image.go | 27 ++++++++++++++++++++++++--- cluster/image_test.go | 19 ++++++++++++++++++- 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/api/handlers.go b/api/handlers.go index 6350525952..be60f7f4bd 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -62,6 +62,20 @@ func getVersion(c *context, w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(version) } +// GET /images/{name:.*}/get +func getImage(c *context, w http.ResponseWriter, r *http.Request) { + name := mux.Vars(r)["name"] + + for _, image := range c.cluster.Images() { + if len(strings.SplitN(name, ":", 2)) == 2 && image.Match(name) || + len(strings.SplitN(name, ":", 2)) == 1 && image.MatchWithoutTag(name) { + proxy(c.tlsConfig, image.Engine.Addr, w, r) + return + } + } + httpError(w, fmt.Sprintf("No such image: %s", name), http.StatusNotFound) +} + // GET /images/get func getImages(c *context, w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { @@ -83,7 +97,8 @@ func getImages(c *context, w http.ResponseWriter, r *http.Request) { // Count how many images we need it has. for _, name := range names { for _, image := range images { - if image.Match(name) { + if len(strings.SplitN(name, ":", 2)) == 2 && image.Match(name) || + len(strings.SplitN(name, ":", 2)) == 1 && image.MatchWithoutTag(name) { matchedImages = matchedImages + 1 break } diff --git a/api/router.go b/api/router.go index fbf95025e0..2539644dc2 100644 --- a/api/router.go +++ b/api/router.go @@ -29,7 +29,7 @@ var routes = map[string]map[string]handler{ "/images/viz": notImplementedHandler, "/images/search": proxyRandom, "/images/get": getImages, - "/images/{name:.*}/get": proxyImage, + "/images/{name:.*}/get": getImage, "/images/{name:.*}/history": proxyImage, "/images/{name:.*}/json": proxyImage, "/containers/ps": getContainersJSON, diff --git a/cluster/image.go b/cluster/image.go index 84cebffc79..bf83bc5026 100644 --- a/cluster/image.go +++ b/cluster/image.go @@ -20,13 +20,34 @@ func (image *Image) Match(IDOrName string) bool { if image.Id == IDOrName || (size > 2 && strings.HasPrefix(image.Id, IDOrName)) { return true } + + if len(strings.SplitN(IDOrName, ":", 2)) == 1 { + IDOrName = IDOrName + ":latest" + } + for _, repoTag := range image.RepoTags { - if len(strings.SplitN(repoTag, ":", 2)) == 1 { - repoTag = repoTag + ":latest" - } if repoTag == IDOrName { return true } } return false } + +// MatchWithoutTag is exported +func (image *Image) MatchWithoutTag(IDOrName string) bool { + size := len(IDOrName) + + if image.Id == IDOrName || (size > 2 && strings.HasPrefix(image.Id, IDOrName)) { + return true + } + + name := strings.SplitN(IDOrName, ":", 2)[0] + + for _, repoTag := range image.RepoTags { + repoName := strings.SplitN(repoTag, ":", 2)[0] + if repoName == name { + return true + } + } + return false +} diff --git a/cluster/image_test.go b/cluster/image_test.go index 64e958b123..af9c80bbe6 100644 --- a/cluster/image_test.go +++ b/cluster/image_test.go @@ -18,7 +18,24 @@ func TestMatch(t *testing.T) { assert.False(t, img.Match("37")) assert.True(t, img.Match("name:latest")) - assert.False(t, img.Match("name")) + assert.True(t, img.Match("name")) assert.False(t, img.Match("nam")) assert.False(t, img.Match("na")) } + +func TestMatchWithoutTag(t *testing.T) { + img := Image{} + + img.Id = "378954456789" + img.RepoTags = []string{"name:latest"} + + assert.True(t, img.MatchWithoutTag("378954456789")) + assert.True(t, img.MatchWithoutTag("3789")) + assert.True(t, img.MatchWithoutTag("378")) + assert.False(t, img.MatchWithoutTag("37")) + + assert.True(t, img.MatchWithoutTag("name:latest")) + assert.True(t, img.MatchWithoutTag("name")) + assert.False(t, img.MatchWithoutTag("nam")) + assert.False(t, img.MatchWithoutTag("na")) +}