mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
commit
68dc189680
8 changed files with 20 additions and 12 deletions
|
@ -819,6 +819,7 @@ func (cli *DockerCli) CmdRmi(args ...string) error {
|
||||||
var (
|
var (
|
||||||
cmd = cli.Subcmd("rmi", "IMAGE [IMAGE...]", "Remove one or more images")
|
cmd = cli.Subcmd("rmi", "IMAGE [IMAGE...]", "Remove one or more images")
|
||||||
force = cmd.Bool([]string{"f", "-force"}, false, "Force")
|
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 {
|
if err := cmd.Parse(args); err != nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -832,6 +833,9 @@ func (cli *DockerCli) CmdRmi(args ...string) error {
|
||||||
if *force {
|
if *force {
|
||||||
v.Set("force", "1")
|
v.Set("force", "1")
|
||||||
}
|
}
|
||||||
|
if *noprune {
|
||||||
|
v.Set("noprune", "1")
|
||||||
|
}
|
||||||
|
|
||||||
var encounteredError error
|
var encounteredError error
|
||||||
for _, name := range cmd.Args() {
|
for _, name := range cmd.Args() {
|
||||||
|
|
|
@ -623,6 +623,7 @@ func deleteImages(eng *engine.Engine, version version.Version, w http.ResponseWr
|
||||||
var job = eng.Job("image_delete", vars["name"])
|
var job = eng.Job("image_delete", vars["name"])
|
||||||
streamJSON(job, w, false)
|
streamJSON(job, w, false)
|
||||||
job.Setenv("force", r.Form.Get("force"))
|
job.Setenv("force", r.Form.Get("force"))
|
||||||
|
job.Setenv("noprune", r.Form.Get("noprune"))
|
||||||
|
|
||||||
return job.Run()
|
return job.Run()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
**New!** You can now use the force parameter to force delete of an image, even if it's
|
||||||
tagged in multiple repositories.
|
tagged in multiple repositories.
|
||||||
|
**New!** You can now use the noprune parameter to prevent the deletion of parent images
|
||||||
|
|
||||||
.. http:delete:: /containers/(id)
|
.. http:delete:: /containers/(id)
|
||||||
|
|
||||||
|
|
|
@ -931,6 +931,7 @@ Remove an image
|
||||||
]
|
]
|
||||||
|
|
||||||
:query force: 1/True/true or 0/False/false, default false
|
: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 200: no error
|
||||||
:statuscode 404: no such image
|
:statuscode 404: no such image
|
||||||
:statuscode 409: conflict
|
:statuscode 409: conflict
|
||||||
|
|
|
@ -1092,6 +1092,7 @@ containers will not be deleted.
|
||||||
Remove one or more images
|
Remove one or more images
|
||||||
|
|
||||||
-f, --force=false: Force
|
-f, --force=false: Force
|
||||||
|
--no-prune=false: Do not delete untagged parents
|
||||||
|
|
||||||
Removing tagged images
|
Removing tagged images
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -1062,7 +1062,7 @@ func TestContainerOrphaning(t *testing.T) {
|
||||||
|
|
||||||
// remove the second image by name
|
// remove the second image by name
|
||||||
resp := engine.NewTable("", 0)
|
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")
|
t.Fatal("Expected error, got none")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ func TestImageTagImageDelete(t *testing.T) {
|
||||||
t.Errorf("Expected %d images, %d found", nExpected, nActual)
|
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)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ func TestImageTagImageDelete(t *testing.T) {
|
||||||
t.Errorf("Expected %d images, %d found", nExpected, nActual)
|
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)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ func TestImageTagImageDelete(t *testing.T) {
|
||||||
nExpected = len(initialImages.Data[0].GetList("RepoTags")) + 1
|
nExpected = len(initialImages.Data[0].GetList("RepoTags")) + 1
|
||||||
nActual = len(images.Data[0].GetList("RepoTags"))
|
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)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,7 +579,7 @@ func TestRmi(t *testing.T) {
|
||||||
t.Fatalf("Expected 2 new images, found %d.", images.Len()-initialImages.Len())
|
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)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,7 +815,7 @@ func TestDeleteTagWithExistingContainers(t *testing.T) {
|
||||||
|
|
||||||
// Try to remove the tag
|
// Try to remove the tag
|
||||||
imgs := engine.NewTable("", 0)
|
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)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1839,7 +1839,7 @@ func (srv *Server) ContainerDestroy(job *engine.Job) engine.Status {
|
||||||
return engine.StatusOK
|
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 (
|
var (
|
||||||
repoName, tag string
|
repoName, tag string
|
||||||
tags = []string{}
|
tags = []string{}
|
||||||
|
@ -1920,8 +1920,8 @@ func (srv *Server) DeleteImage(name string, imgs *engine.Table, first, force boo
|
||||||
out.Set("Deleted", img.ID)
|
out.Set("Deleted", img.ID)
|
||||||
imgs.Add(out)
|
imgs.Add(out)
|
||||||
srv.LogEvent("delete", img.ID, "")
|
srv.LogEvent("delete", img.ID, "")
|
||||||
if img.Parent != "" {
|
if img.Parent != "" && !noprune {
|
||||||
err := srv.DeleteImage(img.Parent, imgs, false, force)
|
err := srv.DeleteImage(img.Parent, imgs, false, force, noprune)
|
||||||
if first {
|
if first {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1938,7 +1938,7 @@ func (srv *Server) ImageDelete(job *engine.Job) engine.Status {
|
||||||
return job.Errorf("Usage: %s IMAGE", job.Name)
|
return job.Errorf("Usage: %s IMAGE", job.Name)
|
||||||
}
|
}
|
||||||
imgs := engine.NewTable("", 0)
|
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)
|
return job.Error(err)
|
||||||
}
|
}
|
||||||
if len(imgs.Data) == 0 {
|
if len(imgs.Data) == 0 {
|
||||||
|
|
Loading…
Add table
Reference in a new issue