Skip to content

Commit

Permalink
Merge pull request containers#633 from vrothberg/0.38-backports
Browse files Browse the repository at this point in the history
[0.38] libimage: force remove: only untag on multi tag image
  • Loading branch information
openshift-merge-robot authored Jun 18, 2021
2 parents 633e3d6 + d458b28 commit 99ee78d
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 8 deletions.
16 changes: 9 additions & 7 deletions libimage/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,17 +329,19 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport,
// an `rmi foo` will not untag "foo" but instead attempt to remove the
// entire image. If there's a container using "foo", we should get an
// error.
if options.Force || referencedBy == "" || numNames == 1 {
if referencedBy == "" || numNames == 1 {
// DO NOTHING, the image will be removed
} else {
byID := strings.HasPrefix(i.ID(), referencedBy)
byDigest := strings.HasPrefix(referencedBy, "sha256:")
if byID && numNames > 1 {
return errors.Errorf("unable to delete image %q by ID with more than one tag (%s): please force removal", i.ID(), i.Names())
} else if byDigest && numNames > 1 {
// FIXME - Docker will remove the digest but containers storage
// does not support that yet, so our hands are tied.
return errors.Errorf("unable to delete image %q by digest with more than one tag (%s): please force removal", i.ID(), i.Names())
if !options.Force {
if byID && numNames > 1 {
return errors.Errorf("unable to delete image %q by ID with more than one tag (%s): please force removal", i.ID(), i.Names())
} else if byDigest && numNames > 1 {
// FIXME - Docker will remove the digest but containers storage
// does not support that yet, so our hands are tied.
return errors.Errorf("unable to delete image %q by digest with more than one tag (%s): please force removal", i.ID(), i.Names())
}
}

// Only try to untag if we know it's not an ID or digest.
Expand Down
2 changes: 1 addition & 1 deletion libimage/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func TestLoad(t *testing.T) {
}

// Now remove the image.
rmReports, rmErrors := runtime.RemoveImages(ctx, loadedImages, &RemoveImagesOptions{Force: true})
rmReports, rmErrors := runtime.RemoveImages(ctx, ids, &RemoveImagesOptions{Force: true})
require.Len(t, rmErrors, 0)
require.Len(t, rmReports, test.numImages)

Expand Down
44 changes: 44 additions & 0 deletions libimage/remove_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package libimage

import (
"context"
"os"
"testing"

"github.com/containers/common/pkg/config"
"github.com/stretchr/testify/require"
)

func TestRemoveImages(t *testing.T) {
// Note: this will resolve pull from the GCR registry (see
// testdata/registries.conf).
busyboxLatest := "docker.io/library/busybox:latest"

runtime, cleanup := testNewRuntime(t)
defer cleanup()
ctx := context.Background()

pullOptions := &PullOptions{}
pullOptions.Writer = os.Stdout
pulledImages, err := runtime.Pull(ctx, busyboxLatest, config.PullPolicyAlways, pullOptions)
require.NoError(t, err)
require.Len(t, pulledImages, 1)

err = pulledImages[0].Tag("foobar")
require.NoError(t, err)

// containers/podman/issues/10685 - force removal on image with
// multiple tags will only untag but not remove all tags including the
// image.
rmReports, rmErrors := runtime.RemoveImages(ctx, []string{"foobar"}, &RemoveImagesOptions{Force: true})
require.Nil(t, rmErrors)
require.Len(t, rmReports, 1)
require.Equal(t, pulledImages[0].ID(), rmReports[0].ID)
require.False(t, rmReports[0].Removed)
require.Equal(t, []string{"localhost/foobar:latest"}, rmReports[0].Untagged)

// The busybox image is still present even if foobar was force removed.
exists, err := runtime.Exists(busyboxLatest)
require.NoError(t, err)
require.True(t, exists)
}

0 comments on commit 99ee78d

Please sign in to comment.