mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #13106 from duglin/HumanizeCliErrors
Use stderr instead of logrus for CLI error messages
This commit is contained in:
commit
56847ec4d4
11 changed files with 71 additions and 25 deletions
|
@ -17,7 +17,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
|
||||||
"github.com/docker/docker/api"
|
"github.com/docker/docker/api"
|
||||||
"github.com/docker/docker/graph/tags"
|
"github.com/docker/docker/graph/tags"
|
||||||
"github.com/docker/docker/pkg/archive"
|
"github.com/docker/docker/pkg/archive"
|
||||||
|
@ -192,7 +191,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
|
||||||
// windows: show error message about modified file permissions
|
// windows: show error message about modified file permissions
|
||||||
// FIXME: this is not a valid warning when the daemon is running windows. should be removed once docker engine for windows can build.
|
// FIXME: this is not a valid warning when the daemon is running windows. should be removed once docker engine for windows can build.
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
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.`)
|
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.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
var body io.Reader
|
var body io.Reader
|
||||||
|
|
|
@ -63,6 +63,14 @@ var funcMap = template.FuncMap{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cli *DockerCli) Out() io.Writer {
|
||||||
|
return cli.out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cli *DockerCli) Err() io.Writer {
|
||||||
|
return cli.err
|
||||||
|
}
|
||||||
|
|
||||||
func (cli *DockerCli) getMethod(args ...string) (func(...string) error, bool) {
|
func (cli *DockerCli) getMethod(args ...string) (func(...string) error, bool) {
|
||||||
camelArgs := make([]string, len(args))
|
camelArgs := make([]string, len(args))
|
||||||
for i, s := range args {
|
for i, s := range args {
|
||||||
|
|
|
@ -71,7 +71,7 @@ func (cli *DockerCli) CmdExec(args ...string) error {
|
||||||
defer func() {
|
defer func() {
|
||||||
logrus.Debugf("End of CmdExec(), Waiting for hijack to finish.")
|
logrus.Debugf("End of CmdExec(), Waiting for hijack to finish.")
|
||||||
if _, ok := <-hijacked; ok {
|
if _, ok := <-hijacked; ok {
|
||||||
logrus.Errorf("Hijack did not finish (chan still open)")
|
fmt.Fprintln(cli.err, "Hijack did not finish (chan still open)")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ func (cli *DockerCli) CmdExec(args ...string) error {
|
||||||
|
|
||||||
if execConfig.Tty && cli.isTerminalIn {
|
if execConfig.Tty && cli.isTerminalIn {
|
||||||
if err := cli.monitorTtySize(execID, true); err != nil {
|
if err := cli.monitorTtySize(execID, true); err != nil {
|
||||||
logrus.Errorf("Error monitoring TTY size: %s", err)
|
fmt.Fprintf(cli.err, "Error monitoring TTY size: %s\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
|
||||||
defer func() {
|
defer func() {
|
||||||
logrus.Debugf("End of CmdRun(), Waiting for hijack to finish.")
|
logrus.Debugf("End of CmdRun(), Waiting for hijack to finish.")
|
||||||
if _, ok := <-hijacked; ok {
|
if _, ok := <-hijacked; ok {
|
||||||
logrus.Errorf("Hijack did not finish (chan still open)")
|
fmt.Fprintln(cli.err, "Hijack did not finish (chan still open)")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if config.AttachStdin || config.AttachStdout || config.AttachStderr {
|
if config.AttachStdin || config.AttachStdout || config.AttachStderr {
|
||||||
|
@ -183,7 +183,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
|
||||||
defer func() {
|
defer func() {
|
||||||
if *flAutoRemove {
|
if *flAutoRemove {
|
||||||
if _, _, err = readBody(cli.call("DELETE", "/containers/"+createResponse.ID+"?v=1", nil, nil)); err != nil {
|
if _, _, err = readBody(cli.call("DELETE", "/containers/"+createResponse.ID+"?v=1", nil, nil)); err != nil {
|
||||||
logrus.Errorf("Error deleting container: %s", err)
|
fmt.Fprintf(cli.err, "Error deleting container: %s\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -195,7 +195,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
|
||||||
|
|
||||||
if (config.AttachStdin || config.AttachStdout || config.AttachStderr) && config.Tty && cli.isTerminalOut {
|
if (config.AttachStdin || config.AttachStdout || config.AttachStderr) && config.Tty && cli.isTerminalOut {
|
||||||
if err := cli.monitorTtySize(createResponse.ID, false); err != nil {
|
if err := cli.monitorTtySize(createResponse.ID, false); err != nil {
|
||||||
logrus.Errorf("Error monitoring TTY size: %s", err)
|
fmt.Fprintf(cli.err, "Error monitoring TTY size: %s\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ func (cli *DockerCli) forwardAllSignals(cid string) chan os.Signal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if sig == "" {
|
if sig == "" {
|
||||||
logrus.Errorf("Unsupported signal: %v. Discarding.", s)
|
fmt.Fprintf(cli.err, "Unsupported signal: %v. Discarding.\n", s)
|
||||||
}
|
}
|
||||||
if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/kill?signal=%s", cid, sig), nil, nil)); err != nil {
|
if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/kill?signal=%s", cid, sig), nil, nil)); err != nil {
|
||||||
logrus.Debugf("Error sending signal: %s", err)
|
logrus.Debugf("Error sending signal: %s", err)
|
||||||
|
@ -96,7 +96,7 @@ func (cli *DockerCli) CmdStart(args ...string) error {
|
||||||
defer func() {
|
defer func() {
|
||||||
logrus.Debugf("CmdStart() returned, defer waiting for hijack to finish.")
|
logrus.Debugf("CmdStart() returned, defer waiting for hijack to finish.")
|
||||||
if _, ok := <-hijacked; ok {
|
if _, ok := <-hijacked; ok {
|
||||||
logrus.Errorf("Hijack did not finish (chan still open)")
|
fmt.Fprintln(cli.err, "Hijack did not finish (chan still open)")
|
||||||
}
|
}
|
||||||
cli.in.Close()
|
cli.in.Close()
|
||||||
}()
|
}()
|
||||||
|
@ -149,7 +149,7 @@ func (cli *DockerCli) CmdStart(args ...string) error {
|
||||||
if *openStdin || *attach {
|
if *openStdin || *attach {
|
||||||
if tty && cli.isTerminalOut {
|
if tty && cli.isTerminalOut {
|
||||||
if err := cli.monitorTtySize(cmd.Arg(0), false); err != nil {
|
if err := cli.monitorTtySize(cmd.Arg(0), false); err != nil {
|
||||||
logrus.Errorf("Error monitoring TTY size: %s", err)
|
fmt.Fprintf(cli.err, "Error monitoring TTY size: %s\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if attchErr := <-cErr; attchErr != nil {
|
if attchErr := <-cErr; attchErr != nil {
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
|
||||||
"github.com/docker/docker/api"
|
"github.com/docker/docker/api"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/autogen/dockerversion"
|
"github.com/docker/docker/autogen/dockerversion"
|
||||||
|
@ -40,7 +39,7 @@ func (cli *DockerCli) CmdVersion(args ...string) error {
|
||||||
|
|
||||||
var v types.Version
|
var v types.Version
|
||||||
if err := json.NewDecoder(stream).Decode(&v); err != nil {
|
if err := json.NewDecoder(stream).Decode(&v); err != nil {
|
||||||
logrus.Errorf("Error reading remote version: %s", err)
|
fmt.Fprintf(cli.err, "Error reading remote version: %s\n", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,8 @@ func main() {
|
||||||
if *flLogLevel != "" {
|
if *flLogLevel != "" {
|
||||||
lvl, err := logrus.ParseLevel(*flLogLevel)
|
lvl, err := logrus.ParseLevel(*flLogLevel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatalf("Unable to parse logging level: %s", *flLogLevel)
|
fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", *flLogLevel)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
setLogLevel(lvl)
|
setLogLevel(lvl)
|
||||||
} else {
|
} else {
|
||||||
|
@ -70,7 +71,12 @@ func main() {
|
||||||
}
|
}
|
||||||
defaultHost, err := opts.ValidateHost(defaultHost)
|
defaultHost, err := opts.ValidateHost(defaultHost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
if *flDaemon {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
} else {
|
||||||
|
fmt.Fprint(os.Stderr, err)
|
||||||
|
}
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
flHosts = append(flHosts, defaultHost)
|
flHosts = append(flHosts, defaultHost)
|
||||||
}
|
}
|
||||||
|
@ -87,7 +93,8 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flHosts) > 1 {
|
if len(flHosts) > 1 {
|
||||||
logrus.Fatal("Please specify only one -H")
|
fmt.Fprintf(os.Stderr, "Please specify only one -H")
|
||||||
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
protoAddrParts := strings.SplitN(flHosts[0], "://", 2)
|
protoAddrParts := strings.SplitN(flHosts[0], "://", 2)
|
||||||
|
|
||||||
|
@ -108,7 +115,8 @@ func main() {
|
||||||
certPool := x509.NewCertPool()
|
certPool := x509.NewCertPool()
|
||||||
file, err := ioutil.ReadFile(*flCa)
|
file, err := ioutil.ReadFile(*flCa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatalf("Couldn't read ca cert %s: %s", *flCa, err)
|
fmt.Fprintf(os.Stderr, "Couldn't read ca cert %s: %s\n", *flCa, err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
certPool.AppendCertsFromPEM(file)
|
certPool.AppendCertsFromPEM(file)
|
||||||
tlsConfig.RootCAs = certPool
|
tlsConfig.RootCAs = certPool
|
||||||
|
@ -123,7 +131,8 @@ func main() {
|
||||||
*flTls = true
|
*flTls = true
|
||||||
cert, err := tls.LoadX509KeyPair(*flCert, *flKey)
|
cert, err := tls.LoadX509KeyPair(*flCert, *flKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatalf("Couldn't load X509 key pair: %q. Make sure the key is encrypted", err)
|
fmt.Fprintf(os.Stderr, "Couldn't load X509 key pair: %q. Make sure the key is encrypted\n", err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||||
}
|
}
|
||||||
|
@ -140,11 +149,13 @@ func main() {
|
||||||
if err := cli.Cmd(flag.Args()...); err != nil {
|
if err := cli.Cmd(flag.Args()...); err != nil {
|
||||||
if sterr, ok := err.(client.StatusError); ok {
|
if sterr, ok := err.(client.StatusError); ok {
|
||||||
if sterr.Status != "" {
|
if sterr.Status != "" {
|
||||||
logrus.Println(sterr.Status)
|
fmt.Fprintln(cli.Err(), sterr.Status)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
os.Exit(sterr.StatusCode)
|
os.Exit(sterr.StatusCode)
|
||||||
}
|
}
|
||||||
logrus.Fatal(err)
|
fmt.Fprintln(cli.Err(), err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4808,7 +4808,7 @@ func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) {
|
||||||
c.Fatalf("test5 was supposed to fail to find passwd")
|
c.Fatalf("test5 was supposed to fail to find passwd")
|
||||||
}
|
}
|
||||||
|
|
||||||
if expected := fmt.Sprintf("The Dockerfile (%s) must be within the build context (.)", strings.Replace(nonDockerfileFile, `\`, `\\`, -1)); !strings.Contains(out, expected) {
|
if expected := fmt.Sprintf("The Dockerfile (%s) must be within the build context (.)", nonDockerfileFile); !strings.Contains(out, expected) {
|
||||||
c.Fatalf("wrong error messsage:%v\nexpected to contain=%v", out, expected)
|
c.Fatalf("wrong error messsage:%v\nexpected to contain=%v", out, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5404,7 +5404,7 @@ func (s *DockerSuite) TestBuildBadCmdFlag(c *check.C) {
|
||||||
c.Fatal("Build should have failed")
|
c.Fatal("Build should have failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
exp := `"Unknown flag: boo"`
|
exp := "\nUnknown flag: boo\n"
|
||||||
if !strings.Contains(out, exp) {
|
if !strings.Contains(out, exp) {
|
||||||
c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
|
c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
|
||||||
}
|
}
|
||||||
|
@ -5421,7 +5421,7 @@ func (s *DockerSuite) TestBuildRUNErrMsg(c *check.C) {
|
||||||
c.Fatal("Should have failed to build")
|
c.Fatal("Should have failed to build")
|
||||||
}
|
}
|
||||||
|
|
||||||
exp := "The command '/bin/sh -c badEXE a1 \\\\& a2\\ta3' returned a non-zero code: 127"
|
exp := `The command '/bin/sh -c badEXE a1 \& a2 a3' returned a non-zero code: 127`
|
||||||
if !strings.Contains(out, exp) {
|
if !strings.Contains(out, exp) {
|
||||||
c.Fatalf("RUN doesn't have the correct output:\nGot:%s\nExpected:%s", out, exp)
|
c.Fatalf("RUN doesn't have the correct output:\nGot:%s\nExpected:%s", out, exp)
|
||||||
}
|
}
|
||||||
|
|
|
@ -907,8 +907,8 @@ func (s *DockerDaemonSuite) TestDaemonLoggingDriverNoneLogsError(c *check.C) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.Fatalf("Logs should fail with \"none\" driver")
|
c.Fatalf("Logs should fail with \"none\" driver")
|
||||||
}
|
}
|
||||||
if !strings.Contains(out, `\"logs\" command is supported only for \"json-file\" logging driver`) {
|
if !strings.Contains(out, `"logs" command is supported only for "json-file" logging driver`) {
|
||||||
c.Fatalf("There should be error about non-json-file driver, got %s", out)
|
c.Fatalf("There should be error about non-json-file driver, got: %s", out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,3 +152,32 @@ func (s *DockerSuite) TestHelpTextVerify(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DockerSuite) TestHelpErrorStderr(c *check.C) {
|
||||||
|
// If we had a generic CLI test file this one shoudl go in there
|
||||||
|
|
||||||
|
cmd := exec.Command(dockerBinary, "boogie")
|
||||||
|
out, ec, err := runCommandWithOutput(cmd)
|
||||||
|
if err == nil || ec == 0 {
|
||||||
|
c.Fatalf("Boogie command should have failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := "docker: 'boogie' is not a docker command. See 'docker --help'.\n"
|
||||||
|
if out != expected {
|
||||||
|
c.Fatalf("Bad output from boogie\nGot:%s\nExpected:%s", out, expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = exec.Command(dockerBinary, "rename", "foo", "bar")
|
||||||
|
out, ec, err = runCommandWithOutput(cmd)
|
||||||
|
if err == nil || ec == 0 {
|
||||||
|
c.Fatalf("Rename should have failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
expected = `Error response from daemon: no such id: foo
|
||||||
|
Error: failed to rename container named foo
|
||||||
|
`
|
||||||
|
if out != expected {
|
||||||
|
c.Fatalf("Bad output from rename\nGot:%s\nExpected:%s", out, expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -2051,7 +2051,7 @@ func (s *DockerSuite) TestRunWithBadDevice(c *check.C) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.Fatal("Run should fail with bad device")
|
c.Fatal("Run should fail with bad device")
|
||||||
}
|
}
|
||||||
expected := `\"/etc\": not a device node`
|
expected := `"/etc": not a device node`
|
||||||
if !strings.Contains(out, expected) {
|
if !strings.Contains(out, expected) {
|
||||||
c.Fatalf("Output should contain %q, actual out: %q", expected, out)
|
c.Fatalf("Output should contain %q, actual out: %q", expected, out)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue