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 {