From 1b6423e9f172b6d2437011ef4504a8247728a73d Mon Sep 17 00:00:00 2001
From: Valentin Rothberg <rothberg@redhat.com>
Date: Mon, 19 Jul 2021 11:41:04 +0200
Subject: [PATCH] refine dangling checks

By proxy by vendoring containers/common. Previously, a "dangling" image
was an untagged image; just a described in the Docker docs. The
definition of dangling has now been refined to an untagged image without
children to be compatible with Docker.

Further update a redundant image-prune test.

Fixes: #10998
Fixes: #10832
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
---
 docs/source/markdown/podman-images.1.md       |  2 +-
 docs/source/markdown/podman-rmi.1.md          |  2 +-
 go.mod                                        |  4 +-
 go.sum                                        | 13 +--
 pkg/api/handlers/types.go                     |  7 +-
 pkg/domain/infra/abi/images_list.go           |  6 +-
 test/e2e/prune_test.go                        | 50 ++++++----
 .../github.com/containers/buildah/.cirrus.yml |  2 +-
 vendor/github.com/containers/buildah/add.go   | 39 +++++++-
 .../containers/buildah/chroot/run.go          | 15 +--
 vendor/github.com/containers/buildah/go.mod   |  8 +-
 vendor/github.com/containers/buildah/go.sum   | 20 ++--
 .../containers/buildah/imagebuildah/build.go  |  2 +-
 .../buildah/imagebuildah/executor.go          |  9 +-
 .../buildah/imagebuildah/stage_executor.go    | 22 ++---
 .../containers/buildah/imagebuildah/util.go   | 17 +---
 .../github.com/containers/buildah/install.md  |  4 +-
 .../containers/buildah/pkg/parse/parse.go     | 98 +++----------------
 .../containers/common/libimage/filters.go     | 10 +-
 .../containers/common/libimage/image.go       | 76 +++++++-------
 .../containers/common/libimage/layer_tree.go  | 90 +++++++++++++----
 .../containers/common/libimage/pull.go        | 17 ++++
 .../containers/common/libimage/runtime.go     | 38 ++++---
 vendor/modules.txt                            |  4 +-
 24 files changed, 300 insertions(+), 255 deletions(-)

diff --git a/docs/source/markdown/podman-images.1.md b/docs/source/markdown/podman-images.1.md
index 23cce450a2..02385daec6 100644
--- a/docs/source/markdown/podman-images.1.md
+++ b/docs/source/markdown/podman-images.1.md
@@ -36,7 +36,7 @@ Filter output based on conditions provided
     Filter on images created before the given IMAGE (name or tag).
 
   **dangling=true|false**
-    Show dangling images. Dangling images are a file system layer that was used in a previous build of an image and is no longer referenced by any active images. They are denoted with the `<none>` tag, consume disk space and serve no active purpose.
+    Show dangling images. Dangling images are a file system layer that was used in a previous build of an image and is no longer referenced by any image. They are denoted with the `<none>` tag, consume disk space and serve no active purpose.
 
   **label**
     Filter by images labels key and/or value.
diff --git a/docs/source/markdown/podman-rmi.1.md b/docs/source/markdown/podman-rmi.1.md
index 1f62d61332..e34b1964b9 100644
--- a/docs/source/markdown/podman-rmi.1.md
+++ b/docs/source/markdown/podman-rmi.1.md
@@ -10,7 +10,7 @@ podman\-rmi - Removes one or more locally stored images
 
 ## DESCRIPTION
 Removes one or more locally stored images.
-Passing an argument _image_ deletes it, along with any of its dangling (untagged) parent images.
+Passing an argument _image_ deletes it, along with any of its dangling parent images.  A dangling image is an image without a tag and without being referenced by another image.
 
 ## OPTIONS
 
diff --git a/go.mod b/go.mod
index 156ec6ef17..2ca9e27c6c 100644
--- a/go.mod
+++ b/go.mod
@@ -11,8 +11,8 @@ require (
 	github.com/container-orchestrated-devices/container-device-interface v0.0.0-20210325223243-f99e8b6c10b9
 	github.com/containernetworking/cni v0.8.1
 	github.com/containernetworking/plugins v0.9.1
-	github.com/containers/buildah v1.21.1-0.20210707133512-2eb97b499d74
-	github.com/containers/common v0.41.1-0.20210716140645-ffcfe1ff6e70
+	github.com/containers/buildah v1.21.1-0.20210721171232-54cafea4c933
+	github.com/containers/common v0.41.1-0.20210721172332-291287e9d060
 	github.com/containers/conmon v2.0.20+incompatible
 	github.com/containers/image/v5 v5.13.2
 	github.com/containers/ocicrypt v1.1.2
diff --git a/go.sum b/go.sum
index b42ab330b0..7b9e13c1dc 100644
--- a/go.sum
+++ b/go.sum
@@ -239,11 +239,11 @@ github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHV
 github.com/containernetworking/plugins v0.8.7/go.mod h1:R7lXeZaBzpfqapcAbHRW8/CYwm0dHzbz0XEjofx0uB0=
 github.com/containernetworking/plugins v0.9.1 h1:FD1tADPls2EEi3flPc2OegIY1M9pUa9r2Quag7HMLV8=
 github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
-github.com/containers/buildah v1.21.1-0.20210707133512-2eb97b499d74 h1:u+Wk1Gv+UgOR0AHmlpbH+ZsdfZt7vkGuiKCyhbI4Ga0=
-github.com/containers/buildah v1.21.1-0.20210707133512-2eb97b499d74/go.mod h1:P0rxPkI7440rWVMkbPkSHX4j1PxjOcx+cY8QrqYgdLE=
-github.com/containers/common v0.40.2-0.20210707094508-0a4a1906d4b2/go.mod h1:thow5Jn7O+rP01njI9COQ16L9g/KQ1LcMcYqP2NhYCU=
-github.com/containers/common v0.41.1-0.20210716140645-ffcfe1ff6e70 h1:9kKqg10PfrLQdsN4lw/n8XIuqLk43JwwAcE4klCvOsI=
-github.com/containers/common v0.41.1-0.20210716140645-ffcfe1ff6e70/go.mod h1:w0CLPB8nH75msgISbE/z8TMIxK9disFsmvFNd2SDid8=
+github.com/containers/buildah v1.21.1-0.20210721171232-54cafea4c933 h1:jqO3hDypBoKM5be+fVcqGHOpX2fOiQy2DFEeb/VKpsk=
+github.com/containers/buildah v1.21.1-0.20210721171232-54cafea4c933/go.mod h1:9gspFNeUJxIK72n1IMIKIHmtcePEZQsv0tjo+1LqkCo=
+github.com/containers/common v0.41.1-0.20210721112610-c95d2f794edf/go.mod h1:Ba5YVNCnyX6xDtg1JqEHa2EMVMW5UbHmIyEqsEwpeGE=
+github.com/containers/common v0.41.1-0.20210721172332-291287e9d060 h1:HgGff2MeEKfYoKp2WQFl9xdsgP7KV8rr/1JZRIuPXmg=
+github.com/containers/common v0.41.1-0.20210721172332-291287e9d060/go.mod h1:Ba5YVNCnyX6xDtg1JqEHa2EMVMW5UbHmIyEqsEwpeGE=
 github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
 github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
 github.com/containers/image/v5 v5.13.2 h1:AgYunV/9d2fRkrmo23wH2MkqeHolFd6oQCkK+1PpuFA=
@@ -259,7 +259,6 @@ github.com/containers/psgo v1.5.2 h1:3aoozst/GIwsrr/5jnFy3FrJay98uujPCu9lTuSZ/Cw
 github.com/containers/psgo v1.5.2/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzPUWfawVU=
 github.com/containers/storage v1.23.5/go.mod h1:ha26Q6ngehFNhf3AWoXldvAvwI4jFe3ETQAf/CeZPyM=
 github.com/containers/storage v1.32.2/go.mod h1:YIBxxjfXZTi04Ah49sh1uSGfmT1V89+I5i3deRobzQo=
-github.com/containers/storage v1.32.5/go.mod h1:8/DVVDqniaUlUV0D0q7cEnXK6Bs2uU3FPqNZVPumwEs=
 github.com/containers/storage v1.32.6 h1:NqdFRewXO/PYPjgCAScoigZc5QUA21yapSEj6kqD8cw=
 github.com/containers/storage v1.32.6/go.mod h1:mdB+b89p+jU8zpzLTVXA0gWMmIo0WrkfGMh1R8O2IQw=
 github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
@@ -698,7 +697,6 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
 github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
 github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
-github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
 github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
 github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
@@ -709,7 +707,6 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
 github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
-github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
 github.com/onsi/gomega v1.14.0 h1:ep6kpPVwmr/nTbklSx2nrLNSIO62DoYAhnPNIMhK8gI=
 github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
 github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go
index 3cc10d70f9..af58787985 100644
--- a/pkg/api/handlers/types.go
+++ b/pkg/api/handlers/types.go
@@ -176,6 +176,11 @@ func ImageToImageSummary(l *libimage.Image) (*entities.ImageSummary, error) {
 	}
 	containerCount := len(containers)
 
+	isDangling, err := l.IsDangling(context.TODO())
+	if err != nil {
+		return nil, errors.Wrapf(err, "failed to check if image %s is dangling", l.ID())
+	}
+
 	is := entities.ImageSummary{
 		ID:           l.ID(),
 		ParentId:     imageData.Parent,
@@ -188,7 +193,7 @@ func ImageToImageSummary(l *libimage.Image) (*entities.ImageSummary, error) {
 		Labels:       imageData.Labels,
 		Containers:   containerCount,
 		ReadOnly:     l.IsReadOnly(),
-		Dangling:     l.IsDangling(),
+		Dangling:     isDangling,
 		Names:        l.Names(),
 		Digest:       string(imageData.Digest),
 		ConfigDigest: "", // TODO: libpod/image didn't set it but libimage should
diff --git a/pkg/domain/infra/abi/images_list.go b/pkg/domain/infra/abi/images_list.go
index b0e9479919..2ec4ad244c 100644
--- a/pkg/domain/infra/abi/images_list.go
+++ b/pkg/domain/infra/abi/images_list.go
@@ -30,12 +30,16 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions)
 		for j, d := range img.Digests() {
 			digests[j] = string(d)
 		}
+		isDangling, err := img.IsDangling(ctx)
+		if err != nil {
+			return nil, errors.Wrapf(err, "error checking if image %q is dangling", img.ID())
+		}
 
 		e := entities.ImageSummary{
 			ID: img.ID(),
 			//			ConfigDigest: string(img.ConfigDigest),
 			Created:     img.Created().Unix(),
-			Dangling:    img.IsDangling(),
+			Dangling:    isDangling,
 			Digest:      string(img.Digest()),
 			RepoDigests: digests,
 			History:     img.NamesHistory(),
diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go
index 68ccd0a947..ff70a8cf49 100644
--- a/test/e2e/prune_test.go
+++ b/test/e2e/prune_test.go
@@ -16,6 +16,11 @@ LABEL RUN podman --version
 RUN apk update
 RUN apk add bash`, ALPINE)
 
+var emptyPruneImage = `
+FROM scratch
+ENV test1=test1
+ENV test2=test2`
+
 var _ = Describe("Podman prune", func() {
 	var (
 		tempdir    string
@@ -110,8 +115,12 @@ var _ = Describe("Podman prune", func() {
 		Expect(session).Should(Exit(0))
 		Expect(len(session.OutputToStringArray())).To(Equal(numImages))
 
-		// Now build a new image with dangling intermediate images.
+		// Now build an image and untag it.  The (intermediate) images
+		// should be removed recursively during pruning.
 		podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true")
+		session = podmanTest.Podman([]string{"untag", "alpine_bash:latest"})
+		session.WaitWithDefaultTimeout()
+		Expect(session).Should(Exit(0))
 
 		session = podmanTest.Podman([]string{"images", "-a"})
 		session.WaitWithDefaultTimeout()
@@ -136,26 +145,33 @@ var _ = Describe("Podman prune", func() {
 		Expect(len(session.OutputToStringArray())).To(Equal(numImages - numPrunedImages))
 	})
 
-	It("podman image prune skip cache images", func() {
-		podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true")
+	It("podman image prune - handle empty images", func() {
+		// As shown in #10832, empty images were not treated correctly
+		// in Podman.
+		podmanTest.BuildImage(emptyPruneImage, "empty:scratch", "true")
 
-		none := podmanTest.Podman([]string{"images", "-a"})
-		none.WaitWithDefaultTimeout()
-		Expect(none).Should(Exit(0))
-		hasNone, _ := none.GrepString("<none>")
+		session := podmanTest.Podman([]string{"images", "-a"})
+		session.WaitWithDefaultTimeout()
+		Expect(session).Should(Exit(0))
+		hasNone, _ := session.GrepString("<none>")
 		Expect(hasNone).To(BeTrue())
 
-		prune := podmanTest.Podman([]string{"image", "prune", "-f"})
-		prune.WaitWithDefaultTimeout()
-		Expect(prune).Should(Exit(0))
+		// Nothing will be pruned.
+		session = podmanTest.Podman([]string{"image", "prune", "-f"})
+		session.WaitWithDefaultTimeout()
+		Expect(session).Should(Exit(0))
+		Expect(len(session.OutputToStringArray())).To(Equal(0))
 
-		after := podmanTest.Podman([]string{"images", "-a"})
-		after.WaitWithDefaultTimeout()
-		Expect(none).Should(Exit(0))
-		// Check if all "dangling" images were pruned.
-		hasNoneAfter, _ := after.GrepString("<none>")
-		Expect(hasNoneAfter).To(BeFalse())
-		Expect(len(after.OutputToStringArray()) > 1).To(BeTrue())
+		// Now the image will be untagged, and its parent images will
+		// be removed recursively.
+		session = podmanTest.Podman([]string{"untag", "empty:scratch"})
+		session.WaitWithDefaultTimeout()
+		Expect(session).Should(Exit(0))
+
+		session = podmanTest.Podman([]string{"image", "prune", "-f"})
+		session.WaitWithDefaultTimeout()
+		Expect(session).Should(Exit(0))
+		Expect(len(session.OutputToStringArray())).To(Equal(2))
 	})
 
 	It("podman image prune dangling images", func() {
diff --git a/vendor/github.com/containers/buildah/.cirrus.yml b/vendor/github.com/containers/buildah/.cirrus.yml
index 849e45f8a6..73ab4fc117 100644
--- a/vendor/github.com/containers/buildah/.cirrus.yml
+++ b/vendor/github.com/containers/buildah/.cirrus.yml
@@ -30,7 +30,7 @@ env:
     UBUNTU_NAME: "ubuntu-2104"
     PRIOR_UBUNTU_NAME: "ubuntu-2010"
 
-    IMAGE_SUFFIX: "c6534244118822912"
+    IMAGE_SUFFIX: "c6248193773010944"
     FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
     PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}"
     UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX}"
diff --git a/vendor/github.com/containers/buildah/add.go b/vendor/github.com/containers/buildah/add.go
index ad178dc6b2..f17e3a9c94 100644
--- a/vendor/github.com/containers/buildah/add.go
+++ b/vendor/github.com/containers/buildah/add.go
@@ -602,12 +602,43 @@ func (b *Builder) userForRun(mountPoint string, userspec string) (specs.User, st
 // userForRun() does, except for the case where we're passed a single numeric
 // value, where we need to use that value for both the UID and the GID.
 func (b *Builder) userForCopy(mountPoint string, userspec string) (uint32, uint32, error) {
-	if id, err := strconv.ParseUint(userspec, 10, 32); err == nil {
-		return uint32(id), uint32(id), nil
+	var (
+		user, group string
+		uid, gid    uint64
+		err         error
+	)
+
+	split := strings.SplitN(userspec, ":", 2)
+	user = split[0]
+	if len(split) > 1 {
+		group = split[1]
 	}
-	user, _, err := b.userForRun(mountPoint, userspec)
+
+	// If userspec did not specify any values for user or group, then fail
+	if user == "" && group == "" {
+		return 0, 0, errors.Errorf("can't find uid for user %s", userspec)
+	}
+
+	// If userspec specifies values for user or group, check for numeric values
+	// and return early.  If not, then translate username/groupname
+	if user != "" {
+		uid, err = strconv.ParseUint(user, 10, 32)
+	}
+	if err == nil {
+		// default gid to uid
+		gid = uid
+		if group != "" {
+			gid, err = strconv.ParseUint(group, 10, 32)
+		}
+	}
+	// If err != nil, then user or group not numeric, check filesystem
+	if err == nil {
+		return uint32(uid), uint32(gid), nil
+	}
+
+	owner, _, err := b.userForRun(mountPoint, userspec)
 	if err != nil {
 		return 0xffffffff, 0xffffffff, err
 	}
-	return user.UID, user.GID, nil
+	return owner.UID, owner.GID, nil
 }
diff --git a/vendor/github.com/containers/buildah/chroot/run.go b/vendor/github.com/containers/buildah/chroot/run.go
index 7cb1d710e6..591003568c 100644
--- a/vendor/github.com/containers/buildah/chroot/run.go
+++ b/vendor/github.com/containers/buildah/chroot/run.go
@@ -161,7 +161,7 @@ func RunUsingChroot(spec *specs.Spec, bundlePath, homeDir string, stdin io.Reade
 	cmd := unshare.Command(runUsingChrootCommand)
 	cmd.Stdin, cmd.Stdout, cmd.Stderr = stdin, stdout, stderr
 	cmd.Dir = "/"
-	cmd.Env = append([]string{fmt.Sprintf("LOGLEVEL=%d", logrus.GetLevel())}, os.Environ()...)
+	cmd.Env = []string{fmt.Sprintf("LOGLEVEL=%d", logrus.GetLevel())}
 
 	logrus.Debugf("Running %#v in %#v", cmd.Cmd, cmd)
 	confwg.Add(1)
@@ -207,7 +207,7 @@ func runUsingChrootMain() {
 		os.Exit(1)
 	}
 
-	if options.Spec == nil {
+	if options.Spec == nil || options.Spec.Process == nil {
 		fmt.Fprintf(os.Stderr, "invalid options spec in runUsingChrootMain\n")
 		os.Exit(1)
 	}
@@ -573,7 +573,7 @@ func runUsingChroot(spec *specs.Spec, bundlePath string, ctty *os.File, stdin io
 	cmd := unshare.Command(append([]string{runUsingChrootExecCommand}, spec.Process.Args...)...)
 	cmd.Stdin, cmd.Stdout, cmd.Stderr = stdin, stdout, stderr
 	cmd.Dir = "/"
-	cmd.Env = append([]string{fmt.Sprintf("LOGLEVEL=%d", logrus.GetLevel())}, os.Environ()...)
+	cmd.Env = []string{fmt.Sprintf("LOGLEVEL=%d", logrus.GetLevel())}
 	cmd.UnshareFlags = syscall.CLONE_NEWUTS | syscall.CLONE_NEWNS
 	requestedUserNS := false
 	for _, ns := range spec.Linux.Namespaces {
@@ -663,7 +663,7 @@ func runUsingChrootExecMain() {
 	// Set the hostname.  We're already in a distinct UTS namespace and are admins in the user
 	// namespace which created it, so we shouldn't get a permissions error, but seccomp policy
 	// might deny our attempt to call sethostname() anyway, so log a debug message for that.
-	if options.Spec == nil {
+	if options.Spec == nil || options.Spec.Process == nil {
 		fmt.Fprintf(os.Stderr, "invalid options spec passed in\n")
 		os.Exit(1)
 	}
@@ -819,7 +819,6 @@ func runUsingChrootExecMain() {
 // Output debug messages when that differs from what we're being asked to do.
 func logNamespaceDiagnostics(spec *specs.Spec) {
 	sawMountNS := false
-	sawUserNS := false
 	sawUTSNS := false
 	for _, ns := range spec.Linux.Namespaces {
 		switch ns.Type {
@@ -854,9 +853,8 @@ func logNamespaceDiagnostics(spec *specs.Spec) {
 			}
 		case specs.UserNamespace:
 			if ns.Path != "" {
-				logrus.Debugf("unable to join user namespace %q, creating a new one", ns.Path)
+				logrus.Debugf("unable to join user namespace, sorry about that")
 			}
-			sawUserNS = true
 		case specs.UTSNamespace:
 			if ns.Path != "" {
 				logrus.Debugf("unable to join UTS namespace %q, creating a new one", ns.Path)
@@ -867,9 +865,6 @@ func logNamespaceDiagnostics(spec *specs.Spec) {
 	if !sawMountNS {
 		logrus.Debugf("mount namespace not requested, but creating a new one anyway")
 	}
-	if !sawUserNS {
-		logrus.Debugf("user namespace not requested, but creating a new one anyway")
-	}
 	if !sawUTSNS {
 		logrus.Debugf("UTS namespace not requested, but creating a new one anyway")
 	}
diff --git a/vendor/github.com/containers/buildah/go.mod b/vendor/github.com/containers/buildah/go.mod
index 494d1e2117..68721b73cf 100644
--- a/vendor/github.com/containers/buildah/go.mod
+++ b/vendor/github.com/containers/buildah/go.mod
@@ -4,10 +4,10 @@ go 1.12
 
 require (
 	github.com/containernetworking/cni v0.8.1
-	github.com/containers/common v0.40.2-0.20210707094508-0a4a1906d4b2
+	github.com/containers/common v0.41.1-0.20210721112610-c95d2f794edf
 	github.com/containers/image/v5 v5.13.2
 	github.com/containers/ocicrypt v1.1.2
-	github.com/containers/storage v1.32.5
+	github.com/containers/storage v1.32.6
 	github.com/docker/distribution v2.7.1+incompatible
 	github.com/docker/go-units v0.4.0
 	github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316
@@ -18,10 +18,10 @@ require (
 	github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect
 	github.com/mattn/go-shellwords v1.0.12
 	github.com/onsi/ginkgo v1.16.4
-	github.com/onsi/gomega v1.13.0
+	github.com/onsi/gomega v1.14.0
 	github.com/opencontainers/go-digest v1.0.0
 	github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6
-	github.com/opencontainers/runc v1.0.0
+	github.com/opencontainers/runc v1.0.1
 	github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
 	github.com/opencontainers/runtime-tools v0.9.0
 	github.com/opencontainers/selinux v1.8.2
diff --git a/vendor/github.com/containers/buildah/go.sum b/vendor/github.com/containers/buildah/go.sum
index 5616f98b5e..ce7eb6c747 100644
--- a/vendor/github.com/containers/buildah/go.sum
+++ b/vendor/github.com/containers/buildah/go.sum
@@ -73,8 +73,9 @@ github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg3
 github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
 github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
 github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
-github.com/Microsoft/hcsshim v0.8.17 h1:yFHH5bghP9ij5Y34PPaMOE8g//oXZ0uJQeMENVo2zcI=
 github.com/Microsoft/hcsshim v0.8.17/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
+github.com/Microsoft/hcsshim v0.8.20 h1:ZTwcx3NS8n07kPf/JZ1qwU6vnjhVPMUWlXBF8r9UxrE=
+github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
 github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
 github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
 github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
@@ -136,6 +137,7 @@ github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX
 github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
 github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
 github.com/cilium/ebpf v0.6.1/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
+github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
@@ -223,8 +225,8 @@ github.com/containernetworking/cni v0.8.1 h1:7zpDnQ3T3s4ucOuJ/ZCLrYBxzkg0AELFfII
 github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
 github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
 github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
-github.com/containers/common v0.40.2-0.20210707094508-0a4a1906d4b2 h1:2ApmOS9jSnJXuSOkZNEAZ7j0/9i8zjoi67b/UpUjPxY=
-github.com/containers/common v0.40.2-0.20210707094508-0a4a1906d4b2/go.mod h1:thow5Jn7O+rP01njI9COQ16L9g/KQ1LcMcYqP2NhYCU=
+github.com/containers/common v0.41.1-0.20210721112610-c95d2f794edf h1:z0ciG0ByyJG3WCBpLYd2XLThCC7UBaH7GeSfXY4sAqc=
+github.com/containers/common v0.41.1-0.20210721112610-c95d2f794edf/go.mod h1:Ba5YVNCnyX6xDtg1JqEHa2EMVMW5UbHmIyEqsEwpeGE=
 github.com/containers/image/v5 v5.13.2 h1:AgYunV/9d2fRkrmo23wH2MkqeHolFd6oQCkK+1PpuFA=
 github.com/containers/image/v5 v5.13.2/go.mod h1:GkWursKDlDcUIT7L7vZf70tADvZCk/Ga0wgS0MuF0ag=
 github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
@@ -235,8 +237,8 @@ github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B
 github.com/containers/ocicrypt v1.1.2 h1:Ez+GAMP/4GLix5Ywo/fL7O0nY771gsBIigiqUm1aXz0=
 github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
 github.com/containers/storage v1.32.2/go.mod h1:YIBxxjfXZTi04Ah49sh1uSGfmT1V89+I5i3deRobzQo=
-github.com/containers/storage v1.32.5 h1:DXgmyA+oOs7YAzKkEqgC5O8l2UuDGJcwEFbdt49qiak=
-github.com/containers/storage v1.32.5/go.mod h1:8/DVVDqniaUlUV0D0q7cEnXK6Bs2uU3FPqNZVPumwEs=
+github.com/containers/storage v1.32.6 h1:NqdFRewXO/PYPjgCAScoigZc5QUA21yapSEj6kqD8cw=
+github.com/containers/storage v1.32.6/go.mod h1:mdB+b89p+jU8zpzLTVXA0gWMmIo0WrkfGMh1R8O2IQw=
 github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
 github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
@@ -609,7 +611,6 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
 github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
-github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
 github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
 github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
@@ -618,8 +619,8 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
-github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak=
-github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
+github.com/onsi/gomega v1.14.0 h1:ep6kpPVwmr/nTbklSx2nrLNSIO62DoYAhnPNIMhK8gI=
+github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
 github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
 github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
 github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@@ -636,8 +637,9 @@ github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h
 github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
 github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
 github.com/opencontainers/runc v1.0.0-rc95/go.mod h1:z+bZxa/+Tz/FmYVWkhUajJdzFeOqjc5vrqskhVyHGUM=
-github.com/opencontainers/runc v1.0.0 h1:QOhAQAYUlKeofuyeKdR6ITvOnXLPbEAjPMjz9wCUXcU=
 github.com/opencontainers/runc v1.0.0/go.mod h1:MU2S3KEB2ZExnhnAQYbwjdYV6HwKtDlNbA2Z2OeNDeA=
+github.com/opencontainers/runc v1.0.1 h1:G18PGckGdAm3yVQRWDVQ1rLSLntiniKJ0cNRT2Tm5gs=
+github.com/opencontainers/runc v1.0.1/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
 github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
 github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
 github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
diff --git a/vendor/github.com/containers/buildah/imagebuildah/build.go b/vendor/github.com/containers/buildah/imagebuildah/build.go
index a315d7f7d1..954ef7f8a1 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/build.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/build.go
@@ -39,7 +39,7 @@ const (
 )
 
 // Mount is a mountpoint for the build container.
-type Mount specs.Mount
+type Mount = specs.Mount
 
 type BuildOptions = define.BuildOptions
 
diff --git a/vendor/github.com/containers/buildah/imagebuildah/executor.go b/vendor/github.com/containers/buildah/imagebuildah/executor.go
index c754ae3c0c..606015ba75 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/executor.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/executor.go
@@ -165,8 +165,7 @@ func NewExecutor(logger *logrus.Logger, store storage.Store, options define.Buil
 		if err != nil {
 			return nil, err
 		}
-
-		transientMounts = append([]Mount{Mount(mount)}, transientMounts...)
+		transientMounts = append([]Mount{mount}, transientMounts...)
 	}
 
 	secrets, err := parse.Secrets(options.CommonBuildOpts.Secrets)
@@ -569,7 +568,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
 	// Build maps of every named base image and every referenced stage root
 	// filesystem.  Individual stages can use them to determine whether or
 	// not they can skip certain steps near the end of their stages.
-	for _, stage := range stages {
+	for stageIndex, stage := range stages {
 		node := stage.Node // first line
 		for node != nil {  // each line
 			for _, child := range node.Children { // tokens on this line, though we only care about the first
@@ -589,7 +588,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
 							// FROM instruction uses argument values,
 							// we might not record the right value here.
 							b.baseMap[base] = true
-							logrus.Debugf("base: %q", base)
+							logrus.Debugf("base for stage %d: %q", stageIndex, base)
 						}
 					}
 				case "ADD", "COPY":
@@ -601,7 +600,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
 							// not record the right value here.
 							rootfs := strings.TrimPrefix(flag, "--from=")
 							b.rootfsMap[rootfs] = true
-							logrus.Debugf("rootfs: %q", rootfs)
+							logrus.Debugf("rootfs needed for COPY in stage %d: %q", stageIndex, rootfs)
 						}
 					}
 				}
diff --git a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
index be105901bb..d3d5cc7c40 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
@@ -434,7 +434,7 @@ func (s *StageExecutor) Run(run imagebuilder.Run, config docker.Config) error {
 		Runtime:          s.executor.runtime,
 		Args:             s.executor.runtimeArgs,
 		NoPivot:          os.Getenv("BUILDAH_NOPIVOT") != "",
-		Mounts:           convertMounts(s.executor.transientMounts),
+		Mounts:           append([]Mount{}, s.executor.transientMounts...),
 		Env:              config.Env,
 		User:             config.User,
 		WorkingDir:       config.WorkingDir,
@@ -557,13 +557,6 @@ func (s *StageExecutor) prepare(ctx context.Context, from string, initializeIBCo
 		OciDecryptConfig:      s.executor.ociDecryptConfig,
 	}
 
-	// Check and see if the image is a pseudonym for the end result of a
-	// previous stage, named by an AS clause in the Dockerfile.
-	s.executor.stagesLock.Lock()
-	if asImageFound, ok := s.executor.imageMap[from]; ok {
-		builderOptions.FromImage = asImageFound
-	}
-	s.executor.stagesLock.Unlock()
 	builder, err = buildah.NewBuilder(ctx, s.executor.store, builderOptions)
 	if err != nil {
 		return nil, errors.Wrapf(err, "error creating build container")
@@ -684,15 +677,20 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
 
 	// If the base image's name corresponds to the result of an earlier
 	// stage, make sure that stage has finished building an image, and
-	// substitute that image's ID for the base image's name here.  If not,
-	// then go on assuming that it's just a regular image that's either in
-	// local storage, or one that we have to pull from a registry.
+	// substitute that image's ID for the base image's name here and force
+	// the pull policy to "never" to avoid triggering an error when it's
+	// set to "always", which doesn't make sense for image IDs.
+	// If not, then go on assuming that it's just a regular image that's
+	// either in local storage, or one that we have to pull from a
+	// registry, subject to the passed-in pull policy.
 	if isStage, err := s.executor.waitForStage(ctx, base, s.stages[:s.index]); isStage && err != nil {
 		return "", nil, err
 	}
+	pullPolicy := s.executor.pullPolicy
 	s.executor.stagesLock.Lock()
 	if stageImage, isPreviousStage := s.executor.imageMap[base]; isPreviousStage {
 		base = stageImage
+		pullPolicy = define.PullNever
 	}
 	s.executor.stagesLock.Unlock()
 
@@ -723,7 +721,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
 	// Create the (first) working container for this stage.  Reinitializing
 	// the imagebuilder configuration may alter the list of steps we have,
 	// so take a snapshot of them *after* that.
-	if _, err := s.prepare(ctx, base, true, true, s.executor.pullPolicy); err != nil {
+	if _, err := s.prepare(ctx, base, true, true, pullPolicy); err != nil {
 		return "", nil, err
 	}
 	children := stage.Node.Children
diff --git a/vendor/github.com/containers/buildah/imagebuildah/util.go b/vendor/github.com/containers/buildah/imagebuildah/util.go
index 7519672bf5..598e407a86 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/util.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/util.go
@@ -2,26 +2,11 @@ package imagebuildah
 
 import (
 	"github.com/containers/buildah"
-	"github.com/opencontainers/runtime-spec/specs-go"
 )
 
 // InitReexec is a wrapper for buildah.InitReexec().  It should be called at
 // the start of main(), and if it returns true, main() should return
-// immediately.
+// successfully immediately.
 func InitReexec() bool {
 	return buildah.InitReexec()
 }
-
-func convertMounts(mounts []Mount) []specs.Mount {
-	specmounts := []specs.Mount{}
-	for _, m := range mounts {
-		s := specs.Mount{
-			Destination: m.Destination,
-			Type:        m.Type,
-			Source:      m.Source,
-			Options:     m.Options,
-		}
-		specmounts = append(specmounts, s)
-	}
-	return specmounts
-}
diff --git a/vendor/github.com/containers/buildah/install.md b/vendor/github.com/containers/buildah/install.md
index 0cec56c755..30ec26cc3b 100644
--- a/vendor/github.com/containers/buildah/install.md
+++ b/vendor/github.com/containers/buildah/install.md
@@ -153,9 +153,7 @@ sudo apt-get -qq -y install buildah
 
 ### Kernel Version Requirements
 To run Buildah on Red Hat Enterprise Linux or CentOS, version 7.4 or higher is required.
-On other Linux distributions Buildah requires a kernel version of 4.0 or
-higher in order to support the OverlayFS filesystem.  The kernel version can be checked
-with the 'uname -a' command.
+On other Linux distributions Buildah requires a kernel version that supports the OverlayFS and/or fuse-overlayfs filesystem -- you'll need to consult your distribution's documentation to determine a minimum version number.
 
 ### runc Requirement
 
diff --git a/vendor/github.com/containers/buildah/pkg/parse/parse.go b/vendor/github.com/containers/buildah/pkg/parse/parse.go
index 0a09dd75ac..5ba2f51d07 100644
--- a/vendor/github.com/containers/buildah/pkg/parse/parse.go
+++ b/vendor/github.com/containers/buildah/pkg/parse/parse.go
@@ -15,6 +15,7 @@ import (
 	"unicode"
 
 	"github.com/containers/buildah/define"
+	"github.com/containers/common/pkg/parse"
 	"github.com/containers/image/v5/types"
 	"github.com/containers/storage/pkg/idtools"
 	"github.com/containers/storage/pkg/unshare"
@@ -205,13 +206,13 @@ func Volume(volume string) (specs.Mount, error) {
 	if err := validateVolumeMountHostDir(arr[0]); err != nil {
 		return mount, err
 	}
-	if err := ValidateVolumeCtrDir(arr[1]); err != nil {
+	if err := parse.ValidateVolumeCtrDir(arr[1]); err != nil {
 		return mount, err
 	}
 	mountOptions := ""
 	if len(arr) > 2 {
 		mountOptions = arr[2]
-		if _, err := ValidateVolumeOpts(strings.Split(arr[2], ",")); err != nil {
+		if _, err := parse.ValidateVolumeOpts(strings.Split(arr[2], ",")); err != nil {
 			return mount, err
 		}
 	}
@@ -360,7 +361,7 @@ func GetBindMount(args []string) (specs.Mount, error) {
 			if len(kv) == 1 {
 				return newMount, errors.Wrapf(optionArgError, kv[0])
 			}
-			if err := ValidateVolumeHostDir(kv[1]); err != nil {
+			if err := parse.ValidateVolumeHostDir(kv[1]); err != nil {
 				return newMount, err
 			}
 			newMount.Source = kv[1]
@@ -369,7 +370,7 @@ func GetBindMount(args []string) (specs.Mount, error) {
 			if len(kv) == 1 {
 				return newMount, errors.Wrapf(optionArgError, kv[0])
 			}
-			if err := ValidateVolumeCtrDir(kv[1]); err != nil {
+			if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
 				return newMount, err
 			}
 			newMount.Destination = kv[1]
@@ -391,7 +392,7 @@ func GetBindMount(args []string) (specs.Mount, error) {
 		newMount.Source = newMount.Destination
 	}
 
-	opts, err := ValidateVolumeOpts(newMount.Options)
+	opts, err := parse.ValidateVolumeOpts(newMount.Options)
 	if err != nil {
 		return newMount, err
 	}
@@ -433,7 +434,7 @@ func GetTmpfsMount(args []string) (specs.Mount, error) {
 			if len(kv) == 1 {
 				return newMount, errors.Wrapf(optionArgError, kv[0])
 			}
-			if err := ValidateVolumeCtrDir(kv[1]); err != nil {
+			if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
 				return newMount, err
 			}
 			newMount.Destination = kv[1]
@@ -452,17 +453,7 @@ func GetTmpfsMount(args []string) (specs.Mount, error) {
 
 // ValidateVolumeHostDir validates a volume mount's source directory
 func ValidateVolumeHostDir(hostDir string) error {
-	if len(hostDir) == 0 {
-		return errors.Errorf("host directory cannot be empty")
-	}
-	if filepath.IsAbs(hostDir) {
-		if _, err := os.Stat(hostDir); err != nil {
-			return errors.WithStack(err)
-		}
-	}
-	// If hostDir is not an absolute path, that means the user wants to create a
-	// named volume. This will be done later on in the code.
-	return nil
+	return parse.ValidateVolumeHostDir(hostDir)
 }
 
 // validates the host path of buildah --volume
@@ -478,75 +469,12 @@ func validateVolumeMountHostDir(hostDir string) error {
 
 // ValidateVolumeCtrDir validates a volume mount's destination directory.
 func ValidateVolumeCtrDir(ctrDir string) error {
-	if len(ctrDir) == 0 {
-		return errors.Errorf("container directory cannot be empty")
-	}
-	if !filepath.IsAbs(ctrDir) {
-		return errors.Errorf("invalid container path %q, must be an absolute path", ctrDir)
-	}
-	return nil
+	return parse.ValidateVolumeCtrDir(ctrDir)
 }
 
 // ValidateVolumeOpts validates a volume's options
 func ValidateVolumeOpts(options []string) ([]string, error) {
-	var foundRootPropagation, foundRWRO, foundLabelChange, bindType, foundExec, foundDev, foundSuid, foundChown int
-	finalOpts := make([]string, 0, len(options))
-	for _, opt := range options {
-		switch opt {
-		case "noexec", "exec":
-			foundExec++
-			if foundExec > 1 {
-				return nil, errors.Errorf("invalid options %q, can only specify 1 'noexec' or 'exec' option", strings.Join(options, ", "))
-			}
-		case "nodev", "dev":
-			foundDev++
-			if foundDev > 1 {
-				return nil, errors.Errorf("invalid options %q, can only specify 1 'nodev' or 'dev' option", strings.Join(options, ", "))
-			}
-		case "nosuid", "suid":
-			foundSuid++
-			if foundSuid > 1 {
-				return nil, errors.Errorf("invalid options %q, can only specify 1 'nosuid' or 'suid' option", strings.Join(options, ", "))
-			}
-		case "rw", "ro":
-			foundRWRO++
-			if foundRWRO > 1 {
-				return nil, errors.Errorf("invalid options %q, can only specify 1 'rw' or 'ro' option", strings.Join(options, ", "))
-			}
-		case "z", "Z", "O":
-			foundLabelChange++
-			if foundLabelChange > 1 {
-				return nil, errors.Errorf("invalid options %q, can only specify 1 'z', 'Z', or 'O' option", strings.Join(options, ", "))
-			}
-		case "U":
-			foundChown++
-			if foundChown > 1 {
-				return nil, errors.Errorf("invalid options %q, can only specify 1 'U' option", strings.Join(options, ", "))
-			}
-		case "private", "rprivate", "shared", "rshared", "slave", "rslave", "unbindable", "runbindable":
-			foundRootPropagation++
-			if foundRootPropagation > 1 {
-				return nil, errors.Errorf("invalid options %q, can only specify 1 '[r]shared', '[r]private', '[r]slave' or '[r]unbindable' option", strings.Join(options, ", "))
-			}
-		case "bind", "rbind":
-			bindType++
-			if bindType > 1 {
-				return nil, errors.Errorf("invalid options %q, can only specify 1 '[r]bind' option", strings.Join(options, ", "))
-			}
-		case "cached", "delegated":
-			// The discarded ops are OS X specific volume options
-			// introduced in a recent Docker version.
-			// They have no meaning on Linux, so here we silently
-			// drop them. This matches Docker's behavior (the options
-			// are intended to be always safe to use, even not on OS
-			// X).
-			continue
-		default:
-			return nil, errors.Errorf("invalid option type %q", opt)
-		}
-		finalOpts = append(finalOpts, opt)
-	}
-	return finalOpts, nil
+	return parse.ValidateVolumeOpts(options)
 }
 
 // validateExtraHost validates that the specified string is a valid extrahost and returns it.
@@ -601,7 +529,7 @@ func SystemContextFromOptions(c *cobra.Command) (*types.SystemContext, error) {
 	creds, err := c.Flags().GetString("creds")
 	if err == nil && c.Flag("creds").Changed {
 		var err error
-		ctx.DockerAuthConfig, err = getDockerAuth(creds)
+		ctx.DockerAuthConfig, err = AuthConfig(creds)
 		if err != nil {
 			return nil, err
 		}
@@ -734,7 +662,9 @@ func parseCreds(creds string) (string, string) {
 	return up[0], up[1]
 }
 
-func getDockerAuth(creds string) (*types.DockerAuthConfig, error) {
+// AuthConfig parses the creds in format [username[:password] into an auth
+// config.
+func AuthConfig(creds string) (*types.DockerAuthConfig, error) {
 	username, password := parseCreds(creds)
 	if username == "" {
 		fmt.Print("Username: ")
diff --git a/vendor/github.com/containers/common/libimage/filters.go b/vendor/github.com/containers/common/libimage/filters.go
index eae18fd9c7..0cc5cc3119 100644
--- a/vendor/github.com/containers/common/libimage/filters.go
+++ b/vendor/github.com/containers/common/libimage/filters.go
@@ -88,7 +88,7 @@ func (r *Runtime) compileImageFilters(ctx context.Context, filters []string) ([]
 			if err != nil {
 				return nil, errors.Wrapf(err, "non-boolean value %q for dangling filter", value)
 			}
-			filterFuncs = append(filterFuncs, filterDangling(dangling))
+			filterFuncs = append(filterFuncs, filterDangling(ctx, dangling))
 
 		case "id":
 			filterFuncs = append(filterFuncs, filterID(value))
@@ -201,9 +201,13 @@ func filterContainers(value bool) filterFunc {
 }
 
 // filterDangling creates a dangling filter for matching the specified value.
-func filterDangling(value bool) filterFunc {
+func filterDangling(ctx context.Context, value bool) filterFunc {
 	return func(img *Image) (bool, error) {
-		return img.IsDangling() == value, nil
+		isDangling, err := img.IsDangling(ctx)
+		if err != nil {
+			return false, err
+		}
+		return isDangling == value, nil
 	}
 }
 
diff --git a/vendor/github.com/containers/common/libimage/image.go b/vendor/github.com/containers/common/libimage/image.go
index 19b929dc77..5b060a1853 100644
--- a/vendor/github.com/containers/common/libimage/image.go
+++ b/vendor/github.com/containers/common/libimage/image.go
@@ -121,24 +121,29 @@ func (i *Image) IsReadOnly() bool {
 	return i.storageImage.ReadOnly
 }
 
-// IsDangling returns true if the image is dangling.  An image is considered
-// dangling if no names are associated with it in the containers storage.
-func (i *Image) IsDangling() bool {
-	return len(i.Names()) == 0
-}
-
-// IsIntermediate returns true if the image is an intermediate image, that is
-// a dangling image without children.
-func (i *Image) IsIntermediate(ctx context.Context) (bool, error) {
-	// If the image has tags, it's not an intermediate one.
-	if !i.IsDangling() {
+// IsDangling returns true if the image is dangling, that is an untagged image
+// without children.
+func (i *Image) IsDangling(ctx context.Context) (bool, error) {
+	if len(i.Names()) > 0 {
+		return false, nil
+	}
+	children, err := i.getChildren(ctx, false)
+	if err != nil {
+		return false, err
+	}
+	return len(children) == 0, nil
+}
+
+// IsIntermediate returns true if the image is an intermediate image, that is
+// an untagged image with children.
+func (i *Image) IsIntermediate(ctx context.Context) (bool, error) {
+	if len(i.Names()) > 0 {
 		return false, nil
 	}
 	children, err := i.getChildren(ctx, false)
 	if err != nil {
 		return false, err
 	}
-	// No tags, no children -> intermediate!
 	return len(children) != 0, nil
 }
 
@@ -271,7 +276,7 @@ type RemoveImageReport struct {
 
 // remove removes the image along with all dangling parent images that no other
 // image depends on.  The image must not be set read-only and not be used by
-// containers.
+// containers.  Returns IDs of removed/untagged images in order.
 //
 // If the image is used by containers return storage.ErrImageUsedByContainer.
 // Use force to remove these containers.
@@ -282,7 +287,12 @@ type RemoveImageReport struct {
 //
 // This function is internal.  Users of libimage should always use
 // `(*Runtime).RemoveImages()`.
-func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport, referencedBy string, options *RemoveImagesOptions) error {
+func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport, referencedBy string, options *RemoveImagesOptions) ([]string, error) {
+	processedIDs := []string{}
+	return i.removeRecursive(ctx, rmMap, processedIDs, referencedBy, options)
+}
+
+func (i *Image) removeRecursive(ctx context.Context, rmMap map[string]*RemoveImageReport, processedIDs []string, referencedBy string, options *RemoveImagesOptions) ([]string, error) {
 	// If referencedBy is empty, the image is considered to be removed via
 	// `image remove --all` which alters the logic below.
 
@@ -294,7 +304,7 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport,
 	logrus.Debugf("Removing image %s", i.ID())
 
 	if i.IsReadOnly() {
-		return errors.Errorf("cannot remove read-only image %q", i.ID())
+		return processedIDs, errors.Errorf("cannot remove read-only image %q", i.ID())
 	}
 
 	if i.runtime.eventChannel != nil {
@@ -306,7 +316,7 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport,
 	if exists {
 		// If the image has already been removed, we're done.
 		if report.Removed {
-			return nil
+			return processedIDs, nil
 		}
 	} else {
 		report = &RemoveImageReport{ID: i.ID()}
@@ -333,7 +343,7 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport,
 	if options.WithSize {
 		size, err := i.Size()
 		if handleError(err) != nil {
-			return err
+			return processedIDs, err
 		}
 		report.Size = size
 	}
@@ -354,18 +364,18 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport,
 		byDigest := strings.HasPrefix(referencedBy, "sha256:")
 		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())
+				return processedIDs, 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())
+				return processedIDs, 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.
 		if !byID && !byDigest {
 			if err := i.Untag(referencedBy); handleError(err) != nil {
-				return err
+				return processedIDs, err
 			}
 			report.Untagged = append(report.Untagged, referencedBy)
 
@@ -374,14 +384,15 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport,
 		}
 	}
 
+	processedIDs = append(processedIDs, i.ID())
 	if skipRemove {
-		return nil
+		return processedIDs, nil
 	}
 
 	// Perform the actual removal. First, remove containers if needed.
 	if options.Force {
 		if err := i.removeContainers(options.RemoveContainerFunc); err != nil {
-			return err
+			return processedIDs, err
 		}
 	}
 
@@ -407,7 +418,7 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport,
 	}
 
 	if _, err := i.runtime.store.DeleteImage(i.ID(), true); handleError(err) != nil {
-		return err
+		return processedIDs, err
 	}
 	report.Untagged = append(report.Untagged, i.Names()...)
 
@@ -417,27 +428,24 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport,
 
 	// Check if can remove the parent image.
 	if parent == nil {
-		return nil
+		return processedIDs, nil
 	}
 
-	if !parent.IsDangling() {
-		return nil
-	}
-
-	// If the image has siblings, we don't remove the parent.
-	hasSiblings, err := parent.HasChildren(ctx)
+	// Only remove the parent if it's dangling, that is being untagged and
+	// without children.
+	danglingParent, err := parent.IsDangling(ctx)
 	if err != nil {
 		// See Podman commit fd9dd7065d44: we need to
 		// be tolerant toward corrupted images.
 		logrus.Warnf("error determining if an image is a parent: %v, ignoring the error", err)
-		hasSiblings = false
+		danglingParent = false
 	}
-	if hasSiblings {
-		return nil
+	if !danglingParent {
+		return processedIDs, nil
 	}
 
 	// Recurse into removing the parent.
-	return parent.remove(ctx, rmMap, "", options)
+	return parent.removeRecursive(ctx, rmMap, processedIDs, "", options)
 }
 
 // Tag the image with the specified name and store it in the local containers
diff --git a/vendor/github.com/containers/common/libimage/layer_tree.go b/vendor/github.com/containers/common/libimage/layer_tree.go
index 4195b43c0e..05f21531b0 100644
--- a/vendor/github.com/containers/common/libimage/layer_tree.go
+++ b/vendor/github.com/containers/common/libimage/layer_tree.go
@@ -15,6 +15,9 @@ type layerTree struct {
 	// ociCache is a cache for Image.ID -> OCI Image. Translations are done
 	// on-demand.
 	ociCache map[string]*ociv1.Image
+	// emptyImages do not have any top-layer so we cannot create a
+	// *layerNode for them.
+	emptyImages []*Image
 }
 
 // node returns a layerNode for the specified layerID.
@@ -105,6 +108,7 @@ func (r *Runtime) layerTree() (*layerTree, error) {
 		img := images[i] // do not leak loop variable outside the scope
 		topLayer := img.TopLayer()
 		if topLayer == "" {
+			tree.emptyImages = append(tree.emptyImages, img)
 			continue
 		}
 		node, exists := tree.nodes[topLayer]
@@ -126,22 +130,13 @@ func (r *Runtime) layerTree() (*layerTree, error) {
 // either the same top layer as parent or parent being the true parent layer.
 // Furthermore, the history of the parent and child images must match with the
 // parent having one history item less.  If all is true, all images are
-// returned.  Otherwise, the first image is returned.
+// returned.  Otherwise, the first image is returned.  Note that manifest lists
+// do not have children.
 func (t *layerTree) children(ctx context.Context, parent *Image, all bool) ([]*Image, error) {
 	if parent.TopLayer() == "" {
-		return nil, nil
-	}
-
-	var children []*Image
-
-	parentNode, exists := t.nodes[parent.TopLayer()]
-	if !exists {
-		// Note: erroring out in this case has turned out having been a
-		// mistake. Users may not be able to recover, so we're now
-		// throwing a warning to guide them to resolve the issue and
-		// turn the errors non-fatal.
-		logrus.Warnf("Layer %s not found in layer tree. The storage may be corrupted, consider running `podman system reset`.", parent.TopLayer())
-		return children, nil
+		if isManifestList, _ := parent.IsManifestList(ctx); isManifestList {
+			return nil, nil
+		}
 	}
 
 	parentID := parent.ID()
@@ -163,6 +158,38 @@ func (t *layerTree) children(ctx context.Context, parent *Image, all bool) ([]*I
 		return areParentAndChild(parentOCI, childOCI), nil
 	}
 
+	var children []*Image
+
+	// Empty images are special in that they do not have any physical layer
+	// but yet can have a parent-child relation.  Hence, compare the
+	// "parent" image to all other known empty images.
+	if parent.TopLayer() == "" {
+		for i := range t.emptyImages {
+			empty := t.emptyImages[i]
+			isParent, err := checkParent(empty)
+			if err != nil {
+				return nil, err
+			}
+			if isParent {
+				children = append(children, empty)
+				if !all {
+					break
+				}
+			}
+		}
+		return children, nil
+	}
+
+	parentNode, exists := t.nodes[parent.TopLayer()]
+	if !exists {
+		// Note: erroring out in this case has turned out having been a
+		// mistake. Users may not be able to recover, so we're now
+		// throwing a warning to guide them to resolve the issue and
+		// turn the errors non-fatal.
+		logrus.Warnf("Layer %s not found in layer tree. The storage may be corrupted, consider running `podman system reset`.", parent.TopLayer())
+		return children, nil
+	}
+
 	// addChildrenFrom adds child images of parent to children.  Returns
 	// true if any image is a child of parent.
 	addChildrenFromNode := func(node *layerNode) (bool, error) {
@@ -204,8 +231,37 @@ func (t *layerTree) children(ctx context.Context, parent *Image, all bool) ([]*I
 }
 
 // parent returns the parent image or nil if no parent image could be found.
+// Note that manifest lists do not have parents.
 func (t *layerTree) parent(ctx context.Context, child *Image) (*Image, error) {
 	if child.TopLayer() == "" {
+		if isManifestList, _ := child.IsManifestList(ctx); isManifestList {
+			return nil, nil
+		}
+	}
+
+	childID := child.ID()
+	childOCI, err := t.toOCI(ctx, child)
+	if err != nil {
+		return nil, err
+	}
+
+	// Empty images are special in that they do not have any physical layer
+	// but yet can have a parent-child relation.  Hence, compare the
+	// "child" image to all other known empty images.
+	if child.TopLayer() == "" {
+		for _, empty := range t.emptyImages {
+			if childID == empty.ID() {
+				continue
+			}
+			emptyOCI, err := t.toOCI(ctx, empty)
+			if err != nil {
+				return nil, err
+			}
+			// History check.
+			if areParentAndChild(emptyOCI, childOCI) {
+				return empty, nil
+			}
+		}
 		return nil, nil
 	}
 
@@ -219,14 +275,8 @@ func (t *layerTree) parent(ctx context.Context, child *Image) (*Image, error) {
 		return nil, nil
 	}
 
-	childOCI, err := t.toOCI(ctx, child)
-	if err != nil {
-		return nil, err
-	}
-
 	// Check images from the parent node (i.e., parent layer) and images
 	// with the same layer (i.e., same top layer).
-	childID := child.ID()
 	images := node.images
 	if node.parent != nil {
 		images = append(images, node.parent.images...)
diff --git a/vendor/github.com/containers/common/libimage/pull.go b/vendor/github.com/containers/common/libimage/pull.go
index 71cec021bc..1a6ad1ce2d 100644
--- a/vendor/github.com/containers/common/libimage/pull.go
+++ b/vendor/github.com/containers/common/libimage/pull.go
@@ -10,6 +10,7 @@ import (
 	"github.com/containers/common/pkg/config"
 	registryTransport "github.com/containers/image/v5/docker"
 	dockerArchiveTransport "github.com/containers/image/v5/docker/archive"
+	dockerDaemonTransport "github.com/containers/image/v5/docker/daemon"
 	"github.com/containers/image/v5/docker/reference"
 	ociArchiveTransport "github.com/containers/image/v5/oci/archive"
 	ociTransport "github.com/containers/image/v5/oci/layout"
@@ -55,6 +56,13 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP
 	var possiblyUnqualifiedName string // used for short-name resolution
 	ref, err := alltransports.ParseImageName(name)
 	if err != nil {
+		// Check whether `name` points to a transport.  If so, we
+		// return the error.  Otherwise we assume that `name` refers to
+		// an image on a registry (e.g., "fedora").
+		if alltransports.TransportFromImageName(name) != nil {
+			return nil, err
+		}
+
 		// If the image clearly refers to a local one, we can look it up directly.
 		// In fact, we need to since they are not parseable.
 		if strings.HasPrefix(name, "sha256:") || (len(name) == 64 && !strings.ContainsAny(name, "/.:@")) {
@@ -169,6 +177,15 @@ func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference,
 	var storageName, imageName string
 	switch ref.Transport().Name() {
 
+	case dockerDaemonTransport.Transport.Name():
+		// Normalize to docker.io if needed (see containers/podman/issues/10998).
+		named, err := reference.ParseNormalizedNamed(ref.StringWithinTransport())
+		if err != nil {
+			return nil, err
+		}
+		imageName = named.String()
+		storageName = imageName
+
 	case ociTransport.Transport.Name():
 		split := strings.SplitN(ref.StringWithinTransport(), ":", 2)
 		storageName = toLocalImageName(split[0])
diff --git a/vendor/github.com/containers/common/libimage/runtime.go b/vendor/github.com/containers/common/libimage/runtime.go
index 1fd2973cbc..26a04dad58 100644
--- a/vendor/github.com/containers/common/libimage/runtime.go
+++ b/vendor/github.com/containers/common/libimage/runtime.go
@@ -3,7 +3,6 @@ package libimage
 import (
 	"context"
 	"os"
-	"path/filepath"
 	"strings"
 
 	"github.com/containers/image/v5/docker/reference"
@@ -94,10 +93,6 @@ func RuntimeFromStore(store storage.Store, options *RuntimeOptions) (*Runtime, e
 
 	setRegistriesConfPath(&systemContext)
 
-	if systemContext.BlobInfoCacheDir == "" {
-		systemContext.BlobInfoCacheDir = filepath.Join(store.GraphRoot(), "cache")
-	}
-
 	return &Runtime{
 		store:         store,
 		systemContext: systemContext,
@@ -592,11 +587,10 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem
 		rmErrors = append(rmErrors, err)
 	}
 
-	orderedIDs := []string{}                // determinism and relative order
 	deleteMap := make(map[string]*deleteMe) // ID -> deleteMe
-
+	toDelete := []string{}
 	// Look up images in the local containers storage and fill out
-	// orderedIDs and the deleteMap.
+	// toDelete and the deleteMap.
 	switch {
 	case len(names) > 0:
 		// Look up the images one-by-one.  That allows for removing
@@ -610,15 +604,12 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem
 			}
 			dm, exists := deleteMap[img.ID()]
 			if !exists {
-				orderedIDs = append(orderedIDs, img.ID())
+				toDelete = append(toDelete, img.ID())
 				dm = &deleteMe{image: img}
 				deleteMap[img.ID()] = dm
 			}
 			dm.referencedBy = append(dm.referencedBy, resolvedName)
 		}
-		if len(orderedIDs) == 0 {
-			return nil, rmErrors
-		}
 
 	default:
 		filteredImages, err := r.ListImages(ctx, nil, &ListImagesOptions{Filters: options.Filters})
@@ -627,14 +618,21 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem
 			return nil, rmErrors
 		}
 		for _, img := range filteredImages {
-			orderedIDs = append(orderedIDs, img.ID())
+			toDelete = append(toDelete, img.ID())
 			deleteMap[img.ID()] = &deleteMe{image: img}
 		}
 	}
 
+	// Return early if there's no image to delete.
+	if len(deleteMap) == 0 {
+		return nil, rmErrors
+	}
+
 	// Now remove the images in the given order.
 	rmMap := make(map[string]*RemoveImageReport)
-	for _, id := range orderedIDs {
+	orderedIDs := []string{}
+	visitedIDs := make(map[string]bool)
+	for _, id := range toDelete {
 		del, exists := deleteMap[id]
 		if !exists {
 			appendError(errors.Errorf("internal error: ID %s not in found in image-deletion map", id))
@@ -644,9 +642,17 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem
 			del.referencedBy = []string{""}
 		}
 		for _, ref := range del.referencedBy {
-			if err := del.image.remove(ctx, rmMap, ref, options); err != nil {
+			processedIDs, err := del.image.remove(ctx, rmMap, ref, options)
+			if err != nil {
 				appendError(err)
-				continue
+			}
+			// NOTE: make sure to add given ID only once to orderedIDs.
+			for _, id := range processedIDs {
+				if visited := visitedIDs[id]; visited {
+					continue
+				}
+				orderedIDs = append(orderedIDs, id)
+				visitedIDs[id] = true
 			}
 		}
 	}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 337d854420..4ded74e369 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -77,7 +77,7 @@ github.com/containernetworking/plugins/pkg/utils/hwaddr
 github.com/containernetworking/plugins/pkg/utils/sysctl
 github.com/containernetworking/plugins/plugins/ipam/host-local/backend
 github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator
-# github.com/containers/buildah v1.21.1-0.20210707133512-2eb97b499d74
+# github.com/containers/buildah v1.21.1-0.20210721171232-54cafea4c933
 github.com/containers/buildah
 github.com/containers/buildah/bind
 github.com/containers/buildah/chroot
@@ -93,7 +93,7 @@ github.com/containers/buildah/pkg/overlay
 github.com/containers/buildah/pkg/parse
 github.com/containers/buildah/pkg/rusage
 github.com/containers/buildah/util
-# github.com/containers/common v0.41.1-0.20210716140645-ffcfe1ff6e70
+# github.com/containers/common v0.41.1-0.20210721172332-291287e9d060
 github.com/containers/common/libimage
 github.com/containers/common/libimage/manifests
 github.com/containers/common/pkg/apparmor