summaryrefslogtreecommitdiff
path: root/libpod/container_exec.go
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@pm.me>2020-05-20 15:29:24 -0400
committerMatthew Heon <matthew.heon@pm.me>2020-05-20 16:11:05 -0400
commit6b9e9610d8ef380d32a682d058157db0f08dd873 (patch)
treeffd1f83437eb6d7e111c91b2036dfd34ff6c78d3 /libpod/container_exec.go
parent5ec56dc79093e52abd8e72913aa62932bf12ba6a (diff)
downloadpodman-6b9e9610d8ef380d32a682d058157db0f08dd873.tar.gz
podman-6b9e9610d8ef380d32a682d058157db0f08dd873.tar.bz2
podman-6b9e9610d8ef380d32a682d058157db0f08dd873.zip
Enable cleanup processes for detached exec
The cleanup command creation logic is made public as part of this and wired such that we can call it both within SpecGen (to make container exit commands) and from the ABI detached exec handler. Exit commands are presently only used for detached exec, but theoretically could be turned on for all exec sessions if we wanted (I'm declining to do this because of potential overhead). I also forgot to copy the exit command from the exec config into the ExecOptions struct used by the OCI runtime, so it was not being added. There are also two significant bugfixes for exec in here. One is for updating the status of running exec sessions - this was always failing as I had coded it to remove the exit file *before* reading it, instead of after (oops). The second was that removing a running exec session would always fail because I inverted the check to see if it was running. Signed-off-by: Matthew Heon <matthew.heon@pm.me>
Diffstat (limited to 'libpod/container_exec.go')
-rw-r--r--libpod/container_exec.go27
1 files changed, 18 insertions, 9 deletions
diff --git a/libpod/container_exec.go b/libpod/container_exec.go
index efbd49b15..f2943b73c 100644
--- a/libpod/container_exec.go
+++ b/libpod/container_exec.go
@@ -65,6 +65,9 @@ type ExecConfig struct {
// ExitCommand is the exec session's exit command.
// This command will be executed when the exec session exits.
// If unset, no command will be executed.
+ // Two arguments will be appended to the exit command by Libpod:
+ // The ID of the exec session, and the ID of the container the exec
+ // session is a part of (in that order).
ExitCommand []string `json:"exitCommand,omitempty"`
}
@@ -195,6 +198,10 @@ func (c *Container) ExecCreate(config *ExecConfig) (string, error) {
return "", errors.Wrapf(err, "error copying exec configuration into exec session")
}
+ if len(session.Config.ExitCommand) > 0 {
+ session.Config.ExitCommand = append(session.Config.ExitCommand, []string{session.ID(), c.ID()}...)
+ }
+
if c.state.ExecSessions == nil {
c.state.ExecSessions = make(map[string]*ExecSession)
}
@@ -606,11 +613,11 @@ func (c *Container) ExecRemove(sessionID string, force bool) error {
// Update status of exec session if running, so we cna check if it
// stopped in the meantime.
if session.State == define.ExecStateRunning {
- stopped, err := c.ociRuntime.ExecUpdateStatus(c, session.ID())
+ running, err := c.ociRuntime.ExecUpdateStatus(c, session.ID())
if err != nil {
return err
}
- if stopped {
+ if !running {
session.State = define.ExecStateStopped
// TODO: should we retrieve exit code here?
// TODO: Might be worth saving state here.
@@ -865,13 +872,6 @@ func (c *Container) getActiveExecSessions() ([]string, error) {
continue
}
if !alive {
- if err := c.cleanupExecBundle(id); err != nil {
- if lastErr != nil {
- logrus.Errorf("Error checking container %s exec sessions: %v", c.ID(), lastErr)
- }
- lastErr = err
- }
-
_, isLegacy := c.state.LegacyExecSessions[id]
if isLegacy {
delete(c.state.LegacyExecSessions, id)
@@ -891,6 +891,12 @@ func (c *Container) getActiveExecSessions() ([]string, error) {
needSave = true
}
+ if err := c.cleanupExecBundle(id); err != nil {
+ if lastErr != nil {
+ logrus.Errorf("Error checking container %s exec sessions: %v", c.ID(), lastErr)
+ }
+ lastErr = err
+ }
} else {
activeSessions = append(activeSessions, id)
}
@@ -911,6 +917,8 @@ func (c *Container) getActiveExecSessions() ([]string, error) {
func (c *Container) removeAllExecSessions() error {
knownSessions := c.getKnownExecSessions()
+ logrus.Debugf("Removing all exec sessions for container %s", c.ID())
+
var lastErr error
for _, id := range knownSessions {
if err := c.ociRuntime.ExecStopContainer(c, id, c.StopTimeout()); err != nil {
@@ -975,6 +983,7 @@ func prepareForExec(c *Container, session *ExecSession) (*ExecOptions, error) {
opts.User = user
opts.PreserveFDs = session.Config.PreserveFDs
opts.DetachKeys = session.Config.DetachKeys
+ opts.ExitCommand = session.Config.ExitCommand
return opts, nil
}