docker rmi -f works with stopped containers + revamped error messages
Docker-DCO-1.1-Signed-off-by: Victor Vieux <victor.vieux@docker.com> (github: vieux) Upstream-commit: 78421b376897c589a3c7a80a5b94fc3dd74e2741 Component: engine
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user