Browse code

Return error code when `volume inspect` fails with a template.

Following `docker inspect` conventions:

- Keep partial info in a buffer to not print incomplete template outputs.
- Break execution when template parsing or decoding fail.

Signed-off-by: David Calavera <david.calavera@gmail.com>

David Calavera authored on 2015/12/03 05:24:30
Showing 2 changed files
... ...
@@ -124,6 +124,7 @@ func (cli *DockerCli) CmdVolumeInspect(args ...string) error {
124 124
 
125 125
 	var status = 0
126 126
 	var volumes []*types.Volume
127
+
127 128
 	for _, name := range cmd.Args() {
128 129
 		resp, err := cli.call("GET", "/volumes/"+name, nil, nil)
129 130
 		if err != nil {
... ...
@@ -132,9 +133,9 @@ func (cli *DockerCli) CmdVolumeInspect(args ...string) error {
132 132
 
133 133
 		var volume types.Volume
134 134
 		if err := json.NewDecoder(resp.body).Decode(&volume); err != nil {
135
-			fmt.Fprintf(cli.err, "%s\n", err)
135
+			fmt.Fprintf(cli.err, "Unable to read inspect data: %v\n", err)
136 136
 			status = 1
137
-			continue
137
+			break
138 138
 		}
139 139
 
140 140
 		if tmpl == nil {
... ...
@@ -142,29 +143,28 @@ func (cli *DockerCli) CmdVolumeInspect(args ...string) error {
142 142
 			continue
143 143
 		}
144 144
 
145
-		if err := tmpl.Execute(cli.out, &volume); err != nil {
146
-			if err := tmpl.Execute(cli.out, &volume); err != nil {
147
-				fmt.Fprintf(cli.err, "%s\n", err)
148
-				status = 1
149
-				continue
150
-			}
145
+		buf := bytes.NewBufferString("")
146
+		if err := tmpl.Execute(buf, &volume); err != nil {
147
+			fmt.Fprintf(cli.err, "Template parsing error: %v\n", err)
148
+			status = 1
149
+			break
151 150
 		}
152
-		io.WriteString(cli.out, "\n")
153
-	}
154 151
 
155
-	if tmpl != nil {
156
-		return nil
152
+		cli.out.Write(buf.Bytes())
153
+		cli.out.Write([]byte{'\n'})
157 154
 	}
158 155
 
159
-	b, err := json.MarshalIndent(volumes, "", "    ")
160
-	if err != nil {
161
-		return err
162
-	}
163
-	_, err = io.Copy(cli.out, bytes.NewReader(b))
164
-	if err != nil {
165
-		return err
156
+	if tmpl == nil {
157
+		b, err := json.MarshalIndent(volumes, "", "    ")
158
+		if err != nil {
159
+			return err
160
+		}
161
+		_, err = io.Copy(cli.out, bytes.NewReader(b))
162
+		if err != nil {
163
+			return err
164
+		}
165
+		io.WriteString(cli.out, "\n")
166 166
 	}
167
-	io.WriteString(cli.out, "\n")
168 167
 
169 168
 	if status != 0 {
170 169
 		return Cli.StatusError{StatusCode: status}
... ...
@@ -165,3 +165,13 @@ func (s *DockerSuite) TestVolumeCliNoArgs(c *check.C) {
165 165
 	c.Assert(stderr, checker.Contains, usage)
166 166
 	c.Assert(stderr, checker.Contains, "flag provided but not defined: --no-such-flag")
167 167
 }
168
+
169
+func (s *DockerSuite) TestVolumeCliInspectTmplError(c *check.C) {
170
+	out, _ := dockerCmd(c, "volume", "create")
171
+	name := strings.TrimSpace(out)
172
+
173
+	out, exitCode, err := dockerCmdWithError("volume", "inspect", "--format='{{ .FooBar }}'", name)
174
+	c.Assert(err, checker.NotNil, check.Commentf("Output: %s", out))
175
+	c.Assert(exitCode, checker.Equals, 1, check.Commentf("Output: %s", out))
176
+	c.Assert(out, checker.Contains, "Template parsing error")
177
+}