From f078f75bf25353720f28f9f1ea180374fe205302 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Mon, 10 Aug 2015 09:48:39 -0400 Subject: [PATCH] Return better errors from exec Also cleans up some of the API side of exec. Was writing the header twice (two different headers). Signed-off-by: Brian Goff --- api/server/exec.go | 26 +++++++++----------------- daemon/exec.go | 13 +++++++++---- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/api/server/exec.go b/api/server/exec.go index ed586569d5..70dcfacc00 100644 --- a/api/server/exec.go +++ b/api/server/exec.go @@ -64,10 +64,9 @@ func (s *Server) postContainerExecStart(version version.Version, w http.Response return err } var ( - execName = vars["name"] - stdin io.ReadCloser - stdout io.Writer - stderr io.Writer + execName = vars["name"] + stdin, inStream io.ReadCloser + stdout, stderr, outStream io.Writer ) execStartCheck := &types.ExecStartCheck{} @@ -76,15 +75,14 @@ func (s *Server) postContainerExecStart(version version.Version, w http.Response } if !execStartCheck.Detach { + var err error // Setting up the streaming http interface. - inStream, outStream, err := hijackServer(w) + inStream, outStream, err = hijackServer(w) if err != nil { return err } defer closeStreams(inStream, outStream) - var errStream io.Writer - if _, ok := r.Header["Upgrade"]; ok { fmt.Fprintf(outStream, "HTTP/1.1 101 UPGRADED\r\nContent-Type: application/vnd.docker.raw-stream\r\nConnection: Upgrade\r\nUpgrade: tcp\r\n\r\n") } else { @@ -92,22 +90,16 @@ func (s *Server) postContainerExecStart(version version.Version, w http.Response } if !execStartCheck.Tty { - errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr) - outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout) + stderr = stdcopy.NewStdWriter(outStream, stdcopy.Stderr) + stdout = stdcopy.NewStdWriter(outStream, stdcopy.Stdout) } - stdin = inStream - stdout = outStream - stderr = errStream } + // Now run the user process in container. - if err := s.daemon.ContainerExecStart(execName, stdin, stdout, stderr); err != nil { - logrus.Errorf("Error starting exec command in container %s: %s", execName, err) - return err + fmt.Fprintf(outStream, "Error running exec in container: %v\n", err) } - w.WriteHeader(http.StatusNoContent) - return nil } diff --git a/daemon/exec.go b/daemon/exec.go index 8b163aec49..73f0f5640f 100644 --- a/daemon/exec.go +++ b/daemon/exec.go @@ -175,7 +175,6 @@ func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, erro } func (d *Daemon) ContainerExecStart(execName string, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) error { - var ( cStdin io.ReadCloser cStdout, cStderr io.Writer @@ -246,12 +245,18 @@ func (d *Daemon) ContainerExecStart(execName string, stdin io.ReadCloser, stdout if err != nil { return fmt.Errorf("attach failed with error: %s", err) } - break + return nil case err := <-execErr: + if err == nil { + return nil + } + + // Maybe the container stopped while we were trying to exec + if !container.IsRunning() { + return fmt.Errorf("container stopped while running exec") + } return err } - - return nil } func (d *Daemon) Exec(c *Container, execConfig *execConfig, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {