Browse code

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 <derek@mcgstyle.net> (github: dmcgowan)

Derek McGowan authored on 2015/10/29 08:07:02
Showing 2 changed files
... ...
@@ -84,6 +84,11 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I
84 84
 		daemon.EventsService.Log("untag", img.ID, "")
85 85
 		records = append(records, untaggedRecord)
86 86
 
87
+		// If has remaining references then untag finishes the remove
88
+		if daemon.repositories.HasReferences(img) {
89
+			return records, nil
90
+		}
91
+
87 92
 		removedRepositoryRef = true
88 93
 	} else {
89 94
 		// If an ID reference was given AND there is exactly one
... ...
@@ -193,6 +193,31 @@ func (s *DockerSuite) TestRmiWithMultipleRepositories(c *check.C) {
193 193
 	c.Assert(out, checker.Contains, "Untagged: "+newTag)
194 194
 }
195 195
 
196
+func (s *DockerSuite) TestRmiForceWithMultipleRepositories(c *check.C) {
197
+	testRequires(c, DaemonIsLinux)
198
+	imageName := "rmiimage"
199
+	tag1 := imageName + ":tag1"
200
+	tag2 := imageName + ":tag2"
201
+
202
+	_, err := buildImage(tag1,
203
+		`FROM scratch
204
+		MAINTAINER "docker"`,
205
+		true)
206
+	if err != nil {
207
+		c.Fatal(err)
208
+	}
209
+
210
+	dockerCmd(c, "tag", tag1, tag2)
211
+
212
+	out, _ := dockerCmd(c, "rmi", "-f", tag2)
213
+	c.Assert(out, checker.Contains, "Untagged: "+tag2)
214
+	c.Assert(out, checker.Not(checker.Contains), "Untagged: "+tag1)
215
+
216
+	// Check built image still exists
217
+	images, _ := dockerCmd(c, "images", "-a")
218
+	c.Assert(images, checker.Contains, imageName, check.Commentf("Built image missing %q; Images: %q", imageName, images))
219
+}
220
+
196 221
 func (s *DockerSuite) TestRmiBlank(c *check.C) {
197 222
 	testRequires(c, DaemonIsLinux)
198 223
 	// try to delete a blank image name