diff options
author | Valentin Rothberg <rothberg@redhat.com> | 2021-02-08 13:51:31 +0100 |
---|---|---|
committer | Valentin Rothberg <rothberg@redhat.com> | 2021-02-08 14:58:17 +0100 |
commit | feecdf919f37d34033b58977e6af5c34bf26b6c4 (patch) | |
tree | c74b72d9e2700a4fa9f2227e571720a9d745e38c /pkg/domain | |
parent | 69ddbde9835159b19fab33f1dd22353e4b1ca484 (diff) | |
download | podman-feecdf919f37d34033b58977e6af5c34bf26b6c4.tar.gz podman-feecdf919f37d34033b58977e6af5c34bf26b6c4.tar.bz2 podman-feecdf919f37d34033b58977e6af5c34bf26b6c4.zip |
make `podman rmi` more robust
The c/storage library is subject to TOCTOUs as the central container and
image storage may be shared by many instances of many tools. As shown
in #6510, it's fairly easy to have multiple instances of Podman running
in parallel and yield image-lookup errors when removing them.
The underlying issue is the TOCTOU of removal being split into multiple
stages of first reading the local images and then removing them. Some
images may already have been removed in between the two stages. To make
image removal more robust, handle errors at stage two when a given image
is not present (anymore) in the storage.
Fixes: #6510
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'pkg/domain')
-rw-r--r-- | pkg/domain/infra/abi/images.go | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 8ca93e770..f2d0f2c39 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -580,12 +580,21 @@ func (ir *ImageEngine) Remove(ctx context.Context, images []string, opts entitie // without having to pass all local data around. deleteImage := func(img *image.Image) error { results, err := ir.Libpod.RemoveImage(ctx, img, opts.Force) - if err != nil { + switch errors.Cause(err) { + case nil: + // Removal worked, so let's report it. + report.Deleted = append(report.Deleted, results.Deleted) + report.Untagged = append(report.Untagged, results.Untagged...) + return nil + case storage.ErrImageUnknown: + // The image must have been removed already (see #6510). + report.Deleted = append(report.Deleted, img.ID()) + report.Untagged = append(report.Untagged, img.ID()) + return nil + default: + // Fatal error. return err } - report.Deleted = append(report.Deleted, results.Deleted) - report.Untagged = append(report.Untagged, results.Untagged...) - return nil } // Delete all images from the local storage. |