Skip to content

Commit c680dd9

Browse files
author
Andy Goldstein
committed
Fix duplicate display of dangling images
Signed-off-by: Andy Goldstein <[email protected]>
1 parent 9732c25 commit c680dd9

File tree

2 files changed

+62
-16
lines changed

2 files changed

+62
-16
lines changed

api/client/commands.go

+19-16
Original file line numberDiff line numberDiff line change
@@ -1518,29 +1518,32 @@ func (cli *DockerCli) CmdImages(args ...string) error {
15181518
outID = common.TruncateID(outID)
15191519
}
15201520

1521-
// Tags referring to this image ID.
1522-
for _, repotag := range out.GetList("RepoTags") {
1523-
repo, tag := parsers.ParseRepositoryTag(repotag)
1521+
repoTags := out.GetList("RepoTags")
1522+
repoDigests := out.GetList("RepoDigests")
15241523

1525-
if !*quiet {
1526-
if *showDigests {
1527-
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"))))
1528-
} else {
1529-
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"))))
1530-
}
1524+
if len(repoTags) == 1 && repoTags[0] == "<none>:<none>" && len(repoDigests) == 1 && repoDigests[0] == "<none>@<none>" {
1525+
// dangling image - clear out either repoTags or repoDigsts so we only show it once below
1526+
repoDigests = []string{}
1527+
}
1528+
1529+
// combine the tags and digests lists
1530+
tagsAndDigests := append(repoTags, repoDigests...)
1531+
for _, repoAndRef := range tagsAndDigests {
1532+
repo, ref := parsers.ParseRepositoryTag(repoAndRef)
1533+
// default tag and digest to none - if there's a value, it'll be set below
1534+
tag := "<none>"
1535+
digest := "<none>"
1536+
if utils.DigestReference(ref) {
1537+
digest = ref
15311538
} else {
1532-
fmt.Fprintln(w, outID)
1539+
tag = ref
15331540
}
1534-
}
15351541

1536-
// Digests referring to this image ID.
1537-
for _, repoDigest := range out.GetList("RepoDigests") {
1538-
repo, digest := parsers.ParseRepositoryTag(repoDigest)
15391542
if !*quiet {
15401543
if *showDigests {
1541-
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"))))
1544+
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"))))
15421545
} else {
1543-
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"))))
1546+
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"))))
15441547
}
15451548
} else {
15461549
fmt.Fprintln(w, outID)

integration-cli/docker_cli_images_test.go

+43
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"strings"
99
"testing"
1010
"time"
11+
12+
"github.com/docker/docker/pkg/common"
1113
)
1214

1315
func TestImagesEnsureImageIsListed(t *testing.T) {
@@ -176,3 +178,44 @@ func TestImagesFilterWhiteSpaceTrimmingAndLowerCasingWorking(t *testing.T) {
176178

177179
logDone("images - white space trimming and lower casing")
178180
}
181+
182+
func TestImagesEnsureDanglingImageOnlyListedOnce(t *testing.T) {
183+
defer deleteAllContainers()
184+
185+
// create container 1
186+
c := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
187+
out, _, err := runCommandWithOutput(c)
188+
if err != nil {
189+
t.Fatalf("error running busybox: %s, %v", out, err)
190+
}
191+
containerId1 := strings.TrimSpace(out)
192+
193+
// tag as foobox
194+
c = exec.Command(dockerBinary, "commit", containerId1, "foobox")
195+
out, _, err = runCommandWithOutput(c)
196+
if err != nil {
197+
t.Fatalf("error tagging foobox: %s", err)
198+
}
199+
imageId := common.TruncateID(strings.TrimSpace(out))
200+
defer deleteImages(imageId)
201+
202+
// overwrite the tag, making the previous image dangling
203+
c = exec.Command(dockerBinary, "tag", "-f", "busybox", "foobox")
204+
out, _, err = runCommandWithOutput(c)
205+
if err != nil {
206+
t.Fatalf("error tagging foobox: %s", err)
207+
}
208+
defer deleteImages("foobox")
209+
210+
c = exec.Command(dockerBinary, "images", "-q", "-f", "dangling=true")
211+
out, _, err = runCommandWithOutput(c)
212+
if err != nil {
213+
t.Fatalf("listing images failed with errors: %s, %v", out, err)
214+
}
215+
216+
if e, a := 1, strings.Count(out, imageId); e != a {
217+
t.Fatalf("expected 1 dangling image, got %d: %s", a, out)
218+
}
219+
220+
logDone("images - dangling image only listed once")
221+
}

0 commit comments

Comments
 (0)