From edd8d2d3511b0b632149d1c1f2cfd2bad2df4679 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Fri, 14 Mar 2014 01:02:28 +0000 Subject: [PATCH 1/4] add no prune to rmi Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- api/client.go | 8 ++++++-- api/server.go | 1 + server/server.go | 8 ++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/api/client.go b/api/client.go index 8ee61f6c22..1aceed50e7 100644 --- a/api/client.go +++ b/api/client.go @@ -817,8 +817,9 @@ func (cli *DockerCli) CmdPort(args ...string) error { // 'docker rmi IMAGE' removes all images with the name IMAGE func (cli *DockerCli) CmdRmi(args ...string) error { var ( - cmd = cli.Subcmd("rmi", "IMAGE [IMAGE...]", "Remove one or more images") - force = cmd.Bool([]string{"f", "-force"}, false, "Force") + cmd = cli.Subcmd("rmi", "IMAGE [IMAGE...]", "Remove one or more images") + force = cmd.Bool([]string{"f", "-force"}, false, "Force") + noprune = cmd.Bool([]string{"-no-prune"}, false, "Do not delete untagged parents") ) if err := cmd.Parse(args); err != nil { return nil @@ -832,6 +833,9 @@ func (cli *DockerCli) CmdRmi(args ...string) error { if *force { v.Set("force", "1") } + if *noprune { + v.Set("noprune", "1") + } var encounteredError error for _, name := range cmd.Args() { diff --git a/api/server.go b/api/server.go index 2d878b957a..774e3131ef 100644 --- a/api/server.go +++ b/api/server.go @@ -624,6 +624,7 @@ func deleteImages(eng *engine.Engine, version version.Version, w http.ResponseWr var job = eng.Job("image_delete", vars["name"]) streamJSON(job, w, false) job.Setenv("force", r.Form.Get("force")) + job.Setenv("noprune", r.Form.Get("noprune")) return job.Run() } diff --git a/server/server.go b/server/server.go index eb9a3a396b..736d54ae52 100644 --- a/server/server.go +++ b/server/server.go @@ -1839,7 +1839,7 @@ func (srv *Server) ContainerDestroy(job *engine.Job) engine.Status { return engine.StatusOK } -func (srv *Server) DeleteImage(name string, imgs *engine.Table, first, force bool) error { +func (srv *Server) DeleteImage(name string, imgs *engine.Table, first, force, noprune bool) error { var ( repoName, tag string tags = []string{} @@ -1920,8 +1920,8 @@ func (srv *Server) DeleteImage(name string, imgs *engine.Table, first, force boo out.Set("Deleted", img.ID) imgs.Add(out) srv.LogEvent("delete", img.ID, "") - if img.Parent != "" { - err := srv.DeleteImage(img.Parent, imgs, false, force) + if img.Parent != "" && !noprune { + err := srv.DeleteImage(img.Parent, imgs, false, force, noprune) if first { return err } @@ -1938,7 +1938,7 @@ func (srv *Server) ImageDelete(job *engine.Job) engine.Status { return job.Errorf("Usage: %s IMAGE", job.Name) } imgs := engine.NewTable("", 0) - if err := srv.DeleteImage(job.Args[0], imgs, true, job.GetenvBool("force")); err != nil { + if err := srv.DeleteImage(job.Args[0], imgs, true, job.GetenvBool("force"), job.GetenvBool("noprune")); err != nil { return job.Error(err) } if len(imgs.Data) == 0 { From afcaaffd0bb84d0c97f4a3ef54f4d35ba3942f65 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Fri, 14 Mar 2014 01:04:35 +0000 Subject: [PATCH 2/4] update doc Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- docs/sources/reference/api/docker_remote_api.rst | 1 + docs/sources/reference/api/docker_remote_api_v1.10.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/sources/reference/api/docker_remote_api.rst b/docs/sources/reference/api/docker_remote_api.rst index 93558fa974..ca7463f351 100644 --- a/docs/sources/reference/api/docker_remote_api.rst +++ b/docs/sources/reference/api/docker_remote_api.rst @@ -50,6 +50,7 @@ What's new **New!** You can now use the force parameter to force delete of an image, even if it's tagged in multiple repositories. + **New!** You can now use the noprune parameter to prevent the deletion of parent images .. http:delete:: /containers/(id) diff --git a/docs/sources/reference/api/docker_remote_api_v1.10.rst b/docs/sources/reference/api/docker_remote_api_v1.10.rst index 20af253f0e..649f58196e 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.10.rst +++ b/docs/sources/reference/api/docker_remote_api_v1.10.rst @@ -931,6 +931,7 @@ Remove an image ] :query force: 1/True/true or 0/False/false, default false + :query noprune: 1/True/true or 0/False/false, default false :statuscode 200: no error :statuscode 404: no such image :statuscode 409: conflict From a18d08177c1b11fd1e88c27d78a7256b5d498d64 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Fri, 14 Mar 2014 17:13:11 +0000 Subject: [PATCH 3/4] Add missing client doc Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- docs/sources/reference/commandline/cli.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/sources/reference/commandline/cli.rst b/docs/sources/reference/commandline/cli.rst index 6d55a0aedc..f302862b9e 100644 --- a/docs/sources/reference/commandline/cli.rst +++ b/docs/sources/reference/commandline/cli.rst @@ -1092,6 +1092,7 @@ containers will not be deleted. Remove one or more images -f, --force=false: Force + --no-prune=false: Do not delete untagged parents Removing tagged images ~~~~~~~~~~~~~~~~~~~~~~ From 326f6a4b4d942bf75ecb003e5c0d439bcb9d67cf Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Mon, 17 Mar 2014 19:17:40 +0000 Subject: [PATCH 4/4] fix tests Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- integration/commands_test.go | 2 +- integration/server_test.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/integration/commands_test.go b/integration/commands_test.go index dba15842c7..5804d9f351 100644 --- a/integration/commands_test.go +++ b/integration/commands_test.go @@ -1062,7 +1062,7 @@ func TestContainerOrphaning(t *testing.T) { // remove the second image by name resp := engine.NewTable("", 0) - if err := srv.DeleteImage(imageName, resp, true, false); err == nil { + if err := srv.DeleteImage(imageName, resp, true, false, false); err == nil { t.Fatal("Expected error, got none") } diff --git a/integration/server_test.go b/integration/server_test.go index 2455c766e3..a401f1306e 100644 --- a/integration/server_test.go +++ b/integration/server_test.go @@ -36,7 +36,7 @@ func TestImageTagImageDelete(t *testing.T) { t.Errorf("Expected %d images, %d found", nExpected, nActual) } - if err := srv.DeleteImage("utest/docker:tag2", engine.NewTable("", 0), true, false); err != nil { + if err := srv.DeleteImage("utest/docker:tag2", engine.NewTable("", 0), true, false, false); err != nil { t.Fatal(err) } @@ -48,7 +48,7 @@ func TestImageTagImageDelete(t *testing.T) { t.Errorf("Expected %d images, %d found", nExpected, nActual) } - if err := srv.DeleteImage("utest:5000/docker:tag3", engine.NewTable("", 0), true, false); err != nil { + if err := srv.DeleteImage("utest:5000/docker:tag3", engine.NewTable("", 0), true, false, false); err != nil { t.Fatal(err) } @@ -57,7 +57,7 @@ func TestImageTagImageDelete(t *testing.T) { nExpected = len(initialImages.Data[0].GetList("RepoTags")) + 1 nActual = len(images.Data[0].GetList("RepoTags")) - if err := srv.DeleteImage("utest:tag1", engine.NewTable("", 0), true, false); err != nil { + if err := srv.DeleteImage("utest:tag1", engine.NewTable("", 0), true, false, false); err != nil { t.Fatal(err) } @@ -579,7 +579,7 @@ func TestRmi(t *testing.T) { t.Fatalf("Expected 2 new images, found %d.", images.Len()-initialImages.Len()) } - if err = srv.DeleteImage(imageID, engine.NewTable("", 0), true, false); err != nil { + if err = srv.DeleteImage(imageID, engine.NewTable("", 0), true, false, false); err != nil { t.Fatal(err) } @@ -815,7 +815,7 @@ func TestDeleteTagWithExistingContainers(t *testing.T) { // Try to remove the tag imgs := engine.NewTable("", 0) - if err := srv.DeleteImage("utest:tag1", imgs, true, false); err != nil { + if err := srv.DeleteImage("utest:tag1", imgs, true, false, false); err != nil { t.Fatal(err) }