Browse code

Flag Addition: --type flag added for docker inspect command

Signed-off-by: Shishir Mahajan <shishir.mahajan@redhat.com>

Shishir Mahajan authored on 2015/06/26 23:47:31
Showing 5 changed files
... ...
@@ -18,42 +18,68 @@ import (
18 18
 func (cli *DockerCli) CmdInspect(args ...string) error {
19 19
 	cmd := cli.Subcmd("inspect", []string{"CONTAINER|IMAGE [CONTAINER|IMAGE...]"}, "Return low-level information on a container or image", true)
20 20
 	tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template")
21
+	inspectType := cmd.String([]string{"-type"}, "", "Return JSON for specified type, (e.g image or container)")
22
+
21 23
 	cmd.Require(flag.Min, 1)
22 24
 
23 25
 	cmd.ParseFlags(args, true)
24 26
 
25 27
 	var tmpl *template.Template
28
+	var err error
29
+	var obj []byte
30
+
26 31
 	if *tmplStr != "" {
27
-		var err error
28 32
 		if tmpl, err = template.New("").Funcs(funcMap).Parse(*tmplStr); err != nil {
29 33
 			return StatusError{StatusCode: 64,
30 34
 				Status: "Template parsing error: " + err.Error()}
31 35
 		}
32 36
 	}
33 37
 
38
+	if *inspectType != "" && *inspectType != "container" && *inspectType != "image" {
39
+		return fmt.Errorf("%q is not a valid value for --type", *inspectType)
40
+	}
41
+
34 42
 	indented := new(bytes.Buffer)
35 43
 	indented.WriteString("[\n")
36 44
 	status := 0
37 45
 	isImage := false
38 46
 
39 47
 	for _, name := range cmd.Args() {
40
-		obj, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil, nil))
41
-		if err != nil {
48
+
49
+		if *inspectType == "" || *inspectType == "container" {
50
+			obj, _, err = readBody(cli.call("GET", "/containers/"+name+"/json", nil, nil))
51
+			if err != nil && *inspectType == "container" {
52
+				if strings.Contains(err.Error(), "No such") {
53
+					fmt.Fprintf(cli.err, "Error: No such container: %s\n", name)
54
+				} else {
55
+					fmt.Fprintf(cli.err, "%s", err)
56
+				}
57
+				status = 1
58
+				continue
59
+			}
60
+		}
61
+
62
+		if obj == nil && (*inspectType == "" || *inspectType == "image") {
42 63
 			obj, _, err = readBody(cli.call("GET", "/images/"+name+"/json", nil, nil))
43 64
 			isImage = true
44 65
 			if err != nil {
45 66
 				if strings.Contains(err.Error(), "No such") {
46
-					fmt.Fprintf(cli.err, "Error: No such image or container: %s\n", name)
67
+					if *inspectType == "" {
68
+						fmt.Fprintf(cli.err, "Error: No such image or container: %s\n", name)
69
+					} else {
70
+						fmt.Fprintf(cli.err, "Error: No such image: %s\n", name)
71
+					}
47 72
 				} else {
48 73
 					fmt.Fprintf(cli.err, "%s", err)
49 74
 				}
50 75
 				status = 1
51 76
 				continue
52 77
 			}
78
+
53 79
 		}
54 80
 
55 81
 		if tmpl == nil {
56
-			if err = json.Indent(indented, obj, "", "    "); err != nil {
82
+			if err := json.Indent(indented, obj, "", "    "); err != nil {
57 83
 				fmt.Fprintf(cli.err, "%s\n", err)
58 84
 				status = 1
59 85
 				continue
... ...
@@ -527,11 +527,16 @@ _docker_inspect() {
527 527
 		--format|-f)
528 528
 			return
529 529
 			;;
530
+		--type)
531
+                     COMPREPLY=( $( compgen -W "image container" -- "$cur" ) )
532
+                     return
533
+                        ;;
534
+
530 535
 	esac
531 536
 
532 537
 	case "$cur" in
533 538
 		-*)
534
-			COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) )
539
+			COMPREPLY=( $( compgen -W "--format -f --type --help" -- "$cur" ) )
535 540
 			;;
536 541
 		*)
537 542
 			__docker_containers_and_images
... ...
@@ -17,6 +17,9 @@ weight=1
17 17
 
18 18
       -f, --format=""    Format the output using the given go template
19 19
 
20
+     --type=container|image  Return JSON for specified type, permissible 
21
+                             values are "image" or "container"
22
+
20 23
 By default, this will render all results in a JSON array. If a format is
21 24
 specified, the given template will be executed for each result.
22 25
 
... ...
@@ -38,6 +38,115 @@ func (s *DockerSuite) TestInspectInt64(c *check.C) {
38 38
 	}
39 39
 }
40 40
 
41
+func (s *DockerSuite) TestInspectDefault(c *check.C) {
42
+
43
+	//Both the container and image are named busybox. docker inspect will fetch the container JSON.
44
+	//If the container JSON is not available, it will go for the image JSON.
45
+
46
+	runCmd := exec.Command(dockerBinary, "run", "--name=busybox", "-d", "busybox", "true")
47
+	out, _, _, err := runCommandWithStdoutStderr(runCmd)
48
+	if err != nil {
49
+		c.Fatalf("failed to run container: %v, output: %q", err, out)
50
+	}
51
+
52
+	inspectCmd := exec.Command(dockerBinary, "inspect", "busybox")
53
+
54
+	_, exitCode, err := runCommandWithOutput(inspectCmd)
55
+	if exitCode != 0 || err != nil {
56
+		c.Fatalf("failed to inspect container: %s, %v", out, err)
57
+	}
58
+}
59
+
60
+func (s *DockerSuite) TestInspectTypeFlagContainer(c *check.C) {
61
+
62
+	//Both the container and image are named busybox. docker inspect will fetch container
63
+	//JSON State.Running field. If the field is true, it's a container.
64
+
65
+	runCmd := exec.Command(dockerBinary, "run", "--name=busybox", "-d", "busybox", "top")
66
+	out, _, _, err := runCommandWithStdoutStderr(runCmd)
67
+	if err != nil {
68
+		c.Fatalf("failed to run container: %v, output: %q", err, out)
69
+	}
70
+
71
+	formatStr := fmt.Sprintf("--format='{{.State.Running}}'")
72
+	inspectCmd := exec.Command(dockerBinary, "inspect", "--type=container", formatStr, "busybox")
73
+
74
+	out, exitCode, err := runCommandWithOutput(inspectCmd)
75
+	if exitCode != 0 || err != nil {
76
+		c.Fatalf("failed to inspect container: %s, %v", out, err)
77
+	}
78
+
79
+	if out != "true\n" {
80
+		c.Fatal("not a container JSON")
81
+	}
82
+}
83
+
84
+func (s *DockerSuite) TestInspectTypeFlagWithNoContainer(c *check.C) {
85
+
86
+	//Run this test on an image named busybox. docker inspect will try to fetch container
87
+	//JSON. Since there is no container named busybox and --type=container, docker inspect will
88
+	//not try to get the image JSON. It will throw an error.
89
+
90
+	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
91
+	out, _, _, err := runCommandWithStdoutStderr(runCmd)
92
+	if err != nil {
93
+		c.Fatalf("failed to run container: %v, output: %q", err, out)
94
+	}
95
+
96
+	inspectCmd := exec.Command(dockerBinary, "inspect", "--type=container", "busybox")
97
+
98
+	_, exitCode, err := runCommandWithOutput(inspectCmd)
99
+	if exitCode == 0 || err == nil {
100
+		c.Fatalf("docker inspect should have failed, as there is no container named busybox")
101
+	}
102
+}
103
+
104
+func (s *DockerSuite) TestInspectTypeFlagWithImage(c *check.C) {
105
+
106
+	//Both the container and image are named busybox. docker inspect will fetch image
107
+	//JSON as --type=image. if there is no image with name busybox, docker inspect
108
+	//will throw an error.
109
+
110
+	runCmd := exec.Command(dockerBinary, "run", "--name=busybox", "-d", "busybox", "true")
111
+	out, _, _, err := runCommandWithStdoutStderr(runCmd)
112
+	if err != nil {
113
+		c.Fatalf("failed to run container: %v, output: %q", err, out)
114
+	}
115
+
116
+	inspectCmd := exec.Command(dockerBinary, "inspect", "--type=image", "busybox")
117
+
118
+	out, exitCode, err := runCommandWithOutput(inspectCmd)
119
+	if exitCode != 0 || err != nil {
120
+		c.Fatalf("failed to inspect image: %s, %v", out, err)
121
+	}
122
+
123
+	if strings.Contains(out, "State") {
124
+		c.Fatal("not an image JSON")
125
+	}
126
+
127
+}
128
+
129
+func (s *DockerSuite) TestInspectTypeFlagWithInvalidValue(c *check.C) {
130
+
131
+	//Both the container and image are named busybox. docker inspect will fail
132
+	//as --type=foobar is not a valid value for the flag.
133
+
134
+	runCmd := exec.Command(dockerBinary, "run", "--name=busybox", "-d", "busybox", "true")
135
+	out, _, _, err := runCommandWithStdoutStderr(runCmd)
136
+	if err != nil {
137
+		c.Fatalf("failed to run container: %v, output: %q", err, out)
138
+	}
139
+
140
+	inspectCmd := exec.Command(dockerBinary, "inspect", "--type=foobar", "busybox")
141
+
142
+	out, exitCode, err := runCommandWithOutput(inspectCmd)
143
+	if exitCode != 0 || err != nil {
144
+		if !strings.Contains(out, "not a valid value for --type") {
145
+			c.Fatalf("failed to inspect image: %s, %v", out, err)
146
+		}
147
+	}
148
+}
149
+
41 150
 func (s *DockerSuite) TestInspectImageFilterInt(c *check.C) {
42 151
 	imageTest := "emptyfs"
43 152
 	out, err := inspectField(imageTest, "Size")
... ...
@@ -8,6 +8,7 @@ docker-inspect - Return low-level information on a container or image
8 8
 **docker inspect**
9 9
 [**--help**]
10 10
 [**-f**|**--format**[=*FORMAT*]]
11
+[**--type**=*container*|*image*]
11 12
 CONTAINER|IMAGE [CONTAINER|IMAGE...]
12 13
 
13 14
 # DESCRIPTION
... ...
@@ -24,14 +25,29 @@ each result.
24 24
 **-f**, **--format**=""
25 25
     Format the output using the given go template.
26 26
 
27
+**--type**=*container*|*image*
28
+    Return JSON for specified type, permissible values are "image" or "container"
29
+
27 30
 # EXAMPLES
28 31
 
32
+Getting information on an image where image name conflict with the container name,
33
+e,g both image and container are named rhel7.
34
+
35
+    $ docker inspect --type=image rhel7
36
+    [
37
+    {
38
+     "Id": "fe01a428b9d9de35d29531e9994157978e8c48fa693e1bf1d221dffbbb67b170",
39
+     "Parent": "10acc31def5d6f249b548e01e8ffbaccfd61af0240c17315a7ad393d022c5ca2",
40
+     ....
41
+    }
42
+    ]
43
+
29 44
 ## Getting information on a container
30 45
 
31 46
 To get information on a container use its ID or instance name:
32 47
 
33 48
     $ docker inspect d2cc496561d6
34
-[{
49
+    [{
35 50
     "Id": "d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47",
36 51
     "Created": "2015-06-08T16:18:02.505155285Z",
37 52
     "Path": "bash",
... ...
@@ -161,8 +177,8 @@ To get information on a container use its ID or instance name:
161 161
         "CpuShares": 0,
162 162
         "Cpuset": ""
163 163
     }
164
-}
165
-]
164
+    }
165
+    ]
166 166
 ## Getting the IP address of a container instance
167 167
 
168 168
 To get the IP address of a container use:
... ...
@@ -188,7 +204,7 @@ Use an image's ID or name (e.g., repository/name[:tag]) to get information
188 188
 on it.
189 189
 
190 190
     $ docker inspect ded7cd95e059
191
-[{
191
+    [{
192 192
     "Id": "ded7cd95e059788f2586a51c275a4f151653779d6a7f4dad77c2bd34601d94e4",
193 193
     "Parent": "48ecf305d2cf7046c1f5f8fcbcd4994403173441d4a7f125b1bb0ceead9de731",
194 194
     "Comment": "",
... ...
@@ -258,8 +274,8 @@ on it.
258 258
             "DeviceSize": "171798691840"
259 259
         }
260 260
     }
261
-}
262
-]
261
+    }
262
+    ]
263 263
 
264 264
 # HISTORY
265 265
 April 2014, originally compiled by William Henry (whenry at redhat dot com)