Explorar o código

Fix duplicate display of dangling images

Signed-off-by: Andy Goldstein <agoldste@redhat.com>
Andy Goldstein %!s(int64=10) %!d(string=hai) anos
pai
achega
c680dd9e5a
Modificáronse 2 ficheiros con 62 adicións e 16 borrados
  1. 19 16
      api/client/commands.go
  2. 43 0
      integration-cli/docker_cli_images_test.go

+ 19 - 16
api/client/commands.go

@@ -1518,29 +1518,32 @@ func (cli *DockerCli) CmdImages(args ...string) error {
 				outID = common.TruncateID(outID)
 				outID = common.TruncateID(outID)
 			}
 			}
 
 
-			// Tags referring to this image ID.
-			for _, repotag := range out.GetList("RepoTags") {
-				repo, tag := parsers.ParseRepositoryTag(repotag)
+			repoTags := out.GetList("RepoTags")
+			repoDigests := out.GetList("RepoDigests")
 
 
-				if !*quiet {
-					if *showDigests {
-						fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", repo, tag, "<none>", outID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), units.HumanSize(float64(out.GetInt64("VirtualSize"))))
-					} else {
-						fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, outID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), units.HumanSize(float64(out.GetInt64("VirtualSize"))))
-					}
+			if len(repoTags) == 1 && repoTags[0] == "<none>:<none>" && len(repoDigests) == 1 && repoDigests[0] == "<none>@<none>" {
+				// dangling image - clear out either repoTags or repoDigsts so we only show it once below
+				repoDigests = []string{}
+			}
+
+			// combine the tags and digests lists
+			tagsAndDigests := append(repoTags, repoDigests...)
+			for _, repoAndRef := range tagsAndDigests {
+				repo, ref := parsers.ParseRepositoryTag(repoAndRef)
+				// default tag and digest to none - if there's a value, it'll be set below
+				tag := "<none>"
+				digest := "<none>"
+				if utils.DigestReference(ref) {
+					digest = ref
 				} else {
 				} else {
-					fmt.Fprintln(w, outID)
+					tag = ref
 				}
 				}
-			}
 
 
-			// Digests referring to this image ID.
-			for _, repoDigest := range out.GetList("RepoDigests") {
-				repo, digest := parsers.ParseRepositoryTag(repoDigest)
 				if !*quiet {
 				if !*quiet {
 					if *showDigests {
 					if *showDigests {
-						fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", repo, "<none>", digest, outID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), units.HumanSize(float64(out.GetInt64("VirtualSize"))))
+						fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", repo, tag, digest, outID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), units.HumanSize(float64(out.GetInt64("VirtualSize"))))
 					} else {
 					} else {
-						fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, "<none>", outID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), units.HumanSize(float64(out.GetInt64("VirtualSize"))))
+						fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, outID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), units.HumanSize(float64(out.GetInt64("VirtualSize"))))
 					}
 					}
 				} else {
 				} else {
 					fmt.Fprintln(w, outID)
 					fmt.Fprintln(w, outID)

+ 43 - 0
integration-cli/docker_cli_images_test.go

@@ -8,6 +8,8 @@ import (
 	"strings"
 	"strings"
 	"testing"
 	"testing"
 	"time"
 	"time"
+
+	"github.com/docker/docker/pkg/common"
 )
 )
 
 
 func TestImagesEnsureImageIsListed(t *testing.T) {
 func TestImagesEnsureImageIsListed(t *testing.T) {
@@ -176,3 +178,44 @@ func TestImagesFilterWhiteSpaceTrimmingAndLowerCasingWorking(t *testing.T) {
 
 
 	logDone("images - white space trimming and lower casing")
 	logDone("images - white space trimming and lower casing")
 }
 }
+
+func TestImagesEnsureDanglingImageOnlyListedOnce(t *testing.T) {
+	defer deleteAllContainers()
+
+	// create container 1
+	c := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
+	out, _, err := runCommandWithOutput(c)
+	if err != nil {
+		t.Fatalf("error running busybox: %s, %v", out, err)
+	}
+	containerId1 := strings.TrimSpace(out)
+
+	// tag as foobox
+	c = exec.Command(dockerBinary, "commit", containerId1, "foobox")
+	out, _, err = runCommandWithOutput(c)
+	if err != nil {
+		t.Fatalf("error tagging foobox: %s", err)
+	}
+	imageId := common.TruncateID(strings.TrimSpace(out))
+	defer deleteImages(imageId)
+
+	// overwrite the tag, making the previous image dangling
+	c = exec.Command(dockerBinary, "tag", "-f", "busybox", "foobox")
+	out, _, err = runCommandWithOutput(c)
+	if err != nil {
+		t.Fatalf("error tagging foobox: %s", err)
+	}
+	defer deleteImages("foobox")
+
+	c = exec.Command(dockerBinary, "images", "-q", "-f", "dangling=true")
+	out, _, err = runCommandWithOutput(c)
+	if err != nil {
+		t.Fatalf("listing images failed with errors: %s, %v", out, err)
+	}
+
+	if e, a := 1, strings.Count(out, imageId); e != a {
+		t.Fatalf("expected 1 dangling image, got %d: %s", a, out)
+	}
+
+	logDone("images - dangling image only listed once")
+}