Signed-off-by: Andy Goldstein <agoldste@redhat.com>
Andy Goldstein authored on 2015/03/18 23:11:01... | ... |
@@ -1518,29 +1518,32 @@ func (cli *DockerCli) CmdImages(args ...string) error { |
1518 | 1518 |
outID = common.TruncateID(outID) |
1519 | 1519 |
} |
1520 | 1520 |
|
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") |
|
1524 | 1523 |
|
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 |
|
1531 | 1538 |
} else { |
1532 |
- fmt.Fprintln(w, outID) |
|
1539 |
+ tag = ref |
|
1533 | 1540 |
} |
1534 |
- } |
|
1535 | 1541 |
|
1536 |
- // Digests referring to this image ID. |
|
1537 |
- for _, repoDigest := range out.GetList("RepoDigests") { |
|
1538 |
- repo, digest := parsers.ParseRepositoryTag(repoDigest) |
|
1539 | 1542 |
if !*quiet { |
1540 | 1543 |
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")))) |
|
1542 | 1545 |
} 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")))) |
|
1544 | 1547 |
} |
1545 | 1548 |
} else { |
1546 | 1549 |
fmt.Fprintln(w, outID) |
... | ... |
@@ -8,6 +8,8 @@ import ( |
8 | 8 |
"strings" |
9 | 9 |
"testing" |
10 | 10 |
"time" |
11 |
+ |
|
12 |
+ "github.com/docker/docker/pkg/common" |
|
11 | 13 |
) |
12 | 14 |
|
13 | 15 |
func TestImagesEnsureImageIsListed(t *testing.T) { |
... | ... |
@@ -176,3 +178,44 @@ func TestImagesFilterWhiteSpaceTrimmingAndLowerCasingWorking(t *testing.T) { |
176 | 176 |
|
177 | 177 |
logDone("images - white space trimming and lower casing") |
178 | 178 |
} |
179 |
+ |
|
180 |
+func TestImagesEnsureDanglingImageOnlyListedOnce(t *testing.T) { |
|
181 |
+ defer deleteAllContainers() |
|
182 |
+ |
|
183 |
+ // create container 1 |
|
184 |
+ c := exec.Command(dockerBinary, "run", "-d", "busybox", "true") |
|
185 |
+ out, _, err := runCommandWithOutput(c) |
|
186 |
+ if err != nil { |
|
187 |
+ t.Fatalf("error running busybox: %s, %v", out, err) |
|
188 |
+ } |
|
189 |
+ containerId1 := strings.TrimSpace(out) |
|
190 |
+ |
|
191 |
+ // tag as foobox |
|
192 |
+ c = exec.Command(dockerBinary, "commit", containerId1, "foobox") |
|
193 |
+ out, _, err = runCommandWithOutput(c) |
|
194 |
+ if err != nil { |
|
195 |
+ t.Fatalf("error tagging foobox: %s", err) |
|
196 |
+ } |
|
197 |
+ imageId := common.TruncateID(strings.TrimSpace(out)) |
|
198 |
+ defer deleteImages(imageId) |
|
199 |
+ |
|
200 |
+ // overwrite the tag, making the previous image dangling |
|
201 |
+ c = exec.Command(dockerBinary, "tag", "-f", "busybox", "foobox") |
|
202 |
+ out, _, err = runCommandWithOutput(c) |
|
203 |
+ if err != nil { |
|
204 |
+ t.Fatalf("error tagging foobox: %s", err) |
|
205 |
+ } |
|
206 |
+ defer deleteImages("foobox") |
|
207 |
+ |
|
208 |
+ c = exec.Command(dockerBinary, "images", "-q", "-f", "dangling=true") |
|
209 |
+ out, _, err = runCommandWithOutput(c) |
|
210 |
+ if err != nil { |
|
211 |
+ t.Fatalf("listing images failed with errors: %s, %v", out, err) |
|
212 |
+ } |
|
213 |
+ |
|
214 |
+ if e, a := 1, strings.Count(out, imageId); e != a { |
|
215 |
+ t.Fatalf("expected 1 dangling image, got %d: %s", a, out) |
|
216 |
+ } |
|
217 |
+ |
|
218 |
+ logDone("images - dangling image only listed once") |
|
219 |
+} |