diff options
Diffstat (limited to 'libpod/container_exec.go')
-rw-r--r-- | libpod/container_exec.go | 79 |
1 files changed, 19 insertions, 60 deletions
diff --git a/libpod/container_exec.go b/libpod/container_exec.go index 7ed7a3343..5469462f8 100644 --- a/libpod/container_exec.go +++ b/libpod/container_exec.go @@ -94,67 +94,14 @@ func (e *ExecSession) ContainerID() string { return e.ContainerId } -// InspectExecSession contains information about a given exec session. -type InspectExecSession struct { - // CanRemove is legacy and used purely for compatibility reasons. - // Will always be set to true, unless the exec session is running. - CanRemove bool `json:"CanRemove"` - // ContainerID is the ID of the container this exec session is attached - // to. - ContainerID string `json:"ContainerID"` - // DetachKeys are the detach keys used by the exec session. - // If set to "" the default keys are being used. - // Will show "<none>" if no detach keys are set. - DetachKeys string `json:"DetachKeys"` - // ExitCode is the exit code of the exec session. Will be set to 0 if - // the exec session has not yet exited. - ExitCode int `json:"ExitCode"` - // ID is the ID of the exec session. - ID string `json:"ID"` - // OpenStderr is whether the container's STDERR stream will be attached. - // Always set to true if the exec session created a TTY. - OpenStderr bool `json:"OpenStderr"` - // OpenStdin is whether the container's STDIN stream will be attached - // to. - OpenStdin bool `json:"OpenStdin"` - // OpenStdout is whether the container's STDOUT stream will be attached. - // Always set to true if the exec session created a TTY. - OpenStdout bool `json:"OpenStdout"` - // Running is whether the exec session is running. - Running bool `json:"Running"` - // Pid is the PID of the exec session's process. - // Will be set to 0 if the exec session is not running. - Pid int `json:"Pid"` - // ProcessConfig contains information about the exec session's process. - ProcessConfig *InspectExecProcess `json:"ProcessConfig"` -} - -// InspectExecProcess contains information about the process in a given exec -// session. -type InspectExecProcess struct { - // Arguments are the arguments to the entrypoint command of the exec - // session. - Arguments []string `json:"arguments"` - // Entrypoint is the entrypoint for the exec session (the command that - // will be executed in the container). - Entrypoint string `json:"entrypoint"` - // Privileged is whether the exec session will be started with elevated - // privileges. - Privileged bool `json:"privileged"` - // Tty is whether the exec session created a terminal. - Tty bool `json:"tty"` - // User is the user the exec session was started as. - User string `json:"user"` -} - // Inspect inspects the given exec session and produces detailed output on its // configuration and current state. -func (e *ExecSession) Inspect() (*InspectExecSession, error) { +func (e *ExecSession) Inspect() (*define.InspectExecSession, error) { if e.Config == nil { return nil, errors.Wrapf(define.ErrInternal, "given exec session does not have a configuration block") } - output := new(InspectExecSession) + output := new(define.InspectExecSession) output.CanRemove = e.State != define.ExecStateRunning output.ContainerID = e.ContainerId if e.Config.DetachKeys != nil { @@ -167,7 +114,7 @@ func (e *ExecSession) Inspect() (*InspectExecSession, error) { output.OpenStdout = e.Config.AttachStdout output.Running = e.State == define.ExecStateRunning output.Pid = e.PID - output.ProcessConfig = new(InspectExecProcess) + output.ProcessConfig = new(define.InspectExecProcess) if len(e.Config.Command) > 0 { output.ProcessConfig.Entrypoint = e.Config.Command[0] if len(e.Config.Command) > 1 { @@ -213,6 +160,11 @@ func (c *Container) ExecCreate(config *ExecConfig) (string, error) { return "", errors.Wrapf(define.ErrInvalidArg, "cannot specify streams to attach to when exec session has a pseudoterminal") } + // Verify that we are in a good state to continue + if !c.ensureState(define.ContainerStateRunning) { + return "", errors.Wrapf(define.ErrCtrStateInvalid, "can only create exec sessions on running containers") + } + // Generate an ID for our new exec session sessionID := stringid.GenerateNonCryptoID() found := true @@ -279,6 +231,11 @@ func (c *Container) ExecStartAndAttach(sessionID string, streams *AttachStreams) } } + // Verify that we are in a good state to continue + if !c.ensureState(define.ContainerStateRunning) { + return errors.Wrapf(define.ErrCtrStateInvalid, "can only start exec sessions when their container is running") + } + session, ok := c.state.ExecSessions[sessionID] if !ok { return errors.Wrapf(define.ErrNoSuchExecSession, "container %s has no exec session with ID %s", c.ID(), sessionID) @@ -575,7 +532,7 @@ func (c *Container) ExecResize(sessionID string, newSize remotecommand.TerminalS return errors.Wrapf(define.ErrNoSuchExecSession, "container %s has no exec session with ID %s", c.ID(), sessionID) } - logrus.Infof("Removing container %s exec session %s", c.ID(), session.ID()) + logrus.Infof("Resizing container %s exec session %s to %+v", c.ID(), session.ID(), newSize) if session.State != define.ExecStateRunning { return errors.Wrapf(define.ErrExecSessionStateInvalid, "cannot resize container %s exec session %s as it is not running", c.ID(), session.ID()) @@ -592,9 +549,6 @@ func (c *Container) Exec(config *ExecConfig, streams *AttachStreams, resize <-ch if err != nil { return -1, err } - if err := c.ExecStartAndAttach(sessionID, streams); err != nil { - return -1, err - } // Start resizing if we have a resize channel. // This goroutine may likely leak, given that we cannot close it here. @@ -605,6 +559,7 @@ func (c *Container) Exec(config *ExecConfig, streams *AttachStreams, resize <-ch // session. if resize != nil { go func() { + logrus.Debugf("Sending resize events to exec session %s", sessionID) for resizeRequest := range resize { if err := c.ExecResize(sessionID, resizeRequest); err != nil { // Assume the exec session went down. @@ -615,6 +570,10 @@ func (c *Container) Exec(config *ExecConfig, streams *AttachStreams, resize <-ch }() } + if err := c.ExecStartAndAttach(sessionID, streams); err != nil { + return -1, err + } + session, err := c.ExecSession(sessionID) if err != nil { return -1, err |