From 2e800d63aa388bb248c97ea24fae2f7190fe3cce Mon Sep 17 00:00:00 2001 From: baude Date: Sat, 20 Apr 2019 12:58:59 -0500 Subject: podman-remote prune containers enable the ability to prune containers from the remote-command. this also includes the system prune command. Signed-off-by: baude --- cmd/podman/commands.go | 2 -- cmd/podman/container.go | 1 + cmd/podman/containers_prune.go | 56 ++++++++++++---------------------------- cmd/podman/system.go | 1 + cmd/podman/system_prune.go | 5 ++-- pkg/adapter/containers.go | 48 ++++++++++++++++++++++++++++++++++ pkg/adapter/containers_remote.go | 28 ++++++++++++++++++++ test/e2e/libpod_suite_test.go | 1 - test/e2e/prune_test.go | 3 --- 9 files changed, 97 insertions(+), 48 deletions(-) diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go index c43ecec5c..ef8debe42 100644 --- a/cmd/podman/commands.go +++ b/cmd/podman/commands.go @@ -46,7 +46,6 @@ func getContainerSubCommands() []*cobra.Command { _execCommand, _mountCommand, _portCommand, - _pruneContainersCommand, _refreshCommand, _restoreCommand, _runlabelCommand, @@ -74,7 +73,6 @@ func getTrustSubCommands() []*cobra.Command { // Commands that the local client implements func getSystemSubCommands() []*cobra.Command { return []*cobra.Command{ - _pruneSystemCommand, _renumberCommand, _dfSystemCommand, } diff --git a/cmd/podman/container.go b/cmd/podman/container.go index 52152d50e..9cd8229f9 100644 --- a/cmd/podman/container.go +++ b/cmd/podman/container.go @@ -61,6 +61,7 @@ var ( _logsCommand, _pauseCommand, _restartCommand, + _pruneContainersCommand, _runCommand, _rmCommand, _startCommand, diff --git a/cmd/podman/containers_prune.go b/cmd/podman/containers_prune.go index abc56cee1..340c47e8d 100644 --- a/cmd/podman/containers_prune.go +++ b/cmd/podman/containers_prune.go @@ -1,14 +1,11 @@ package main import ( - "context" - "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/adapter" "github.com/pkg/errors" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -41,39 +38,6 @@ func init() { flags.BoolVarP(&pruneContainersCommand.Force, "force", "f", false, "Force removal of a running container. The default is false") } -func pruneContainers(runtime *adapter.LocalRuntime, ctx context.Context, maxWorkers int, force, volumes bool) error { - var deleteFuncs []shared.ParallelWorkerInput - - filter := func(c *libpod.Container) bool { - state, err := c.State() - if state == libpod.ContainerStateStopped || (state == libpod.ContainerStateExited && err == nil && c.PodID() == "") { - return true - } - return false - } - delContainers, err := runtime.GetContainers(filter) - if err != nil { - return err - } - if len(delContainers) < 1 { - return nil - } - for _, container := range delContainers { - con := container - f := func() error { - return runtime.RemoveContainer(ctx, con, force, volumes) - } - - deleteFuncs = append(deleteFuncs, shared.ParallelWorkerInput{ - ContainerID: con.ID(), - ParallelFunc: f, - }) - } - // Run the parallel funcs - deleteErrors, errCount := shared.ParallelExecuteWorkerPool(maxWorkers, deleteFuncs) - return printParallelOutput(deleteErrors, errCount) -} - func pruneContainersCmd(c *cliconfig.PruneContainersValues) error { runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { @@ -81,11 +45,23 @@ func pruneContainersCmd(c *cliconfig.PruneContainersValues) error { } defer runtime.Shutdown(false) - maxWorkers := shared.Parallelize("rm") + maxWorkers := shared.DefaultPoolSize("prune") if c.GlobalIsSet("max-workers") { maxWorkers = c.GlobalFlags.MaxWorks } - logrus.Debugf("Setting maximum workers to %d", maxWorkers) - - return pruneContainers(runtime, getContext(), maxWorkers, c.Bool("force"), c.Bool("volumes")) + ok, failures, err := runtime.Prune(getContext(), maxWorkers, c.Force) + if err != nil { + if errors.Cause(err) == libpod.ErrNoSuchCtr { + if len(c.InputArgs) > 1 { + exitCode = 125 + } else { + exitCode = 1 + } + } + return err + } + if len(failures) > 0 { + exitCode = 125 + } + return printCmdResults(ok, failures) } diff --git a/cmd/podman/system.go b/cmd/podman/system.go index 528a594de..80080bf44 100644 --- a/cmd/podman/system.go +++ b/cmd/podman/system.go @@ -20,6 +20,7 @@ var ( var systemCommands = []*cobra.Command{ _infoCommand, + _pruneSystemCommand, } func init() { diff --git a/cmd/podman/system_prune.go b/cmd/podman/system_prune.go index 2c1c5607a..37b6ef95f 100644 --- a/cmd/podman/system_prune.go +++ b/cmd/podman/system_prune.go @@ -81,14 +81,15 @@ Are you sure you want to continue? [y/N] `, volumeString) rmWorkers := shared.Parallelize("rm") ctx := getContext() fmt.Println("Deleted Containers") - lasterr := pruneContainers(runtime, ctx, rmWorkers, false, false) + ok, failures, lasterr := runtime.Prune(ctx, rmWorkers, false) + printCmdResults(ok, failures) fmt.Println("Deleted Pods") pruneValues := cliconfig.PodPruneValues{ PodmanCommand: c.PodmanCommand, Force: c.Force, } - ok, failures, err := runtime.PrunePods(ctx, &pruneValues) + ok, failures, err = runtime.PrunePods(ctx, &pruneValues) if err != nil { if lasterr != nil { logrus.Errorf("%q", lasterr) diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index 9f5fc7e65..fb85e54ba 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -786,3 +786,51 @@ func (r *LocalRuntime) Top(cli *cliconfig.TopValues) ([]string, error) { } return container.Top(descriptors) } + +// Prune removes stopped containers +func (r *LocalRuntime) Prune(ctx context.Context, maxWorkers int, force bool) ([]string, map[string]error, error) { + var ( + ok = []string{} + failures = map[string]error{} + err error + ) + + logrus.Debugf("Setting maximum rm workers to %d", maxWorkers) + + filter := func(c *libpod.Container) bool { + state, err := c.State() + if err != nil { + logrus.Error(err) + return false + } + if c.PodID() != "" { + return false + } + if state == libpod.ContainerStateStopped || state == libpod.ContainerStateExited { + return true + } + return false + } + delContainers, err := r.Runtime.GetContainers(filter) + if err != nil { + return ok, failures, err + } + if len(delContainers) < 1 { + return ok, failures, err + } + pool := shared.NewPool("prune", maxWorkers, len(delContainers)) + for _, c := range delContainers { + ctr := c + pool.Add(shared.Job{ + ID: ctr.ID(), + Fn: func() error { + err := r.Runtime.RemoveContainer(ctx, ctr, force, false) + if err != nil { + logrus.Debugf("Failed to prune container %s: %s", ctr.ID(), err.Error()) + } + return err + }, + }) + } + return pool.Run() +} diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go index ef6d0efe1..93875dd8a 100644 --- a/pkg/adapter/containers_remote.go +++ b/pkg/adapter/containers_remote.go @@ -852,3 +852,31 @@ func (r *LocalRuntime) Top(cli *cliconfig.TopValues) ([]string, error) { } return iopodman.Top().Call(r.Conn, ctr.ID(), descriptors) } + +// Prune removes stopped containers +func (r *LocalRuntime) Prune(ctx context.Context, maxWorkers int, force bool) ([]string, map[string]error, error) { + + var ( + ok = []string{} + failures = map[string]error{} + ctrs []*Container + err error + ) + logrus.Debugf("Setting maximum rm workers to %d", maxWorkers) + + filters := []string{libpod.ContainerStateExited.String()} + ctrs, err = r.LookupContainersWithStatus(filters) + if err != nil { + return ok, failures, err + } + for _, c := range ctrs { + c := c + _, err := iopodman.RemoveContainer().Call(r.Conn, c.ID(), false, false) + if err != nil { + failures[c.ID()] = err + } else { + ok = append(ok, c.ID()) + } + } + return ok, failures, nil +} diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go index 867844c32..10ca9ac47 100644 --- a/test/e2e/libpod_suite_test.go +++ b/test/e2e/libpod_suite_test.go @@ -13,7 +13,6 @@ import ( ) func SkipIfRemote() { - ginkgo.Skip("This function is not enabled for remote podman") } func SkipIfRootless() { diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go index 544d54b50..377c9f5e1 100644 --- a/test/e2e/prune_test.go +++ b/test/e2e/prune_test.go @@ -39,7 +39,6 @@ var _ = Describe("Podman prune", func() { }) It("podman container prune containers", func() { - SkipIfRemote() top := podmanTest.RunTopContainer("") top.WaitWithDefaultTimeout() Expect(top.ExitCode()).To(Equal(0)) @@ -102,8 +101,6 @@ var _ = Describe("Podman prune", func() { }) It("podman system prune pods", func() { - SkipIfRemote() - session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) -- cgit v1.2.3-54-g00ecf