From 0c40b62c77d8f7dba8e73ac3ced0de536ec220d5 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Fri, 20 Mar 2020 15:23:35 -0400 Subject: Implement APIv2 Exec Create and Inspect Endpoints Start and Resize require further implementation work. Signed-off-by: Matthew Heon --- libpod/container_exec.go | 64 ++++++------------------------------------------ libpod/define/inspect.go | 54 ++++++++++++++++++++++++++++++++++++++++ libpod/runtime_ctr.go | 18 ++++++++++++++ 3 files changed, 80 insertions(+), 56 deletions(-) create mode 100644 libpod/define/inspect.go (limited to 'libpod') diff --git a/libpod/container_exec.go b/libpod/container_exec.go index 7ed7a3343..795eb7453 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 "" 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 diff --git a/libpod/define/inspect.go b/libpod/define/inspect.go new file mode 100644 index 000000000..b7cd13f82 --- /dev/null +++ b/libpod/define/inspect.go @@ -0,0 +1,54 @@ +package define + +// 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 "" 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"` +} diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 0b18436ca..b99e6df84 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -830,6 +830,24 @@ func (r *Runtime) GetLatestContainer() (*Container, error) { return ctrs[lastCreatedIndex], nil } +// GetExecSessionContainer gets the container that a given exec session ID is +// attached to. +func (r *Runtime) GetExecSessionContainer(id string) (*Container, error) { + r.lock.RLock() + defer r.lock.RUnlock() + + if !r.valid { + return nil, define.ErrRuntimeStopped + } + + ctrID, err := r.state.GetExecSession(id) + if err != nil { + return nil, err + } + + return r.state.Container(ctrID) +} + // PruneContainers removes stopped and exited containers from localstorage. A set of optional filters // can be provided to be more granular. func (r *Runtime) PruneContainers(filterFuncs []ContainerFilter) (map[string]int64, map[string]error, error) { -- cgit v1.2.3-54-g00ecf