diff options
-rw-r--r-- | cmd/podman/images/rm.go | 1 | ||||
-rw-r--r-- | docs/source/markdown/podman-rmi.1.md | 14 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/images.go | 3 | ||||
-rw-r--r-- | pkg/api/server/register_images.go | 4 | ||||
-rw-r--r-- | pkg/bindings/images/types.go | 2 | ||||
-rw-r--r-- | pkg/bindings/images/types_remove_options.go | 15 | ||||
-rw-r--r-- | pkg/domain/entities/images.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/abi/images.go | 1 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/images.go | 2 | ||||
-rw-r--r-- | test/system/010-images.bats | 9 |
10 files changed, 51 insertions, 2 deletions
diff --git a/cmd/podman/images/rm.go b/cmd/podman/images/rm.go index dd138d410..13dab62d4 100644 --- a/cmd/podman/images/rm.go +++ b/cmd/podman/images/rm.go @@ -56,6 +56,7 @@ func init() { func imageRemoveFlagSet(flags *pflag.FlagSet) { flags.BoolVarP(&imageOpts.All, "all", "a", false, "Remove all images") + flags.BoolVarP(&imageOpts.Ignore, "ignore", "i", false, "Ignore errors if a specified image does not exist") flags.BoolVarP(&imageOpts.Force, "force", "f", false, "Force Removal of the image") } diff --git a/docs/source/markdown/podman-rmi.1.md b/docs/source/markdown/podman-rmi.1.md index 5fe0efa18..8d0e5e500 100644 --- a/docs/source/markdown/podman-rmi.1.md +++ b/docs/source/markdown/podman-rmi.1.md @@ -24,6 +24,10 @@ Remove all images in the local storage. This option will cause podman to remove all containers that are using the image before removing the image from the system. +#### **--ignore**, **-i** + +If a specified image does not exist in the local storage, ignore it and do not throw an error. + Remove an image by its short ID ``` @@ -43,6 +47,16 @@ Remove all images and containers. ``` $ podman rmi -a -f ``` + +Remove an absent image with and without the `--ignore` flag. +``` +$ podman rmi --ignore nothing +$ podman rmi nothing +Error: nothing: image not known + +``` + + ## Exit Status **0** All specified images removed diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index eb9fb12a6..d59a83342 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -613,6 +613,7 @@ func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) { query := struct { All bool `schema:"all"` Force bool `schema:"force"` + Ignore bool `schema:"ignore"` Images []string `schema:"images"` }{} @@ -621,7 +622,7 @@ func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) { return } - opts := entities.ImageRemoveOptions{All: query.All, Force: query.Force} + opts := entities.ImageRemoveOptions{All: query.All, Force: query.Force, Ignore: query.Ignore} imageEngine := abi.ImageEngine{Libpod: runtime} rmReport, rmErrors := imageEngine.Remove(r.Context(), query.Images, opts) strErrs := errorhandling.ErrorsToStrings(rmErrors) diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 017310f12..89f808e7d 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -944,6 +944,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // name: force // description: Force image removal (including containers using the images). // type: boolean + // - in: query + // name: ignore + // description: Ignore if a specified image does not exist and do not throw an error. + // type: boolean // produces: // - application/json // responses: diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go index a44a3527f..163365924 100644 --- a/pkg/bindings/images/types.go +++ b/pkg/bindings/images/types.go @@ -11,6 +11,8 @@ type RemoveOptions struct { All *bool // Forces removes all containers based on the image Force *bool + // Ignore if a specified image does not exist and do not throw an error. + Ignore *bool } //go:generate go run ../generator/generator.go DiffOptions diff --git a/pkg/bindings/images/types_remove_options.go b/pkg/bindings/images/types_remove_options.go index 1fbe5f4ea..613a33183 100644 --- a/pkg/bindings/images/types_remove_options.go +++ b/pkg/bindings/images/types_remove_options.go @@ -46,3 +46,18 @@ func (o *RemoveOptions) GetForce() bool { } return *o.Force } + +// WithIgnore set field Ignore to given value +func (o *RemoveOptions) WithIgnore(value bool) *RemoveOptions { + o.Ignore = &value + return o +} + +// GetIgnore returns value of field Ignore +func (o *RemoveOptions) GetIgnore() bool { + if o.Ignore == nil { + var z bool + return z + } + return *o.Ignore +} diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index 2ac21cfeb..93334fc6a 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -90,6 +90,8 @@ type ImageRemoveOptions struct { All bool // Foce will force image removal including containers using the images. Force bool + // Ignore if a specified image does not exist and do not throw an error. + Ignore bool // Confirms if given name is a manifest list and removes it, otherwise returns error. LookupManifest bool } diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 0b1281aac..0b07901d4 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -578,6 +578,7 @@ func (ir *ImageEngine) Remove(ctx context.Context, images []string, opts entitie libimageOptions := &libimage.RemoveImagesOptions{} libimageOptions.Filters = []string{"readonly=false"} libimageOptions.Force = opts.Force + libimageOptions.Ignore = opts.Ignore libimageOptions.LookupManifest = opts.LookupManifest if !opts.All { libimageOptions.Filters = append(libimageOptions.Filters, "intermediate=false") diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index 3ee97d94c..62eacb19f 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -28,7 +28,7 @@ func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.Boo } func (ir *ImageEngine) Remove(ctx context.Context, imagesArg []string, opts entities.ImageRemoveOptions) (*entities.ImageRemoveReport, []error) { - options := new(images.RemoveOptions).WithForce(opts.Force).WithAll(opts.All) + options := new(images.RemoveOptions).WithForce(opts.Force).WithIgnore(opts.Ignore).WithAll(opts.All) return images.Remove(ir.ClientCtx, imagesArg, options) } diff --git a/test/system/010-images.bats b/test/system/010-images.bats index dbf4b2828..257508418 100644 --- a/test/system/010-images.bats +++ b/test/system/010-images.bats @@ -303,4 +303,13 @@ Deleted: $pauseID" run_podman image exists $IMAGE } +@test "podman rmi --ignore" { + random_image_name=$(random_string) + random_image_name=${random_image_name,,} # name must be lowercase + run_podman 1 rmi $random_image_name + is "$output" "Error: $random_image_name: image not known.*" + run_podman rmi --ignore $random_image_name + is "$output" "" +} + # vim: filetype=sh |