mirror of https://github.com/containers/podman.git
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 <bbaude@redhat.com>
This commit is contained in:
parent
135c8bef22
commit
2e800d63aa
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ var (
|
|||
_logsCommand,
|
||||
_pauseCommand,
|
||||
_restartCommand,
|
||||
_pruneContainersCommand,
|
||||
_runCommand,
|
||||
_rmCommand,
|
||||
_startCommand,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ var (
|
|||
|
||||
var systemCommands = []*cobra.Command{
|
||||
_infoCommand,
|
||||
_pruneSystemCommand,
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
)
|
||||
|
||||
func SkipIfRemote() {
|
||||
ginkgo.Skip("This function is not enabled for remote podman")
|
||||
}
|
||||
|
||||
func SkipIfRootless() {
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue