diff --git a/ctrd/container.go b/ctrd/container.go index 7d54fa7e4c..fd5ac4347a 100644 --- a/ctrd/container.go +++ b/ctrd/container.go @@ -122,13 +122,18 @@ func (c *Client) execContainer(ctx context.Context, process *Process) error { exitTime: status.ExitTime(), } - // run hook if not got fail here - if err := <-fail; err == nil { - for _, hook := range c.hooks { - if err := hook(process.ExecID, msg); err != nil { - logrus.Errorf("failed to execute the exec exit hooks: %v", err) - break - } + if err := <-fail; err != nil { + msg.err = err + // exit code should not be zero when exec get failed. + if msg.exitCode == 0 { + msg.exitCode = 126 + } + } + // XXX: if exec process get run, io should be closed in this function, + for _, hook := range c.hooks { + if err := hook(process.ExecID, msg); err != nil { + logrus.Errorf("failed to execute the exec exit hooks: %v", err) + break } } @@ -141,7 +146,6 @@ func (c *Client) execContainer(ctx context.Context, process *Process) error { // start the exec process if err := execProcess.Start(ctx); err != nil { fail <- err - return errors.Wrap(err, "failed to exec process") } return nil diff --git a/daemon/mgr/container.go b/daemon/mgr/container.go index 53a0c526d6..5767d32f30 100644 --- a/daemon/mgr/container.go +++ b/daemon/mgr/container.go @@ -3,6 +3,7 @@ package mgr import ( "context" "fmt" + "io" "io/ioutil" "os" "os/exec" @@ -34,6 +35,7 @@ import ( containerdtypes "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/mount" + "github.com/docker/docker/pkg/stdcopy" "github.com/docker/libnetwork" "github.com/go-openapi/strfmt" "github.com/imdario/mergo" @@ -1855,17 +1857,21 @@ func (mgr *ContainerManager) execExitedAndRelease(id string, m *ctrd.Message) er execConfig.Running = false execConfig.Error = m.RawError() - io := mgr.IOs.Get(id) - if io == nil { + eio := mgr.IOs.Get(id) + if eio == nil { return nil } if err := m.RawError(); err != nil { - fmt.Fprintf(io.Stdout, "%v\n", err) + var stdout io.Writer = eio.Stdout + if !execConfig.Tty && !eio.MuxDisabled { + stdout = stdcopy.NewStdWriter(stdout, stdcopy.Stdout) + } + stdout.Write([]byte(err.Error() + "\r\n")) } // close io - io.Close() + eio.Close() mgr.IOs.Remove(id) return nil