diff options
author | Peter Hunt <pehunt@redhat.com> | 2019-03-15 17:41:03 -0400 |
---|---|---|
committer | Peter Hunt <pehunt@redhat.com> | 2019-04-16 11:23:18 -0400 |
commit | 0b34b4a59cf090a47a2a13cc4814954c497b3d49 (patch) | |
tree | 22e5185775ae83766d6911dd6b3d6b8376a976e1 /cmd/podman | |
parent | a2e9626d92dedb182a500c3a0f04dcc0499a6d54 (diff) | |
download | podman-0b34b4a59cf090a47a2a13cc4814954c497b3d49.tar.gz podman-0b34b4a59cf090a47a2a13cc4814954c497b3d49.tar.bz2 podman-0b34b4a59cf090a47a2a13cc4814954c497b3d49.zip |
Add podman pod prune
podman system prune would leave pods be, and not prune them if they were stopped.
Fix this by adding a `podman pod prune` command that prunes stopped pods similarly to containers.
Signed-off-by: Peter Hunt <pehunt@redhat.com>
Diffstat (limited to 'cmd/podman')
-rw-r--r-- | cmd/podman/cliconfig/config.go | 5 | ||||
-rw-r--r-- | cmd/podman/pod.go | 1 | ||||
-rw-r--r-- | cmd/podman/pods_prune.go | 91 | ||||
-rw-r--r-- | cmd/podman/shared/pod.go | 58 | ||||
-rw-r--r-- | cmd/podman/system_prune.go | 11 |
5 files changed, 136 insertions, 30 deletions
diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go index 982c77c17..16c98a13e 100644 --- a/cmd/podman/cliconfig/config.go +++ b/cmd/podman/cliconfig/config.go @@ -159,6 +159,11 @@ type PruneContainersValues struct { Force bool } +type PrunePodsValues struct { + PodmanCommand + Force bool +} + type ImportValues struct { PodmanCommand Change []string diff --git a/cmd/podman/pod.go b/cmd/podman/pod.go index 2d9bca21d..ed331965e 100644 --- a/cmd/podman/pod.go +++ b/cmd/podman/pod.go @@ -24,6 +24,7 @@ var podSubCommands = []*cobra.Command{ _podInspectCommand, _podKillCommand, _podPauseCommand, + _prunePodsCommand, _podPsCommand, _podRestartCommand, _podRmCommand, diff --git a/cmd/podman/pods_prune.go b/cmd/podman/pods_prune.go new file mode 100644 index 000000000..4ffe6fc27 --- /dev/null +++ b/cmd/podman/pods_prune.go @@ -0,0 +1,91 @@ +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" +) + +var ( + prunePodsCommand cliconfig.PrunePodsValues + prunePodsDescription = ` + podman pod prune + + Removes all exited pods +` + _prunePodsCommand = &cobra.Command{ + Use: "prune", + Args: noSubArgs, + Short: "Remove all stopped pods", + Long: prunePodsDescription, + RunE: func(cmd *cobra.Command, args []string) error { + prunePodsCommand.InputArgs = args + prunePodsCommand.GlobalFlags = MainGlobalOpts + return prunePodsCmd(&prunePodsCommand) + }, + } +) + +func init() { + prunePodsCommand.Command = _prunePodsCommand + prunePodsCommand.SetHelpTemplate(HelpTemplate()) + prunePodsCommand.SetUsageTemplate(UsageTemplate()) + flags := prunePodsCommand.Flags() + flags.BoolVarP(&prunePodsCommand.Force, "force", "f", false, "Force removal of a running pods. The default is false") +} + +func prunePods(runtime *adapter.LocalRuntime, ctx context.Context, maxWorkers int, force bool) error { + var deleteFuncs []shared.ParallelWorkerInput + + filter := func(p *libpod.Pod) bool { + state, err := shared.GetPodStatus(p) + // pod states should be the same + if state == shared.PodStateStopped || (state == shared.PodStateExited && err == nil) { + return true + } + return false + } + delPods, err := runtime.Pods(filter) + if err != nil { + return err + } + if len(delPods) < 1 { + return nil + } + for _, pod := range delPods { + p := pod + f := func() error { + return runtime.RemovePod(ctx, p, force, force) + } + + deleteFuncs = append(deleteFuncs, shared.ParallelWorkerInput{ + ContainerID: p.ID(), + ParallelFunc: f, + }) + } + // Run the parallel funcs + deleteErrors, errCount := shared.ParallelExecuteWorkerPool(maxWorkers, deleteFuncs) + return printParallelOutput(deleteErrors, errCount) +} + +func prunePodsCmd(c *cliconfig.PrunePodsValues) error { + runtime, err := adapter.GetRuntime(&c.PodmanCommand) + if err != nil { + return errors.Wrapf(err, "could not get runtime") + } + defer runtime.Shutdown(false) + + maxWorkers := shared.Parallelize("rm") + if c.GlobalIsSet("max-workers") { + maxWorkers = c.GlobalFlags.MaxWorks + } + logrus.Debugf("Setting maximum workers to %d", maxWorkers) + + return prunePods(runtime, getContext(), maxWorkers, c.Bool("force")) +} diff --git a/cmd/podman/shared/pod.go b/cmd/podman/shared/pod.go index 4d936d61c..3f4cb0312 100644 --- a/cmd/podman/shared/pod.go +++ b/cmd/podman/shared/pod.go @@ -10,12 +10,12 @@ import ( ) const ( - stopped = "Stopped" - running = "Running" - paused = "Paused" - exited = "Exited" - errored = "Error" - created = "Created" + PodStateStopped = "Stopped" + PodStateRunning = "Running" + PodStatePaused = "Paused" + PodStateExited = "Exited" + PodStateErrored = "Error" + PodStateCreated = "Created" ) // GetPodStatus determines the status of the pod based on the @@ -24,7 +24,7 @@ const ( func GetPodStatus(pod *libpod.Pod) (string, error) { ctrStatuses, err := pod.Status() if err != nil { - return errored, err + return PodStateErrored, err } return CreatePodStatusResults(ctrStatuses) } @@ -32,44 +32,44 @@ func GetPodStatus(pod *libpod.Pod) (string, error) { func CreatePodStatusResults(ctrStatuses map[string]libpod.ContainerStatus) (string, error) { ctrNum := len(ctrStatuses) if ctrNum == 0 { - return created, nil + return PodStateCreated, nil } statuses := map[string]int{ - stopped: 0, - running: 0, - paused: 0, - created: 0, - errored: 0, + PodStateStopped: 0, + PodStateRunning: 0, + PodStatePaused: 0, + PodStateCreated: 0, + PodStateErrored: 0, } for _, ctrStatus := range ctrStatuses { switch ctrStatus { case libpod.ContainerStateExited: fallthrough case libpod.ContainerStateStopped: - statuses[stopped]++ + statuses[PodStateStopped]++ case libpod.ContainerStateRunning: - statuses[running]++ + statuses[PodStateRunning]++ case libpod.ContainerStatePaused: - statuses[paused]++ + statuses[PodStatePaused]++ case libpod.ContainerStateCreated, libpod.ContainerStateConfigured: - statuses[created]++ + statuses[PodStateCreated]++ default: - statuses[errored]++ + statuses[PodStateErrored]++ } } - if statuses[running] > 0 { - return running, nil - } else if statuses[paused] == ctrNum { - return paused, nil - } else if statuses[stopped] == ctrNum { - return exited, nil - } else if statuses[stopped] > 0 { - return stopped, nil - } else if statuses[errored] > 0 { - return errored, nil + if statuses[PodStateRunning] > 0 { + return PodStateRunning, nil + } else if statuses[PodStatePaused] == ctrNum { + return PodStatePaused, nil + } else if statuses[PodStateStopped] == ctrNum { + return PodStateExited, nil + } else if statuses[PodStateStopped] > 0 { + return PodStateStopped, nil + } else if statuses[PodStateErrored] > 0 { + return PodStateErrored, nil } - return created, nil + return PodStateCreated, nil } // GetNamespaceOptions transforms a slice of kernel namespaces diff --git a/cmd/podman/system_prune.go b/cmd/podman/system_prune.go index 436d54823..14cb96941 100644 --- a/cmd/podman/system_prune.go +++ b/cmd/podman/system_prune.go @@ -59,6 +59,7 @@ func pruneSystemCmd(c *cliconfig.SystemPruneValues) error { fmt.Printf(` WARNING! This will remove: - all stopped containers%s + - all stopped pods - all dangling images - all build cache Are you sure you want to continue? [y/N] `, volumeString) @@ -77,9 +78,17 @@ Are you sure you want to continue? [y/N] `, volumeString) } defer runtime.Shutdown(false) + rmWorkers := shared.Parallelize("rm") ctx := getContext() fmt.Println("Deleted Containers") - lasterr := pruneContainers(runtime, ctx, shared.Parallelize("rm"), false, false) + lasterr := pruneContainers(runtime, ctx, rmWorkers, false, false) + fmt.Println("Deleted Pods") + if err := prunePods(runtime, ctx, rmWorkers, true); err != nil { + if lasterr != nil { + logrus.Errorf("%q", lasterr) + } + lasterr = err + } if c.Bool("volumes") { fmt.Println("Deleted Volumes") err := volumePrune(runtime, getContext()) |