Browse code

Added tags list to /images/:id/json api.

It closes #10139.

Signed-off-by: Rozhnov Alexandr <nox73@ya.ru>

Rozhnov Alexandr authored on 2015/05/13 22:23:36
Showing 5 changed files
... ...
@@ -96,6 +96,7 @@ type GraphDriverData struct {
96 96
 // GET "/images/{name:.*}/json"
97 97
 type ImageInspect struct {
98 98
 	ID              string `json:"Id"`
99
+	Tags            []string
99 100
 	Parent          string
100 101
 	Comment         string
101 102
 	Created         string
... ...
@@ -81,6 +81,7 @@ This section lists each version from latest to oldest.  Each listing includes a
81 81
 * `GET /volumes/(name)` get low-level information about a volume.
82 82
 * `DELETE /volumes/(name)`remove a volume with the specified name.
83 83
 * `VolumeDriver` has been moved from config to hostConfig to make the configuration portable.
84
+* `GET /images/(name)/json` now returns information about tags of the image.
84 85
 
85 86
 
86 87
 ### v1.20 API changes
... ...
@@ -1433,7 +1433,7 @@ Return low-level information on the image `name`
1433 1433
 
1434 1434
 **Example request**:
1435 1435
 
1436
-    GET /images/ubuntu/json HTTP/1.1
1436
+    GET /images/example/json HTTP/1.1
1437 1437
 
1438 1438
 **Example response**:
1439 1439
 
... ...
@@ -1441,34 +1441,90 @@ Return low-level information on the image `name`
1441 1441
     Content-Type: application/json
1442 1442
 
1443 1443
     {
1444
-         "Created": "2013-03-23T22:24:18.818426-07:00",
1445
-         "Container": "3d67245a8d72ecf13f33dffac9f79dcdf70f75acb84d308770391510e0c23ad0",
1446
-         "ContainerConfig":
1447
-                 {
1448
-                         "Hostname": "",
1449
-                         "User": "",
1450
-                         "AttachStdin": false,
1451
-                         "AttachStdout": false,
1452
-                         "AttachStderr": false,
1453
-                         "Tty": true,
1454
-                         "OpenStdin": true,
1455
-                         "StdinOnce": false,
1456
-                         "Env": null,
1457
-                         "Cmd": ["/bin/bash"],
1458
-                         "Dns": null,
1459
-                         "Image": "ubuntu",
1460
-                         "Labels": {
1461
-                             "com.example.vendor": "Acme",
1462
-                             "com.example.license": "GPL",
1463
-                             "com.example.version": "1.0"
1464
-                         },
1465
-                         "Volumes": null,
1466
-                         "VolumesFrom": "",
1467
-                         "WorkingDir": ""
1468
-                 },
1469
-         "Id": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
1470
-         "Parent": "27cf784147099545",
1471
-         "Size": 6824592
1444
+       "Id" : "85f05633ddc1c50679be2b16a0479ab6f7637f8884e0cfe0f4d20e1ebb3d6e7c",
1445
+       "Container" : "cb91e48a60d01f1e27028b4fc6819f4f290b3cf12496c8176ec714d0d390984a",
1446
+       "Comment" : "",
1447
+       "Os" : "linux",
1448
+       "Architecture" : "amd64",
1449
+       "Parent" : "91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c",
1450
+       "ContainerConfig" : {
1451
+          "Tty" : false,
1452
+          "Hostname" : "e611e15f9c9d",
1453
+          "Volumes" : null,
1454
+          "Domainname" : "",
1455
+          "AttachStdout" : false,
1456
+          "PublishService" : "",
1457
+          "AttachStdin" : false,
1458
+          "OpenStdin" : false,
1459
+          "StdinOnce" : false,
1460
+          "NetworkDisabled" : false,
1461
+          "OnBuild" : [],
1462
+          "Image" : "91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c",
1463
+          "User" : "",
1464
+          "WorkingDir" : "",
1465
+          "Entrypoint" : null,
1466
+          "MacAddress" : "",
1467
+          "AttachStderr" : false,
1468
+          "Labels" : {
1469
+             "com.example.license" : "GPL",
1470
+             "com.example.version" : "1.0",
1471
+             "com.example.vendor" : "Acme"
1472
+          },
1473
+          "Env" : [
1474
+             "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
1475
+          ],
1476
+          "ExposedPorts" : null,
1477
+          "Cmd" : [
1478
+             "/bin/sh",
1479
+             "-c",
1480
+             "#(nop) LABEL com.example.vendor=Acme com.example.license=GPL com.example.version=1.0"
1481
+          ]
1482
+       },
1483
+       "DockerVersion" : "1.9.0-dev",
1484
+       "VirtualSize" : 188359297,
1485
+       "Size" : 0,
1486
+       "Author" : "",
1487
+       "Created" : "2015-09-10T08:30:53.26995814Z",
1488
+       "GraphDriver" : {
1489
+          "Name" : "aufs",
1490
+          "Data" : null
1491
+       },
1492
+       "Tags" : [
1493
+          "example:1.0",
1494
+          "example:latest",
1495
+          "example:stable"
1496
+       ],
1497
+       "Config" : {
1498
+          "Image" : "91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c",
1499
+          "NetworkDisabled" : false,
1500
+          "OnBuild" : [],
1501
+          "StdinOnce" : false,
1502
+          "PublishService" : "",
1503
+          "AttachStdin" : false,
1504
+          "OpenStdin" : false,
1505
+          "Domainname" : "",
1506
+          "AttachStdout" : false,
1507
+          "Tty" : false,
1508
+          "Hostname" : "e611e15f9c9d",
1509
+          "Volumes" : null,
1510
+          "Cmd" : [
1511
+             "/bin/bash"
1512
+          ],
1513
+          "ExposedPorts" : null,
1514
+          "Env" : [
1515
+             "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
1516
+          ],
1517
+          "Labels" : {
1518
+             "com.example.vendor" : "Acme",
1519
+             "com.example.version" : "1.0",
1520
+             "com.example.license" : "GPL"
1521
+          },
1522
+          "Entrypoint" : null,
1523
+          "MacAddress" : "",
1524
+          "AttachStderr" : false,
1525
+          "WorkingDir" : "",
1526
+          "User" : ""
1527
+       }
1472 1528
     }
1473 1529
 
1474 1530
 Status Codes:
... ...
@@ -8,6 +8,7 @@ import (
8 8
 
9 9
 	"github.com/Sirupsen/logrus"
10 10
 	"github.com/docker/docker/api/types"
11
+	"github.com/docker/docker/utils"
11 12
 )
12 13
 
13 14
 // lookupRaw looks up an image by name in a TagStore and returns the raw JSON
... ...
@@ -34,8 +35,22 @@ func (s *TagStore) Lookup(name string) (*types.ImageInspect, error) {
34 34
 		return nil, fmt.Errorf("No such image: %s", name)
35 35
 	}
36 36
 
37
+	var tags = make([]string, 0)
38
+
39
+	s.Lock()
40
+	for repoName, repository := range s.Repositories {
41
+		for ref, id := range repository {
42
+			if id == image.ID {
43
+				imgRef := utils.ImageReference(repoName, ref)
44
+				tags = append(tags, imgRef)
45
+			}
46
+		}
47
+	}
48
+	s.Unlock()
49
+
37 50
 	imageInspect := &types.ImageInspect{
38 51
 		ID:              image.ID,
52
+		Tags:            tags,
39 53
 		Parent:          image.Parent,
40 54
 		Comment:         image.Comment,
41 55
 		Created:         image.Created.Format(time.RFC3339Nano),
... ...
@@ -6,6 +6,8 @@ import (
6 6
 	"net/http"
7 7
 	"strings"
8 8
 
9
+	"github.com/docker/docker/api/types"
10
+	"github.com/docker/docker/pkg/stringutils"
9 11
 	"github.com/go-check/check"
10 12
 )
11 13
 
... ...
@@ -111,3 +113,23 @@ func (s *DockerSuite) TestInspectApiContainerVolumeDriver(c *check.C) {
111 111
 		c.Fatal("Api version 1.21 expected to include VolumeDriver in 'HostConfig'")
112 112
 	}
113 113
 }
114
+
115
+func (s *DockerSuite) TestInspectApiImageResponse(c *check.C) {
116
+	dockerCmd(c, "tag", "busybox:latest", "busybox:mytag")
117
+
118
+	endpoint := "/images/busybox/json"
119
+	status, body, err := sockRequest("GET", endpoint, nil)
120
+
121
+	c.Assert(err, check.IsNil)
122
+	c.Assert(status, check.Equals, http.StatusOK)
123
+
124
+	var imageJSON types.ImageInspect
125
+	if err = json.Unmarshal(body, &imageJSON); err != nil {
126
+		c.Fatalf("unable to unmarshal body for latest version: %v", err)
127
+	}
128
+
129
+	c.Assert(len(imageJSON.Tags), check.Equals, 2)
130
+
131
+	c.Assert(stringutils.InSlice(imageJSON.Tags, "busybox:latest"), check.Equals, true)
132
+	c.Assert(stringutils.InSlice(imageJSON.Tags, "busybox:mytag"), check.Equals, true)
133
+}