From 48e7f7963e142a0a45b583c5e65015d896c59433 Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Wed, 28 Oct 2015 16:07:02 -0700 Subject: [PATCH] Fix rmi -f removing multiple tags When an image has multiple tags and rmi is called with force on a tag, only the single tag should be removed. The current behavior is broken and removes all tags and the image. Signed-off-by: Derek McGowan (github: dmcgowan) --- daemon/image_delete.go | 5 +++++ integration-cli/docker_cli_rmi_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/daemon/image_delete.go b/daemon/image_delete.go index b28072103a..3bcf023b42 100644 --- a/daemon/image_delete.go +++ b/daemon/image_delete.go @@ -84,6 +84,11 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I daemon.EventsService.Log("untag", img.ID, "") records = append(records, untaggedRecord) + // If has remaining references then untag finishes the remove + if daemon.repositories.HasReferences(img) { + return records, nil + } + removedRepositoryRef = true } else { // If an ID reference was given AND there is exactly one diff --git a/integration-cli/docker_cli_rmi_test.go b/integration-cli/docker_cli_rmi_test.go index 19914315ee..32472ea723 100644 --- a/integration-cli/docker_cli_rmi_test.go +++ b/integration-cli/docker_cli_rmi_test.go @@ -193,6 +193,31 @@ func (s *DockerSuite) TestRmiWithMultipleRepositories(c *check.C) { c.Assert(out, checker.Contains, "Untagged: "+newTag) } +func (s *DockerSuite) TestRmiForceWithMultipleRepositories(c *check.C) { + testRequires(c, DaemonIsLinux) + imageName := "rmiimage" + tag1 := imageName + ":tag1" + tag2 := imageName + ":tag2" + + _, err := buildImage(tag1, + `FROM scratch + MAINTAINER "docker"`, + true) + if err != nil { + c.Fatal(err) + } + + dockerCmd(c, "tag", tag1, tag2) + + out, _ := dockerCmd(c, "rmi", "-f", tag2) + c.Assert(out, checker.Contains, "Untagged: "+tag2) + c.Assert(out, checker.Not(checker.Contains), "Untagged: "+tag1) + + // Check built image still exists + images, _ := dockerCmd(c, "images", "-a") + c.Assert(images, checker.Contains, imageName, check.Commentf("Built image missing %q; Images: %q", imageName, images)) +} + func (s *DockerSuite) TestRmiBlank(c *check.C) { testRequires(c, DaemonIsLinux) // try to delete a blank image name