Add the rmi flag to podman-run to delete container image

The --rmi flag will delete the container image after its execution
unless that image is already been used by another container(s).

This is useful when one wants to execute a container once and remove
any resources attached to it.

Signed-off-by: Boaz Shuster <boaz.shuster.github@gmail.com>
This commit is contained in:
Boaz Shuster
2020-01-01 09:53:25 +02:00
parent 1641ee6180
commit 11e5c53d11
9 changed files with 70 additions and 3 deletions

View File

@ -44,6 +44,7 @@ func init() {
flags.BoolVarP(&cleanupCommand.All, "all", "a", false, "Cleans up all containers")
flags.BoolVarP(&cleanupCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.BoolVar(&cleanupCommand.Remove, "rm", false, "After cleanup, remove the container entirely")
flags.BoolVar(&cleanupCommand.RemoveImage, "rmi", false, "After cleanup, remove the image entirely")
markFlagHiddenForRemoteClient("latest", flags)
}

View File

@ -658,9 +658,10 @@ type VolumeRmValues struct {
type CleanupValues struct {
PodmanCommand
All bool
Latest bool
Remove bool
All bool
Latest bool
Remove bool
RemoveImage bool
}
type SystemPruneValues struct {

View File

@ -7,6 +7,7 @@ import (
"github.com/containers/libpod/pkg/adapter"
"github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@ -38,6 +39,7 @@ func init() {
flags.SetInterspersed(false)
flags.SetNormalizeFunc(aliasFlags)
flags.Bool("sig-proxy", true, "Proxy received signals to the process")
flags.Bool("rmi", false, "Remove container image unless used by other containers")
flags.AddFlagSet(getNetFlags())
getCreateFlags(&runCommand.PodmanCommand)
markFlagHiddenForRemoteClient("authfile", flags)
@ -64,5 +66,13 @@ func runCmd(c *cliconfig.RunValues) error {
defer runtime.DeferredShutdown(false)
exitCode, err = runtime.Run(getContext(), c, exitCode)
if c.Bool("rmi") {
imageName := c.InputArgs[0]
if newImage, newImageErr := runtime.NewImageFromLocal(imageName); newImageErr != nil {
logrus.Errorf("%s", errors.Wrapf(newImageErr, "failed creating image object"))
} else if _, errImage := runtime.RemoveImage(getContext(), newImage, false); errImage != nil {
logrus.Errorf("%s", errors.Wrapf(errImage, "failed removing image"))
}
}
return err
}

View File

@ -1967,6 +1967,7 @@ _podman_container_run() {
boolean_options="$boolean_options
--detach -d
--rm
--rmi
--sig-proxy=false
"
__podman_complete_detach_keys && return

View File

@ -22,6 +22,14 @@ to run containers such as CRI-O, the last started container could be from either
The latest option is not supported on the remote client.
**--rm**
After cleanup, remove the container entirely.
**--rmi**
After cleanup, remove the image entirely.
## EXAMPLE
`podman container cleanup mywebserver`

View File

@ -689,6 +689,11 @@ Note that the container will not be removed when it could not be created or
started successfully. This allows the user to inspect the container after
failure.
**--rmi**=*true|false*
After exit of the container, remove the image unless another
container is using it. The default is *false*.
**--rootfs**
If specified, the first argument refers to an exploded container on the file system.

View File

@ -1101,6 +1101,15 @@ func (r *LocalRuntime) CleanupContainers(ctx context.Context, cli *cliconfig.Cle
} else {
failures[ctr.ID()] = err
}
if cli.RemoveImage {
_, imageName := ctr.Image()
if err := removeContainerImage(ctx, ctr, r); err != nil {
failures[imageName] = err
} else {
ok = append(ok, imageName)
}
}
}
return ok, failures, nil
}
@ -1120,6 +1129,16 @@ func cleanupContainer(ctx context.Context, ctr *libpod.Container, runtime *Local
return nil
}
func removeContainerImage(ctx context.Context, ctr *libpod.Container, runtime *LocalRuntime) error {
_, imageName := ctr.Image()
ctrImage, err := runtime.NewImageFromLocal(imageName)
if err != nil {
return err
}
_, err = runtime.RemoveImage(ctx, ctrImage, false)
return err
}
// Port displays port information about existing containers
func (r *LocalRuntime) Port(c *cliconfig.PortValues) ([]*Container, error) {
var (

View File

@ -156,6 +156,7 @@ type CreateConfig struct {
Resources CreateResourceConfig
RestartPolicy string
Rm bool //rm
Rmi bool //rmi
StopSignal syscall.Signal // stop-signal
StopTimeout uint // stop-timeout
Systemd bool
@ -233,6 +234,10 @@ func (c *CreateConfig) createExitCommand(runtime *libpod.Runtime) ([]string, err
command = append(command, "--rm")
}
if c.Rmi {
command = append(command, "--rmi")
}
return command, nil
}

View File

@ -136,4 +136,21 @@ echo $rand | 0 | $rand
run_podman rmi busybox
}
# 'run --rmi' deletes the image in the end unless it's used by another container.
@test "podman run --rmi - remove image" {
skip_if_remote "podman-remote does not emit 'Trying to pull' msgs"
run_podman 0 run --rmi --rm redis /bin/true
run_podman 1 image exists redis
}
@test "podman run --rmi - not remove image" {
skip_if_remote "podman-remote does not emit 'Trying to pull' msgs"
run_podman run redis /bin/true
run_podman images | grep redis
run_podman run --rmi --rm redis /bin/true
run_podman images | grep redis
run_podman 0 rm -a
}
# vim: filetype=sh