Skip to content

Commit

Permalink
Merge pull request #9266 from vrothberg/fix-6510
Browse files Browse the repository at this point in the history
make `podman rmi` more robust
  • Loading branch information
openshift-merge-robot authored Feb 8, 2021
2 parents c32913d + feecdf9 commit 2bf1321
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
17 changes: 13 additions & 4 deletions pkg/domain/infra/abi/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
30 changes: 30 additions & 0 deletions test/e2e/rmi_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package integration

import (
"fmt"
"os"
"sync"

. "github.com/containers/podman/v2/test/utils"
. "github.com/onsi/ginkgo"
Expand Down Expand Up @@ -275,4 +277,32 @@ RUN find $LOCAL
match, _ := session.ErrorGrepString("image name or ID must be specified")
Expect(match).To(BeTrue())
})

It("podman image rm - concurrent with shared layers", func() {
// #6510 has shown a fairly simple reproducer to force storage
// errors during parallel image removal. Since it's subject to
// a race, we may not hit the condition a 100 percent of times
// but ocal reproducers hit it all the time.

var wg sync.WaitGroup

buildAndRemove := func(i int) {
defer GinkgoRecover()
defer wg.Done()
imageName := fmt.Sprintf("rmtest:%d", i)
containerfile := `FROM quay.io/libpod/cirros:latest
RUN ` + fmt.Sprintf("touch %s", imageName)

podmanTest.BuildImage(containerfile, imageName, "false")
session := podmanTest.Podman([]string{"rmi", "-f", imageName})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
}

wg.Add(10)
for i := 0; i < 10; i++ {
go buildAndRemove(i)
}
wg.Wait()
})
})

0 comments on commit 2bf1321

Please sign in to comment.