From 45e091bca5ceead863589be607710a9aec206a70 Mon Sep 17 00:00:00 2001 From: Chanwit Kaewkasi Date: Tue, 25 Aug 2015 21:19:29 +0700 Subject: [PATCH] implement grouping list of images by Id Signed-off-by: Chanwit Kaewkasi --- api/handlers.go | 29 ++++++++++++++++++++++++++--- test/integration/api/images.bats | 10 +++++----- test/integration/api/pull.bats | 6 +++--- test/integration/api/tag.bats | 8 ++++++-- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/api/handlers.go b/api/handlers.go index 7fc93b9c42..56891ddc18 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -123,8 +123,9 @@ func getImagesJSON(c *context, w http.ResponseWriter, r *http.Request) { } accepteds, _ := filters["node"] - images := []*cluster.Image{} - + // this struct helps grouping images + // but still keeps their Engine infos as an array. + groupImages := make(map[string]dockerclient.Image) for _, image := range c.cluster.Images(all) { if len(accepteds) != 0 { found := false @@ -138,9 +139,31 @@ func getImagesJSON(c *context, w http.ResponseWriter, r *http.Request) { continue } } - images = append(images, image) + + // grouping images by Id, and concat their RepoTags + if entry, existed := groupImages[image.Id]; existed { + entry.RepoTags = append(entry.RepoTags, image.RepoTags...) + groupImages[image.Id] = entry + } else { + groupImages[image.Id] = image.Image + } } + images := []dockerclient.Image{} + + for _, image := range groupImages { + // de-duplicate RepoTags + result := []string{} + seen := map[string]bool{} + for _, val := range image.RepoTags { + if _, ok := seen[val]; !ok { + result = append(result, val) + seen[val] = true + } + } + image.RepoTags = result + images = append(images, image) + } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(images) } diff --git a/test/integration/api/images.bats b/test/integration/api/images.bats index 6154bc6b7b..03402e1c8b 100644 --- a/test/integration/api/images.bats +++ b/test/integration/api/images.bats @@ -14,16 +14,15 @@ function teardown() { start_docker_with_busybox 2 swarm_manage - - # we should get 2 busyboxes, plus the header. + # With grouping, we should get 1 busybox, plus the header. run docker_swarm images [ "$status" -eq 0 ] - [ "${#lines[@]}" -eq 3 ] + [ "${#lines[@]}" -eq 2 ] # Every line should contain "busybox" except for the header for((i=1; i<${#lines[@]}; i++)); do [[ "${lines[i]}" == *"busybox"* ]] done - + # Try with --filter. run docker_swarm images --filter node=node-0 [ "$status" -eq 0 ] @@ -40,6 +39,7 @@ function teardown() { [[ "${lines[1]}" == *"busybox"* ]] # Try images -a + # lines are: header, busybox, , run docker_swarm images -a - [ "${#lines[@]}" -ge 5 ] + [ "${#lines[@]}" -ge 4 ] } diff --git a/test/integration/api/pull.bats b/test/integration/api/pull.bats index 32c600c112..1e27c4549a 100644 --- a/test/integration/api/pull.bats +++ b/test/integration/api/pull.bats @@ -18,11 +18,11 @@ function teardown() { docker_swarm pull busybox - # we should get 2 busyboxes, plus the header. + # with grouping, we should get 1 busybox, plus the header. run docker_swarm images [ "$status" -eq 0 ] - [ "${#lines[@]}" -eq 3 ] - # every line should contain "busybox" exclude the first head line + [ "${#lines[@]}" -eq 2 ] + # every line should contain "busybox" exclude the first head line for((i=1; i<${#lines[@]}; i++)); do [[ "${lines[i]}" == *"busybox"* ]] done diff --git a/test/integration/api/tag.bats b/test/integration/api/tag.bats index d03c0dd65e..ff340cc4dc 100644 --- a/test/integration/api/tag.bats +++ b/test/integration/api/tag.bats @@ -46,6 +46,10 @@ function teardown() { docker_swarm tag busybox tag_busybox:test # verify - run docker_swarm images - [[ $(echo ${output} | grep -o "tag_busybox" | wc -l) == 2 ]] + # change the way to verify tagged image on each node after image deduplication + run docker_swarm images --filter node=node-0 + [[ $(echo ${output} | grep -o "tag_busybox" | wc -l) == 1 ]] + + run docker_swarm images --filter node=node-1 + [[ $(echo ${output} | grep -o "tag_busybox" | wc -l) == 1 ]] }