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,
|
_execCommand,
|
||||||
_mountCommand,
|
_mountCommand,
|
||||||
_portCommand,
|
_portCommand,
|
||||||
_pruneContainersCommand,
|
|
||||||
_refreshCommand,
|
_refreshCommand,
|
||||||
_restoreCommand,
|
_restoreCommand,
|
||||||
_runlabelCommand,
|
_runlabelCommand,
|
||||||
|
@ -74,7 +73,6 @@ func getTrustSubCommands() []*cobra.Command {
|
||||||
// Commands that the local client implements
|
// Commands that the local client implements
|
||||||
func getSystemSubCommands() []*cobra.Command {
|
func getSystemSubCommands() []*cobra.Command {
|
||||||
return []*cobra.Command{
|
return []*cobra.Command{
|
||||||
_pruneSystemCommand,
|
|
||||||
_renumberCommand,
|
_renumberCommand,
|
||||||
_dfSystemCommand,
|
_dfSystemCommand,
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ var (
|
||||||
_logsCommand,
|
_logsCommand,
|
||||||
_pauseCommand,
|
_pauseCommand,
|
||||||
_restartCommand,
|
_restartCommand,
|
||||||
|
_pruneContainersCommand,
|
||||||
_runCommand,
|
_runCommand,
|
||||||
_rmCommand,
|
_rmCommand,
|
||||||
_startCommand,
|
_startCommand,
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||||
"github.com/containers/libpod/cmd/podman/shared"
|
"github.com/containers/libpod/cmd/podman/shared"
|
||||||
"github.com/containers/libpod/libpod"
|
"github.com/containers/libpod/libpod"
|
||||||
"github.com/containers/libpod/pkg/adapter"
|
"github.com/containers/libpod/pkg/adapter"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/spf13/cobra"
|
"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")
|
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 {
|
func pruneContainersCmd(c *cliconfig.PruneContainersValues) error {
|
||||||
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
|
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -81,11 +45,23 @@ func pruneContainersCmd(c *cliconfig.PruneContainersValues) error {
|
||||||
}
|
}
|
||||||
defer runtime.Shutdown(false)
|
defer runtime.Shutdown(false)
|
||||||
|
|
||||||
maxWorkers := shared.Parallelize("rm")
|
maxWorkers := shared.DefaultPoolSize("prune")
|
||||||
if c.GlobalIsSet("max-workers") {
|
if c.GlobalIsSet("max-workers") {
|
||||||
maxWorkers = c.GlobalFlags.MaxWorks
|
maxWorkers = c.GlobalFlags.MaxWorks
|
||||||
}
|
}
|
||||||
logrus.Debugf("Setting maximum workers to %d", maxWorkers)
|
ok, failures, err := runtime.Prune(getContext(), maxWorkers, c.Force)
|
||||||
|
if err != nil {
|
||||||
return pruneContainers(runtime, getContext(), maxWorkers, c.Bool("force"), c.Bool("volumes"))
|
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{
|
var systemCommands = []*cobra.Command{
|
||||||
_infoCommand,
|
_infoCommand,
|
||||||
|
_pruneSystemCommand,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -81,14 +81,15 @@ Are you sure you want to continue? [y/N] `, volumeString)
|
||||||
rmWorkers := shared.Parallelize("rm")
|
rmWorkers := shared.Parallelize("rm")
|
||||||
ctx := getContext()
|
ctx := getContext()
|
||||||
fmt.Println("Deleted Containers")
|
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")
|
fmt.Println("Deleted Pods")
|
||||||
pruneValues := cliconfig.PodPruneValues{
|
pruneValues := cliconfig.PodPruneValues{
|
||||||
PodmanCommand: c.PodmanCommand,
|
PodmanCommand: c.PodmanCommand,
|
||||||
Force: c.Force,
|
Force: c.Force,
|
||||||
}
|
}
|
||||||
ok, failures, err := runtime.PrunePods(ctx, &pruneValues)
|
ok, failures, err = runtime.PrunePods(ctx, &pruneValues)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if lasterr != nil {
|
if lasterr != nil {
|
||||||
logrus.Errorf("%q", lasterr)
|
logrus.Errorf("%q", lasterr)
|
||||||
|
|
|
@ -786,3 +786,51 @@ func (r *LocalRuntime) Top(cli *cliconfig.TopValues) ([]string, error) {
|
||||||
}
|
}
|
||||||
return container.Top(descriptors)
|
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)
|
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() {
|
func SkipIfRemote() {
|
||||||
ginkgo.Skip("This function is not enabled for remote podman")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SkipIfRootless() {
|
func SkipIfRootless() {
|
||||||
|
|
|
@ -39,7 +39,6 @@ var _ = Describe("Podman prune", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman container prune containers", func() {
|
It("podman container prune containers", func() {
|
||||||
SkipIfRemote()
|
|
||||||
top := podmanTest.RunTopContainer("")
|
top := podmanTest.RunTopContainer("")
|
||||||
top.WaitWithDefaultTimeout()
|
top.WaitWithDefaultTimeout()
|
||||||
Expect(top.ExitCode()).To(Equal(0))
|
Expect(top.ExitCode()).To(Equal(0))
|
||||||
|
@ -102,8 +101,6 @@ var _ = Describe("Podman prune", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman system prune pods", func() {
|
It("podman system prune pods", func() {
|
||||||
SkipIfRemote()
|
|
||||||
|
|
||||||
session := podmanTest.Podman([]string{"pod", "create"})
|
session := podmanTest.Podman([]string{"pod", "create"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session.ExitCode()).To(Equal(0))
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
|
Loading…
Reference in New Issue