From 78421b376897c589a3c7a80a5b94fc3dd74e2741 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 8 Apr 2014 01:00:32 +0000 Subject: [PATCH 1/2] docker rmi -f works with stopped containers + revamped error messages Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- server/server.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/server/server.go b/server/server.go index 0ab0a4a00b..8426a9fc41 100644 --- a/server/server.go +++ b/server/server.go @@ -1952,6 +1952,7 @@ func (srv *Server) DeleteImage(name string, imgs *engine.Table, first, force, no var ( repoName, tag string tags = []string{} + tagDeleted bool ) repoName, tag = utils.ParseRepositoryTag(name) @@ -2002,7 +2003,7 @@ func (srv *Server) DeleteImage(name string, imgs *engine.Table, first, force, no //Untag the current image for _, tag := range tags { - tagDeleted, err := srv.daemon.Repositories().Delete(repoName, tag) + tagDeleted, err = srv.daemon.Repositories().Delete(repoName, tag) if err != nil { return err } @@ -2016,7 +2017,7 @@ func (srv *Server) DeleteImage(name string, imgs *engine.Table, first, force, no tags = srv.daemon.Repositories().ByID()[img.ID] if (len(tags) <= 1 && repoName == "") || len(tags) == 0 { if len(byParents[img.ID]) == 0 { - if err := srv.canDeleteImage(img.ID); err != nil { + if err := srv.canDeleteImage(img.ID, force, tagDeleted); err != nil { return err } if err := srv.daemon.Repositories().DeleteAll(img.ID); err != nil { @@ -2059,7 +2060,11 @@ func (srv *Server) ImageDelete(job *engine.Job) engine.Status { return engine.StatusOK } -func (srv *Server) canDeleteImage(imgID string) error { +func (srv *Server) canDeleteImage(imgID string, force, untagged bool) error { + var message string + if untagged { + message = " (but image was untagged)" + } for _, container := range srv.daemon.List() { parent, err := srv.daemon.Repositories().LookupImage(container.Image) if err != nil { @@ -2068,7 +2073,14 @@ func (srv *Server) canDeleteImage(imgID string) error { if err := parent.WalkHistory(func(p *image.Image) error { if imgID == p.ID { - return fmt.Errorf("Conflict, cannot delete %s because the container %s is using it", utils.TruncateID(imgID), utils.TruncateID(container.ID)) + if container.State.IsRunning() { + if force { + return fmt.Errorf("Conflict, cannot force delete %s because the running container %s is using it%s, stop it and retry", utils.TruncateID(imgID), utils.TruncateID(container.ID), message) + } + return fmt.Errorf("Conflict, cannot delete %s because the running container %s is using it%s, stop it and use -f to force", utils.TruncateID(imgID), utils.TruncateID(container.ID), message) + } else if !force { + return fmt.Errorf("Conflict, cannot delete %s because the container %s is using it%s, use -f to force", utils.TruncateID(imgID), utils.TruncateID(container.ID), message) + } } return nil }); err != nil { From 68d8d9a62d6199d0e285f8ec07b1a3cbdada8ac8 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Mon, 28 Apr 2014 19:03:31 +0000 Subject: [PATCH 2/2] update message Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- server/server.go | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/server/server.go b/server/server.go index 8426a9fc41..caed481a9f 100644 --- a/server/server.go +++ b/server/server.go @@ -24,19 +24,6 @@ package server import ( "encoding/json" "fmt" - "github.com/dotcloud/docker/api" - "github.com/dotcloud/docker/archive" - "github.com/dotcloud/docker/daemon" - "github.com/dotcloud/docker/daemonconfig" - "github.com/dotcloud/docker/dockerversion" - "github.com/dotcloud/docker/engine" - "github.com/dotcloud/docker/graph" - "github.com/dotcloud/docker/image" - "github.com/dotcloud/docker/pkg/graphdb" - "github.com/dotcloud/docker/pkg/signal" - "github.com/dotcloud/docker/registry" - "github.com/dotcloud/docker/runconfig" - "github.com/dotcloud/docker/utils" "io" "io/ioutil" "log" @@ -53,6 +40,20 @@ import ( "sync" "syscall" "time" + + "github.com/dotcloud/docker/api" + "github.com/dotcloud/docker/archive" + "github.com/dotcloud/docker/daemon" + "github.com/dotcloud/docker/daemonconfig" + "github.com/dotcloud/docker/dockerversion" + "github.com/dotcloud/docker/engine" + "github.com/dotcloud/docker/graph" + "github.com/dotcloud/docker/image" + "github.com/dotcloud/docker/pkg/graphdb" + "github.com/dotcloud/docker/pkg/signal" + "github.com/dotcloud/docker/registry" + "github.com/dotcloud/docker/runconfig" + "github.com/dotcloud/docker/utils" ) // jobInitApi runs the remote api server `srv` as a daemon, @@ -2063,7 +2064,7 @@ func (srv *Server) ImageDelete(job *engine.Job) engine.Status { func (srv *Server) canDeleteImage(imgID string, force, untagged bool) error { var message string if untagged { - message = " (but image was untagged)" + message = " (docker untagged the image)" } for _, container := range srv.daemon.List() { parent, err := srv.daemon.Repositories().LookupImage(container.Image)