mirror of https://github.com/containers/podman.git
podman rmi --ignore
Add an `--ignore` flag to `podman image rm` to instruct ignoring image if a specified image does not exist and to not throw an error. Other commands (e.g., `podman container rm`) already support this flag. Such an `--ignore` flag can come in handy in clean-up scripcts such as the teardown phases in the Podman tests. Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
This commit is contained in:
parent
c2eae35c60
commit
95dad4d8a4
|
@ -56,6 +56,7 @@ func init() {
|
||||||
|
|
||||||
func imageRemoveFlagSet(flags *pflag.FlagSet) {
|
func imageRemoveFlagSet(flags *pflag.FlagSet) {
|
||||||
flags.BoolVarP(&imageOpts.All, "all", "a", false, "Remove all images")
|
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")
|
flags.BoolVarP(&imageOpts.Force, "force", "f", false, "Force Removal of the image")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
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
|
Remove an image by its short ID
|
||||||
```
|
```
|
||||||
|
@ -43,6 +47,16 @@ Remove all images and containers.
|
||||||
```
|
```
|
||||||
$ podman rmi -a -f
|
$ 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
|
## Exit Status
|
||||||
**0** All specified images removed
|
**0** All specified images removed
|
||||||
|
|
||||||
|
|
|
@ -613,6 +613,7 @@ func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) {
|
||||||
query := struct {
|
query := struct {
|
||||||
All bool `schema:"all"`
|
All bool `schema:"all"`
|
||||||
Force bool `schema:"force"`
|
Force bool `schema:"force"`
|
||||||
|
Ignore bool `schema:"ignore"`
|
||||||
Images []string `schema:"images"`
|
Images []string `schema:"images"`
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
|
@ -621,7 +622,7 @@ func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
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}
|
imageEngine := abi.ImageEngine{Libpod: runtime}
|
||||||
rmReport, rmErrors := imageEngine.Remove(r.Context(), query.Images, opts)
|
rmReport, rmErrors := imageEngine.Remove(r.Context(), query.Images, opts)
|
||||||
strErrs := errorhandling.ErrorsToStrings(rmErrors)
|
strErrs := errorhandling.ErrorsToStrings(rmErrors)
|
||||||
|
|
|
@ -944,6 +944,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
||||||
// name: force
|
// name: force
|
||||||
// description: Force image removal (including containers using the images).
|
// description: Force image removal (including containers using the images).
|
||||||
// type: boolean
|
// type: boolean
|
||||||
|
// - in: query
|
||||||
|
// name: ignore
|
||||||
|
// description: Ignore if a specified image does not exist and do not throw an error.
|
||||||
|
// type: boolean
|
||||||
// produces:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
// responses:
|
// responses:
|
||||||
|
|
|
@ -11,6 +11,8 @@ type RemoveOptions struct {
|
||||||
All *bool
|
All *bool
|
||||||
// Forces removes all containers based on the image
|
// Forces removes all containers based on the image
|
||||||
Force *bool
|
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
|
//go:generate go run ../generator/generator.go DiffOptions
|
||||||
|
|
|
@ -46,3 +46,18 @@ func (o *RemoveOptions) GetForce() bool {
|
||||||
}
|
}
|
||||||
return *o.Force
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -90,6 +90,8 @@ type ImageRemoveOptions struct {
|
||||||
All bool
|
All bool
|
||||||
// Foce will force image removal including containers using the images.
|
// Foce will force image removal including containers using the images.
|
||||||
Force bool
|
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.
|
// Confirms if given name is a manifest list and removes it, otherwise returns error.
|
||||||
LookupManifest bool
|
LookupManifest bool
|
||||||
}
|
}
|
||||||
|
|
|
@ -578,6 +578,7 @@ func (ir *ImageEngine) Remove(ctx context.Context, images []string, opts entitie
|
||||||
libimageOptions := &libimage.RemoveImagesOptions{}
|
libimageOptions := &libimage.RemoveImagesOptions{}
|
||||||
libimageOptions.Filters = []string{"readonly=false"}
|
libimageOptions.Filters = []string{"readonly=false"}
|
||||||
libimageOptions.Force = opts.Force
|
libimageOptions.Force = opts.Force
|
||||||
|
libimageOptions.Ignore = opts.Ignore
|
||||||
libimageOptions.LookupManifest = opts.LookupManifest
|
libimageOptions.LookupManifest = opts.LookupManifest
|
||||||
if !opts.All {
|
if !opts.All {
|
||||||
libimageOptions.Filters = append(libimageOptions.Filters, "intermediate=false")
|
libimageOptions.Filters = append(libimageOptions.Filters, "intermediate=false")
|
||||||
|
|
|
@ -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) {
|
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)
|
return images.Remove(ir.ClientCtx, imagesArg, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -303,4 +303,13 @@ Deleted: $pauseID"
|
||||||
run_podman image exists $IMAGE
|
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
|
# vim: filetype=sh
|
||||||
|
|
Loading…
Reference in New Issue