diff options
author | Matthew Heon <matthew.heon@pm.me> | 2020-05-19 15:54:53 -0400 |
---|---|---|
committer | Matthew Heon <matthew.heon@pm.me> | 2020-05-20 16:11:05 -0400 |
commit | 5ec56dc79093e52abd8e72913aa62932bf12ba6a (patch) | |
tree | 2552e0b79d6b48bc5b8cbfb948ccb2afde576be1 | |
parent | 05a034118fcb5057593cb1492f1c9be59f7a88d8 (diff) | |
download | podman-5ec56dc79093e52abd8e72913aa62932bf12ba6a.tar.gz podman-5ec56dc79093e52abd8e72913aa62932bf12ba6a.tar.bz2 podman-5ec56dc79093e52abd8e72913aa62932bf12ba6a.zip |
Add ability to clean up exec sessions with cleanup
We need to be able to use cleanup processes to remove exec
sessions as part of detached exec. This PR adds that ability. A
new flag is added to `podman container cleanup`, `--exec`, to
specify an exec session to be cleaned up.
As part of this, ensure that `ExecCleanup` can clean up exec
sessions that were running, but have since exited. This ensures
that we can come back to an exec session that was running but has
since stopped, and clean it up.
Signed-off-by: Matthew Heon <matthew.heon@pm.me>
-rw-r--r-- | cmd/podman/containers/cleanup.go | 14 | ||||
-rw-r--r-- | docs/source/markdown/podman-container-cleanup.1.md | 7 | ||||
-rw-r--r-- | libpod/container_exec.go | 22 | ||||
-rw-r--r-- | pkg/domain/entities/containers.go | 1 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 14 |
5 files changed, 57 insertions, 1 deletions
diff --git a/cmd/podman/containers/cleanup.go b/cmd/podman/containers/cleanup.go index 2bcd1c1e9..257efb971 100644 --- a/cmd/podman/containers/cleanup.go +++ b/cmd/podman/containers/cleanup.go @@ -7,6 +7,7 @@ import ( "github.com/containers/libpod/cmd/podman/registry" "github.com/containers/libpod/cmd/podman/utils" "github.com/containers/libpod/pkg/domain/entities" + "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -43,6 +44,7 @@ func init() { flags := cleanupCommand.Flags() flags.BoolVarP(&cleanupOptions.All, "all", "a", false, "Cleans up all containers") flags.BoolVarP(&cleanupOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + flags.StringVar(&cleanupOptions.Exec, "exec", "", "Clean up the given exec session instead of the container") flags.BoolVar(&cleanupOptions.Remove, "rm", false, "After cleanup, remove the container entirely") flags.BoolVar(&cleanupOptions.RemoveImage, "rmi", false, "After cleanup, remove the image entirely") @@ -52,6 +54,18 @@ func cleanup(cmd *cobra.Command, args []string) error { var ( errs utils.OutputErrors ) + + if cleanupOptions.Exec != "" { + switch { + case cleanupOptions.All: + return errors.Errorf("exec and all options conflict") + case len(args) > 1: + return errors.Errorf("cannot use exec option when more than one container is given") + case cleanupOptions.RemoveImage: + return errors.Errorf("exec and rmi options conflict") + } + } + responses, err := registry.ContainerEngine().ContainerCleanup(registry.GetContext(), args, cleanupOptions) if err != nil { return err diff --git a/docs/source/markdown/podman-container-cleanup.1.md b/docs/source/markdown/podman-container-cleanup.1.md index 66a6cff62..a200c2c36 100644 --- a/docs/source/markdown/podman-container-cleanup.1.md +++ b/docs/source/markdown/podman-container-cleanup.1.md @@ -16,6 +16,13 @@ Sometimes container's mount points and network stacks can remain if the podman c Cleanup all containers. +**--exec**=_session_ + +Clean up an exec session for a single container. +Can only be specified if a single container is being cleaned up (conflicts with **--all** as such). +If **--rm** is not specified, temporary files for the exec session will be cleaned up; if it is, the exec session will be removed from the container. +Conflicts with **--rmi** as the container is not being cleaned up so the image cannot be removed. + **--latest**, **-l** Instead of providing the container name or ID, use the last created container. If you use methods other than Podman to run containers such as CRI-O, the last started container could be from either of those methods. diff --git a/libpod/container_exec.go b/libpod/container_exec.go index a38f22488..efbd49b15 100644 --- a/libpod/container_exec.go +++ b/libpod/container_exec.go @@ -556,7 +556,27 @@ func (c *Container) ExecCleanup(sessionID string) error { } if session.State == define.ExecStateRunning { - return errors.Wrapf(define.ErrExecSessionStateInvalid, "cannot clean up container %s exec session %s as it is running", c.ID(), session.ID()) + // Check if the exec session is still running. + alive, err := c.ociRuntime.ExecUpdateStatus(c, session.ID()) + if err != nil { + return err + } + + if alive { + return errors.Wrapf(define.ErrExecSessionStateInvalid, "cannot clean up container %s exec session %s as it is running", c.ID(), session.ID()) + } + + exitCode, err := c.readExecExitCode(session.ID()) + if err != nil { + return err + } + session.ExitCode = exitCode + session.PID = 0 + session.State = define.ExecStateStopped + + if err := c.save(); err != nil { + return err + } } logrus.Infof("Cleaning up container %s exec session %s", c.ID(), session.ID()) diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index f362f88a6..8d85a9b23 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -310,6 +310,7 @@ type ContainerRunReport struct { // cleanup command type ContainerCleanupOptions struct { All bool + Exec string Latest bool Remove bool RemoveImage bool diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 18282bb79..e8eb91644 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -888,6 +888,20 @@ func (ic *ContainerEngine) ContainerCleanup(ctx context.Context, namesOrIds []st for _, ctr := range ctrs { var err error report := entities.ContainerCleanupReport{Id: ctr.ID()} + + if options.Exec != "" { + if options.Remove { + if err := ctr.ExecRemove(options.Exec, false); err != nil { + return nil, err + } + } else { + if err := ctr.ExecCleanup(options.Exec); err != nil { + return nil, err + } + } + return []*entities.ContainerCleanupReport{}, nil + } + if options.Remove { err = ic.Libpod.RemoveContainer(ctx, ctr, false, true) if err != nil { |