Browse code

Use stderr instead of logrus for CLI error messages

Signed-off-by: Doug Davis <dug@us.ibm.com>

Doug Davis authored on 2015/05/10 03:33:06
Showing 11 changed files
... ...
@@ -17,7 +17,6 @@ import (
17 17
 	"strconv"
18 18
 	"strings"
19 19
 
20
-	"github.com/Sirupsen/logrus"
21 20
 	"github.com/docker/docker/api"
22 21
 	"github.com/docker/docker/graph"
23 22
 	"github.com/docker/docker/pkg/archive"
... ...
@@ -192,7 +191,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
192 192
 	// windows: show error message about modified file permissions
193 193
 	// FIXME: this is not a valid warning when the daemon is running windows. should be removed once docker engine for windows can build.
194 194
 	if runtime.GOOS == "windows" {
195
-		logrus.Warn(`SECURITY WARNING: You are building a Docker image from Windows against a Linux Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.`)
195
+		fmt.Fprintln(cli.err, `SECURITY WARNING: You are building a Docker image from Windows against a Linux Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.`)
196 196
 	}
197 197
 
198 198
 	var body io.Reader
... ...
@@ -63,6 +63,14 @@ var funcMap = template.FuncMap{
63 63
 	},
64 64
 }
65 65
 
66
+func (cli *DockerCli) Out() io.Writer {
67
+	return cli.out
68
+}
69
+
70
+func (cli *DockerCli) Err() io.Writer {
71
+	return cli.err
72
+}
73
+
66 74
 func (cli *DockerCli) getMethod(args ...string) (func(...string) error, bool) {
67 75
 	camelArgs := make([]string, len(args))
68 76
 	for i, s := range args {
... ...
@@ -71,7 +71,7 @@ func (cli *DockerCli) CmdExec(args ...string) error {
71 71
 	defer func() {
72 72
 		logrus.Debugf("End of CmdExec(), Waiting for hijack to finish.")
73 73
 		if _, ok := <-hijacked; ok {
74
-			logrus.Errorf("Hijack did not finish (chan still open)")
74
+			fmt.Fprintln(cli.err, "Hijack did not finish (chan still open)")
75 75
 		}
76 76
 	}()
77 77
 
... ...
@@ -109,7 +109,7 @@ func (cli *DockerCli) CmdExec(args ...string) error {
109 109
 
110 110
 	if execConfig.Tty && cli.isTerminalIn {
111 111
 		if err := cli.monitorTtySize(execID, true); err != nil {
112
-			logrus.Errorf("Error monitoring TTY size: %s", err)
112
+			fmt.Fprintf(cli.err, "Error monitoring TTY size: %s\n", err)
113 113
 		}
114 114
 	}
115 115
 
... ...
@@ -133,7 +133,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
133 133
 	defer func() {
134 134
 		logrus.Debugf("End of CmdRun(), Waiting for hijack to finish.")
135 135
 		if _, ok := <-hijacked; ok {
136
-			logrus.Errorf("Hijack did not finish (chan still open)")
136
+			fmt.Fprintln(cli.err, "Hijack did not finish (chan still open)")
137 137
 		}
138 138
 	}()
139 139
 	if config.AttachStdin || config.AttachStdout || config.AttachStderr {
... ...
@@ -183,7 +183,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
183 183
 	defer func() {
184 184
 		if *flAutoRemove {
185 185
 			if _, _, err = readBody(cli.call("DELETE", "/containers/"+createResponse.ID+"?v=1", nil, nil)); err != nil {
186
-				logrus.Errorf("Error deleting container: %s", err)
186
+				fmt.Fprintf(cli.err, "Error deleting container: %s\n", err)
187 187
 			}
188 188
 		}
189 189
 	}()
... ...
@@ -195,7 +195,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
195 195
 
196 196
 	if (config.AttachStdin || config.AttachStdout || config.AttachStderr) && config.Tty && cli.isTerminalOut {
197 197
 		if err := cli.monitorTtySize(createResponse.ID, false); err != nil {
198
-			logrus.Errorf("Error monitoring TTY size: %s", err)
198
+			fmt.Fprintf(cli.err, "Error monitoring TTY size: %s\n", err)
199 199
 		}
200 200
 	}
201 201
 
... ...
@@ -30,7 +30,7 @@ func (cli *DockerCli) forwardAllSignals(cid string) chan os.Signal {
30 30
 				}
31 31
 			}
32 32
 			if sig == "" {
33
-				logrus.Errorf("Unsupported signal: %v. Discarding.", s)
33
+				fmt.Fprintf(cli.err, "Unsupported signal: %v. Discarding.\n", s)
34 34
 			}
35 35
 			if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/kill?signal=%s", cid, sig), nil, nil)); err != nil {
36 36
 				logrus.Debugf("Error sending signal: %s", err)
... ...
@@ -96,7 +96,7 @@ func (cli *DockerCli) CmdStart(args ...string) error {
96 96
 		defer func() {
97 97
 			logrus.Debugf("CmdStart() returned, defer waiting for hijack to finish.")
98 98
 			if _, ok := <-hijacked; ok {
99
-				logrus.Errorf("Hijack did not finish (chan still open)")
99
+				fmt.Fprintln(cli.err, "Hijack did not finish (chan still open)")
100 100
 			}
101 101
 			cli.in.Close()
102 102
 		}()
... ...
@@ -149,7 +149,7 @@ func (cli *DockerCli) CmdStart(args ...string) error {
149 149
 	if *openStdin || *attach {
150 150
 		if tty && cli.isTerminalOut {
151 151
 			if err := cli.monitorTtySize(cmd.Arg(0), false); err != nil {
152
-				logrus.Errorf("Error monitoring TTY size: %s", err)
152
+				fmt.Fprintf(cli.err, "Error monitoring TTY size: %s\n", err)
153 153
 			}
154 154
 		}
155 155
 		if attchErr := <-cErr; attchErr != nil {
... ...
@@ -5,7 +5,6 @@ import (
5 5
 	"fmt"
6 6
 	"runtime"
7 7
 
8
-	"github.com/Sirupsen/logrus"
9 8
 	"github.com/docker/docker/api"
10 9
 	"github.com/docker/docker/api/types"
11 10
 	"github.com/docker/docker/autogen/dockerversion"
... ...
@@ -40,7 +39,7 @@ func (cli *DockerCli) CmdVersion(args ...string) error {
40 40
 
41 41
 	var v types.Version
42 42
 	if err := json.NewDecoder(stream).Decode(&v); err != nil {
43
-		logrus.Errorf("Error reading remote version: %s", err)
43
+		fmt.Fprintf(cli.err, "Error reading remote version: %s\n", err)
44 44
 		return err
45 45
 	}
46 46
 
... ...
@@ -46,7 +46,8 @@ func main() {
46 46
 	if *flLogLevel != "" {
47 47
 		lvl, err := logrus.ParseLevel(*flLogLevel)
48 48
 		if err != nil {
49
-			logrus.Fatalf("Unable to parse logging level: %s", *flLogLevel)
49
+			fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", *flLogLevel)
50
+			os.Exit(1)
50 51
 		}
51 52
 		setLogLevel(lvl)
52 53
 	} else {
... ...
@@ -73,7 +74,12 @@ func main() {
73 73
 		}
74 74
 		defaultHost, err := opts.ValidateHost(defaultHost)
75 75
 		if err != nil {
76
-			logrus.Fatal(err)
76
+			if *flDaemon {
77
+				logrus.Fatal(err)
78
+			} else {
79
+				fmt.Fprint(os.Stderr, err)
80
+			}
81
+			os.Exit(1)
77 82
 		}
78 83
 		flHosts = append(flHosts, defaultHost)
79 84
 	}
... ...
@@ -90,7 +96,8 @@ func main() {
90 90
 	}
91 91
 
92 92
 	if len(flHosts) > 1 {
93
-		logrus.Fatal("Please specify only one -H")
93
+		fmt.Fprintf(os.Stderr, "Please specify only one -H")
94
+		os.Exit(0)
94 95
 	}
95 96
 	protoAddrParts := strings.SplitN(flHosts[0], "://", 2)
96 97
 
... ...
@@ -111,7 +118,8 @@ func main() {
111 111
 		certPool := x509.NewCertPool()
112 112
 		file, err := ioutil.ReadFile(*flCa)
113 113
 		if err != nil {
114
-			logrus.Fatalf("Couldn't read ca cert %s: %s", *flCa, err)
114
+			fmt.Fprintf(os.Stderr, "Couldn't read ca cert %s: %s\n", *flCa, err)
115
+			os.Exit(1)
115 116
 		}
116 117
 		certPool.AppendCertsFromPEM(file)
117 118
 		tlsConfig.RootCAs = certPool
... ...
@@ -126,7 +134,8 @@ func main() {
126 126
 			*flTls = true
127 127
 			cert, err := tls.LoadX509KeyPair(*flCert, *flKey)
128 128
 			if err != nil {
129
-				logrus.Fatalf("Couldn't load X509 key pair: %q. Make sure the key is encrypted", err)
129
+				fmt.Fprintf(os.Stderr, "Couldn't load X509 key pair: %q. Make sure the key is encrypted\n", err)
130
+				os.Exit(1)
130 131
 			}
131 132
 			tlsConfig.Certificates = []tls.Certificate{cert}
132 133
 		}
... ...
@@ -143,11 +152,13 @@ func main() {
143 143
 	if err := cli.Cmd(flag.Args()...); err != nil {
144 144
 		if sterr, ok := err.(client.StatusError); ok {
145 145
 			if sterr.Status != "" {
146
-				logrus.Println(sterr.Status)
146
+				fmt.Fprintln(cli.Err(), sterr.Status)
147
+				os.Exit(1)
147 148
 			}
148 149
 			os.Exit(sterr.StatusCode)
149 150
 		}
150
-		logrus.Fatal(err)
151
+		fmt.Fprintln(cli.Err(), err)
152
+		os.Exit(1)
151 153
 	}
152 154
 }
153 155
 
... ...
@@ -4808,7 +4808,7 @@ func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) {
4808 4808
 		c.Fatalf("test5 was supposed to fail to find passwd")
4809 4809
 	}
4810 4810
 
4811
-	if expected := fmt.Sprintf("The Dockerfile (%s) must be within the build context (.)", strings.Replace(nonDockerfileFile, `\`, `\\`, -1)); !strings.Contains(out, expected) {
4811
+	if expected := fmt.Sprintf("The Dockerfile (%s) must be within the build context (.)", nonDockerfileFile); !strings.Contains(out, expected) {
4812 4812
 		c.Fatalf("wrong error messsage:%v\nexpected to contain=%v", out, expected)
4813 4813
 	}
4814 4814
 
... ...
@@ -5404,7 +5404,7 @@ func (s *DockerSuite) TestBuildBadCmdFlag(c *check.C) {
5404 5404
 		c.Fatal("Build should have failed")
5405 5405
 	}
5406 5406
 
5407
-	exp := `"Unknown flag: boo"`
5407
+	exp := "\nUnknown flag: boo\n"
5408 5408
 	if !strings.Contains(out, exp) {
5409 5409
 		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
5410 5410
 	}
... ...
@@ -5421,7 +5421,7 @@ func (s *DockerSuite) TestBuildRUNErrMsg(c *check.C) {
5421 5421
 		c.Fatal("Should have failed to build")
5422 5422
 	}
5423 5423
 
5424
-	exp := "The command '/bin/sh -c badEXE a1 \\\\& a2\\ta3' returned a non-zero code: 127"
5424
+	exp := `The command '/bin/sh -c badEXE a1 \& a2	a3' returned a non-zero code: 127`
5425 5425
 	if !strings.Contains(out, exp) {
5426 5426
 		c.Fatalf("RUN doesn't have the correct output:\nGot:%s\nExpected:%s", out, exp)
5427 5427
 	}
... ...
@@ -907,8 +907,8 @@ func (s *DockerDaemonSuite) TestDaemonLoggingDriverNoneLogsError(c *check.C) {
907 907
 	if err == nil {
908 908
 		c.Fatalf("Logs should fail with \"none\" driver")
909 909
 	}
910
-	if !strings.Contains(out, `\"logs\" command is supported only for \"json-file\" logging driver`) {
911
-		c.Fatalf("There should be error about non-json-file driver, got %s", out)
910
+	if !strings.Contains(out, `"logs" command is supported only for "json-file" logging driver`) {
911
+		c.Fatalf("There should be error about non-json-file driver, got: %s", out)
912 912
 	}
913 913
 }
914 914
 
... ...
@@ -152,3 +152,32 @@ func (s *DockerSuite) TestHelpTextVerify(c *check.C) {
152 152
 	}
153 153
 
154 154
 }
155
+
156
+func (s *DockerSuite) TestHelpErrorStderr(c *check.C) {
157
+	// If we had a generic CLI test file this one shoudl go in there
158
+
159
+	cmd := exec.Command(dockerBinary, "boogie")
160
+	out, ec, err := runCommandWithOutput(cmd)
161
+	if err == nil || ec == 0 {
162
+		c.Fatalf("Boogie command should have failed")
163
+	}
164
+
165
+	expected := "docker: 'boogie' is not a docker command. See 'docker --help'.\n"
166
+	if out != expected {
167
+		c.Fatalf("Bad output from boogie\nGot:%s\nExpected:%s", out, expected)
168
+	}
169
+
170
+	cmd = exec.Command(dockerBinary, "rename", "foo", "bar")
171
+	out, ec, err = runCommandWithOutput(cmd)
172
+	if err == nil || ec == 0 {
173
+		c.Fatalf("Rename should have failed")
174
+	}
175
+
176
+	expected = `Error response from daemon: no such id: foo
177
+Error: failed to rename container named foo
178
+`
179
+	if out != expected {
180
+		c.Fatalf("Bad output from rename\nGot:%s\nExpected:%s", out, expected)
181
+	}
182
+
183
+}
... ...
@@ -2051,7 +2051,7 @@ func (s *DockerSuite) TestRunWithBadDevice(c *check.C) {
2051 2051
 	if err == nil {
2052 2052
 		c.Fatal("Run should fail with bad device")
2053 2053
 	}
2054
-	expected := `\"/etc\": not a device node`
2054
+	expected := `"/etc": not a device node`
2055 2055
 	if !strings.Contains(out, expected) {
2056 2056
 		c.Fatalf("Output should contain %q, actual out: %q", expected, out)
2057 2057
 	}