Browse code

fix bug with rmi multiple tag

Signed-off-by: Jessica Frazelle <princess@docker.com>

Jessica Frazelle authored on 2015/05/30 03:12:58
Showing 2 changed files
... ...
@@ -63,7 +63,8 @@ func (daemon *Daemon) imgDeleteHelper(name string, list *[]types.ImageDelete, fi
63 63
 	repos := daemon.Repositories().ByID()[img.ID]
64 64
 
65 65
 	//If delete by id, see if the id belong only to one repository
66
-	if repoName == "" {
66
+	deleteByID := repoName == ""
67
+	if deleteByID {
67 68
 		for _, repoAndTag := range repos {
68 69
 			parsedRepo, parsedTag := parsers.ParseRepositoryTag(repoAndTag)
69 70
 			if repoName == "" || repoName == parsedRepo {
... ...
@@ -91,7 +92,7 @@ func (daemon *Daemon) imgDeleteHelper(name string, list *[]types.ImageDelete, fi
91 91
 		return nil
92 92
 	}
93 93
 
94
-	if len(repos) <= 1 {
94
+	if len(repos) <= 1 || (len(repoAndTags) <= 1 && deleteByID) {
95 95
 		if err := daemon.canDeleteImage(img.ID, force); err != nil {
96 96
 			return err
97 97
 		}
... ...
@@ -74,6 +74,55 @@ func (s *DockerSuite) TestRmiTag(c *check.C) {
74 74
 	}
75 75
 }
76 76
 
77
+func (s *DockerSuite) TestRmiImgIDMultipleTag(c *check.C) {
78
+	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir '/busybox-one'")
79
+	out, _, err := runCommandWithOutput(runCmd)
80
+	if err != nil {
81
+		c.Fatalf("failed to create a container:%s, %v", out, err)
82
+	}
83
+	containerID := strings.TrimSpace(out)
84
+	runCmd = exec.Command(dockerBinary, "commit", containerID, "busybox-one")
85
+	out, _, err = runCommandWithOutput(runCmd)
86
+	if err != nil {
87
+		c.Fatalf("failed to commit a new busybox-one:%s, %v", out, err)
88
+	}
89
+
90
+	imagesBefore, _ := dockerCmd(c, "images", "-a")
91
+	dockerCmd(c, "tag", "busybox-one", "busybox-one:tag1")
92
+	dockerCmd(c, "tag", "busybox-one", "busybox-one:tag2")
93
+
94
+	imagesAfter, _ := dockerCmd(c, "images", "-a")
95
+	if strings.Count(imagesAfter, "\n") != strings.Count(imagesBefore, "\n")+2 {
96
+		c.Fatalf("tag busybox to create 2 more images with same imageID; docker images shows: %q\n", imagesAfter)
97
+	}
98
+
99
+	imgID, err := inspectField("busybox-one:tag1", "Id")
100
+	c.Assert(err, check.IsNil)
101
+
102
+	// run a container with the image
103
+	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "busybox-one", "top"))
104
+	if err != nil {
105
+		c.Fatalf("failed to create a container:%s, %v", out, err)
106
+	}
107
+	containerID = strings.TrimSpace(out)
108
+
109
+	// first checkout without force it fails
110
+	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "rmi", imgID))
111
+	expected := fmt.Sprintf("Conflict, cannot delete %s because the running container %s is using it, stop it and use -f to force", imgID[:12], containerID[:12])
112
+	if err == nil || !strings.Contains(out, expected) {
113
+		c.Fatalf("rmi tagged in multiple repos should have failed without force: %s, %v, expected: %s", out, err, expected)
114
+	}
115
+
116
+	dockerCmd(c, "stop", containerID)
117
+	dockerCmd(c, "rmi", "-f", imgID)
118
+
119
+	imagesAfter, _ = dockerCmd(c, "images", "-a")
120
+	if strings.Contains(imagesAfter, imgID[:12]) {
121
+		c.Fatalf("rmi -f %s failed, image still exists: %q\n\n", imgID, imagesAfter)
122
+	}
123
+
124
+}
125
+
77 126
 func (s *DockerSuite) TestRmiImgIDForce(c *check.C) {
78 127
 	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir '/busybox-test'")
79 128
 	out, _, err := runCommandWithOutput(runCmd)
... ...
@@ -119,7 +168,6 @@ func (s *DockerSuite) TestRmiImgIDForce(c *check.C) {
119 119
 }
120 120
 
121 121
 func (s *DockerSuite) TestRmiTagWithExistingContainers(c *check.C) {
122
-
123 122
 	container := "test-delete-tag"
124 123
 	newtag := "busybox:newtag"
125 124
 	bb := "busybox:latest"