Browse code

Use RepoTags & RepoDigest in inspect

To be coherent with /images/json (images command)

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2015/10/22 19:34:12
Showing 7 changed files
... ...
@@ -96,7 +96,8 @@ type GraphDriverData struct {
96 96
 // GET "/images/{name:.*}/json"
97 97
 type ImageInspect struct {
98 98
 	ID              string `json:"Id"`
99
-	Tags            []string
99
+	RepoTags        []string
100
+	RepoDigests     []string
100 101
 	Parent          string
101 102
 	Comment         string
102 103
 	Created         string
... ...
@@ -104,7 +104,7 @@ This section lists each version from latest to oldest.  Each listing includes a
104 104
 * `GET /volumes/(name)` get low-level information about a volume.
105 105
 * `DELETE /volumes/(name)`remove a volume with the specified name.
106 106
 * `VolumeDriver` has been moved from config to hostConfig to make the configuration portable.
107
-* `GET /images/(name)/json` now returns information about tags of the image.
107
+* `GET /images/(name)/json` now returns information about tags and digests of the image.
108 108
 * The `config` option now accepts the field `StopSignal`, which specifies the signal to use to kill a container.
109 109
 * `GET /containers/(id)/stats` will return networking information respectively for each interface.
110 110
 * The `hostConfig` option now accepts the field `DnsOptions`, which specifies a
... ...
@@ -1550,7 +1550,10 @@ Return low-level information on the image `name`
1550 1550
           "Name" : "aufs",
1551 1551
           "Data" : null
1552 1552
        },
1553
-       "Tags" : [
1553
+       "RepoDigests" : [
1554
+          "localhost:5000/test/busybox/example@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf"
1555
+       ],
1556
+       "RepoTags" : [
1554 1557
           "example:1.0",
1555 1558
           "example:latest",
1556 1559
           "example:stable"
... ...
@@ -1547,7 +1547,10 @@ Return low-level information on the image `name`
1547 1547
           "Name" : "aufs",
1548 1548
           "Data" : null
1549 1549
        },
1550
-       "Tags" : [
1550
+       "RepoDigests" : [
1551
+          "localhost:5000/test/busybox/example@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf"
1552
+       ],
1553
+       "RepoTags" : [
1551 1554
           "example:1.0",
1552 1555
           "example:latest",
1553 1556
           "example:stable"
... ...
@@ -19,14 +19,19 @@ func (s *TagStore) Lookup(name string) (*types.ImageInspect, error) {
19 19
 		return nil, fmt.Errorf("No such image: %s", name)
20 20
 	}
21 21
 
22
-	var tags = make([]string, 0)
22
+	var repoTags = make([]string, 0)
23
+	var repoDigests = make([]string, 0)
23 24
 
24 25
 	s.Lock()
25 26
 	for repoName, repository := range s.Repositories {
26 27
 		for ref, id := range repository {
27 28
 			if id == image.ID {
28 29
 				imgRef := utils.ImageReference(repoName, ref)
29
-				tags = append(tags, imgRef)
30
+				if utils.DigestReference(ref) {
31
+					repoDigests = append(repoDigests, imgRef)
32
+				} else {
33
+					repoTags = append(repoTags, imgRef)
34
+				}
30 35
 			}
31 36
 		}
32 37
 	}
... ...
@@ -34,7 +39,8 @@ func (s *TagStore) Lookup(name string) (*types.ImageInspect, error) {
34 34
 
35 35
 	imageInspect := &types.ImageInspect{
36 36
 		ID:              image.ID,
37
-		Tags:            tags,
37
+		RepoTags:        repoTags,
38
+		RepoDigests:     repoDigests,
38 39
 		Parent:          image.Parent,
39 40
 		Comment:         image.Comment,
40 41
 		Created:         image.Created.Format(time.RFC3339Nano),
... ...
@@ -128,10 +128,10 @@ func (s *DockerSuite) TestInspectApiImageResponse(c *check.C) {
128 128
 		c.Fatalf("unable to unmarshal body for latest version: %v", err)
129 129
 	}
130 130
 
131
-	c.Assert(len(imageJSON.Tags), check.Equals, 2)
131
+	c.Assert(len(imageJSON.RepoTags), check.Equals, 2)
132 132
 
133
-	c.Assert(stringutils.InSlice(imageJSON.Tags, "busybox:latest"), check.Equals, true)
134
-	c.Assert(stringutils.InSlice(imageJSON.Tags, "busybox:mytag"), check.Equals, true)
133
+	c.Assert(stringutils.InSlice(imageJSON.RepoTags, "busybox:latest"), check.Equals, true)
134
+	c.Assert(stringutils.InSlice(imageJSON.RepoTags, "busybox:mytag"), check.Equals, true)
135 135
 }
136 136
 
137 137
 // #17131, #17139, #17173
... ...
@@ -8,6 +8,8 @@ import (
8 8
 
9 9
 	"github.com/docker/distribution/digest"
10 10
 	"github.com/docker/distribution/manifest"
11
+	"github.com/docker/docker/api/types"
12
+	"github.com/docker/docker/pkg/stringutils"
11 13
 	"github.com/docker/docker/utils"
12 14
 	"github.com/go-check/check"
13 15
 )
... ...
@@ -390,6 +392,27 @@ func (s *DockerRegistrySuite) TestListImagesWithDigests(c *check.C) {
390 390
 	}
391 391
 }
392 392
 
393
+func (s *DockerRegistrySuite) TestInspectImageWithDigests(c *check.C) {
394
+	digest, err := setupImage(c)
395
+	c.Assert(err, check.IsNil, check.Commentf("error setting up image: %v", err))
396
+
397
+	imageReference := fmt.Sprintf("%s@%s", repoName, digest)
398
+
399
+	// pull from the registry using the <name>@<digest> reference
400
+	dockerCmd(c, "pull", imageReference)
401
+
402
+	out, _ := dockerCmd(c, "inspect", imageReference)
403
+
404
+	var imageJSON []types.ImageInspect
405
+	if err = json.Unmarshal([]byte(out), &imageJSON); err != nil {
406
+		c.Fatalf("unable to unmarshal body for latest version: %v", err)
407
+	}
408
+
409
+	c.Assert(len(imageJSON), check.Equals, 1)
410
+	c.Assert(len(imageJSON[0].RepoDigests), check.Equals, 1)
411
+	c.Assert(stringutils.InSlice(imageJSON[0].RepoDigests, imageReference), check.Equals, true)
412
+}
413
+
393 414
 func (s *DockerRegistrySuite) TestPsListContainersFilterAncestorImageByDigest(c *check.C) {
394 415
 	digest, err := setupImage(c)
395 416
 	c.Assert(err, check.IsNil, check.Commentf("error setting up image: %v", err))