Procházet zdrojové kódy

Fix docker rmi trying to remove a being used parent

Signed-off-by: Lei Jitang <leijitang@huawei.com>
Lei Jitang před 9 roky
rodič
revize
0bbc9f1d2d

+ 5 - 2
daemon/image_delete.go

@@ -195,6 +195,7 @@ func (daemon *Daemon) removeAllReferencesToImageID(imgID image.ID, records *[]ty
 // Implements the error interface.
 type imageDeleteConflict struct {
 	hard    bool
+	used    bool
 	imgID   image.ID
 	message string
 }
@@ -225,8 +226,8 @@ func (daemon *Daemon) imageDeleteHelper(imgID image.ID, records *[]types.ImageDe
 	// First, determine if this image has any conflicts. Ignore soft conflicts
 	// if force is true.
 	if conflict := daemon.checkImageDeleteConflict(imgID, force); conflict != nil {
-		if quiet && !daemon.imageIsDangling(imgID) {
-			// Ignore conflicts UNLESS the image is "dangling" in
+		if quiet && (!daemon.imageIsDangling(imgID) || conflict.used) {
+			// Ignore conflicts UNLESS the image is "dangling" or not being used in
 			// which case we want the user to know.
 			return nil
 		}
@@ -312,6 +313,7 @@ func (daemon *Daemon) checkImageDeleteHardConflict(imgID image.ID) *imageDeleteC
 			return &imageDeleteConflict{
 				imgID:   imgID,
 				hard:    true,
+				used:    true,
 				message: fmt.Sprintf("image is being used by running container %s", stringid.TruncateID(container.ID)),
 			}
 		}
@@ -339,6 +341,7 @@ func (daemon *Daemon) checkImageDeleteSoftConflict(imgID image.ID) *imageDeleteC
 		if container.ImageID == imgID {
 			return &imageDeleteConflict{
 				imgID:   imgID,
+				used:    true,
 				message: fmt.Sprintf("image is being used by stopped container %s", stringid.TruncateID(container.ID)),
 			}
 		}

+ 2 - 2
integration-cli/docker_cli_rm_test.go

@@ -60,9 +60,9 @@ func (s *DockerSuite) TestRmContainerOrphaning(c *check.C) {
 	// rebuild dockerfile with a small addition at the end
 	_, err = buildImage(img, dockerfile2, true)
 	c.Assert(err, check.IsNil, check.Commentf("Could not rebuild image %s", img))
-	// try to remove the image, should error out.
+	// try to remove the image, should not error out.
 	out, _, err := dockerCmdWithError("rmi", img)
-	c.Assert(err, check.NotNil, check.Commentf("Expected to error out removing the image, but succeeded: %s", out))
+	c.Assert(err, check.IsNil, check.Commentf("Expected to removing the image, but failed: %s", out))
 
 	// check if we deleted the first image
 	out, _ = dockerCmd(c, "images", "-q", "--no-trunc")

+ 15 - 0
integration-cli/docker_cli_rmi_test.go

@@ -322,3 +322,18 @@ func (*DockerSuite) TestRmiParentImageFail(c *check.C) {
 		c.Fatalf("rmi should have failed because it's a parent image, got %s", out)
 	}
 }
+
+func (s *DockerSuite) TestRmiWithParentInUse(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+	out, _ := dockerCmd(c, "create", "busybox")
+	cID := strings.TrimSpace(out)
+	out, _ = dockerCmd(c, "commit", cID)
+	imageID := strings.TrimSpace(out)
+
+	out, _ = dockerCmd(c, "create", imageID)
+	cID = strings.TrimSpace(out)
+	out, _ = dockerCmd(c, "commit", cID)
+	imageID = strings.TrimSpace(out)
+
+	dockerCmd(c, "rmi", imageID)
+}