Bläddra i källkod

Move "image_delete" to daemon/image_delete.go

Note: this cannot yet be moved to graph/ because of a lingering
dependency on daemon. This has been noted in a FIXME.

Signed-off-by: Solomon Hykes <solomon@docker.com>
Solomon Hykes 11 år sedan
förälder
incheckning
7a5e3df162
4 ändrade filer med 165 tillägg och 151 borttagningar
  1. 2 0
      daemon/daemon.go
  2. 156 0
      daemon/image_delete.go
  3. 0 143
      server/image.go
  4. 7 8
      server/init.go

+ 2 - 0
daemon/daemon.go

@@ -107,6 +107,7 @@ type Daemon struct {
 func (daemon *Daemon) Install(eng *engine.Engine) error {
 	// FIXME: rename "delete" to "rm" for consistency with the CLI command
 	// FIXME: rename ContainerDestroy to ContainerRm for consistency with the CLI command
+	// FIXME: remove ImageDelete's dependency on Daemon, then move to graph/
 	for name, method := range map[string]engine.Handler{
 		"attach":            daemon.ContainerAttach,
 		"commit":            daemon.ContainerCommit,
@@ -127,6 +128,7 @@ func (daemon *Daemon) Install(eng *engine.Engine) error {
 		"top":               daemon.ContainerTop,
 		"unpause":           daemon.ContainerUnpause,
 		"wait":              daemon.ContainerWait,
+		"image_delete":      daemon.ImageDelete, // FIXME: see above
 	} {
 		if err := eng.Register(name, method); err != nil {
 			return err

+ 156 - 0
daemon/image_delete.go

@@ -0,0 +1,156 @@
+package daemon
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/docker/docker/engine"
+	"github.com/docker/docker/graph"
+	"github.com/docker/docker/image"
+	"github.com/docker/docker/pkg/parsers"
+	"github.com/docker/docker/utils"
+)
+
+func (daemon *Daemon) ImageDelete(job *engine.Job) engine.Status {
+	if n := len(job.Args); n != 1 {
+		return job.Errorf("Usage: %s IMAGE", job.Name)
+	}
+	imgs := engine.NewTable("", 0)
+	if err := daemon.DeleteImage(job.Eng, job.Args[0], imgs, true, job.GetenvBool("force"), job.GetenvBool("noprune")); err != nil {
+		return job.Error(err)
+	}
+	if len(imgs.Data) == 0 {
+		return job.Errorf("Conflict, %s wasn't deleted", job.Args[0])
+	}
+	if _, err := imgs.WriteListTo(job.Stdout); err != nil {
+		return job.Error(err)
+	}
+	return engine.StatusOK
+}
+
+// FIXME: make this private and use the job instead
+func (daemon *Daemon) DeleteImage(eng *engine.Engine, name string, imgs *engine.Table, first, force, noprune bool) error {
+	var (
+		repoName, tag string
+		tags          = []string{}
+		tagDeleted    bool
+	)
+
+	// FIXME: please respect DRY and centralize repo+tag parsing in a single central place! -- shykes
+	repoName, tag = parsers.ParseRepositoryTag(name)
+	if tag == "" {
+		tag = graph.DEFAULTTAG
+	}
+
+	img, err := daemon.Repositories().LookupImage(name)
+	if err != nil {
+		if r, _ := daemon.Repositories().Get(repoName); r != nil {
+			return fmt.Errorf("No such image: %s:%s", repoName, tag)
+		}
+		return fmt.Errorf("No such image: %s", name)
+	}
+
+	if strings.Contains(img.ID, name) {
+		repoName = ""
+		tag = ""
+	}
+
+	byParents, err := daemon.Graph().ByParent()
+	if err != nil {
+		return err
+	}
+
+	//If delete by id, see if the id belong only to one repository
+	if repoName == "" {
+		for _, repoAndTag := range daemon.Repositories().ByID()[img.ID] {
+			parsedRepo, parsedTag := parsers.ParseRepositoryTag(repoAndTag)
+			if repoName == "" || repoName == parsedRepo {
+				repoName = parsedRepo
+				if parsedTag != "" {
+					tags = append(tags, parsedTag)
+				}
+			} else if repoName != parsedRepo && !force {
+				// the id belongs to multiple repos, like base:latest and user:test,
+				// in that case return conflict
+				return fmt.Errorf("Conflict, cannot delete image %s because it is tagged in multiple repositories, use -f to force", name)
+			}
+		}
+	} else {
+		tags = append(tags, tag)
+	}
+
+	if !first && len(tags) > 0 {
+		return nil
+	}
+
+	//Untag the current image
+	for _, tag := range tags {
+		tagDeleted, err = daemon.Repositories().Delete(repoName, tag)
+		if err != nil {
+			return err
+		}
+		if tagDeleted {
+			out := &engine.Env{}
+			out.Set("Untagged", repoName+":"+tag)
+			imgs.Add(out)
+			eng.Job("log", "untag", img.ID, "").Run()
+		}
+	}
+	tags = daemon.Repositories().ByID()[img.ID]
+	if (len(tags) <= 1 && repoName == "") || len(tags) == 0 {
+		if len(byParents[img.ID]) == 0 {
+			if err := daemon.canDeleteImage(img.ID, force, tagDeleted); err != nil {
+				return err
+			}
+			if err := daemon.Repositories().DeleteAll(img.ID); err != nil {
+				return err
+			}
+			if err := daemon.Graph().Delete(img.ID); err != nil {
+				return err
+			}
+			out := &engine.Env{}
+			out.Set("Deleted", img.ID)
+			imgs.Add(out)
+			eng.Job("log", "delete", img.ID, "").Run()
+			if img.Parent != "" && !noprune {
+				err := daemon.DeleteImage(eng, img.Parent, imgs, false, force, noprune)
+				if first {
+					return err
+				}
+
+			}
+
+		}
+	}
+	return nil
+}
+
+func (daemon *Daemon) canDeleteImage(imgID string, force, untagged bool) error {
+	var message string
+	if untagged {
+		message = " (docker untagged the image)"
+	}
+	for _, container := range daemon.List() {
+		parent, err := daemon.Repositories().LookupImage(container.Image)
+		if err != nil {
+			return err
+		}
+
+		if err := parent.WalkHistory(func(p *image.Image) error {
+			if imgID == p.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 {
+			return err
+		}
+	}
+	return nil
+}

+ 0 - 143
server/image.go

@@ -19,7 +19,6 @@ import (
 	"github.com/docker/docker/archive"
 	"github.com/docker/docker/builder"
 	"github.com/docker/docker/engine"
-	"github.com/docker/docker/graph"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/registry"
@@ -640,148 +639,6 @@ func (srv *Server) ImagePush(job *engine.Job) engine.Status {
 	return engine.StatusOK
 }
 
-func (srv *Server) DeleteImage(name string, imgs *engine.Table, first, force, noprune bool) error {
-	var (
-		repoName, tag string
-		tags          = []string{}
-		tagDeleted    bool
-	)
-
-	repoName, tag = parsers.ParseRepositoryTag(name)
-	if tag == "" {
-		tag = graph.DEFAULTTAG
-	}
-
-	img, err := srv.daemon.Repositories().LookupImage(name)
-	if err != nil {
-		if r, _ := srv.daemon.Repositories().Get(repoName); r != nil {
-			return fmt.Errorf("No such image: %s:%s", repoName, tag)
-		}
-		return fmt.Errorf("No such image: %s", name)
-	}
-
-	if strings.Contains(img.ID, name) {
-		repoName = ""
-		tag = ""
-	}
-
-	byParents, err := srv.daemon.Graph().ByParent()
-	if err != nil {
-		return err
-	}
-
-	//If delete by id, see if the id belong only to one repository
-	if repoName == "" {
-		for _, repoAndTag := range srv.daemon.Repositories().ByID()[img.ID] {
-			parsedRepo, parsedTag := parsers.ParseRepositoryTag(repoAndTag)
-			if repoName == "" || repoName == parsedRepo {
-				repoName = parsedRepo
-				if parsedTag != "" {
-					tags = append(tags, parsedTag)
-				}
-			} else if repoName != parsedRepo && !force {
-				// the id belongs to multiple repos, like base:latest and user:test,
-				// in that case return conflict
-				return fmt.Errorf("Conflict, cannot delete image %s because it is tagged in multiple repositories, use -f to force", name)
-			}
-		}
-	} else {
-		tags = append(tags, tag)
-	}
-
-	if !first && len(tags) > 0 {
-		return nil
-	}
-
-	//Untag the current image
-	for _, tag := range tags {
-		tagDeleted, err = srv.daemon.Repositories().Delete(repoName, tag)
-		if err != nil {
-			return err
-		}
-		if tagDeleted {
-			out := &engine.Env{}
-			out.Set("Untagged", repoName+":"+tag)
-			imgs.Add(out)
-			srv.LogEvent("untag", img.ID, "")
-		}
-	}
-	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, force, tagDeleted); err != nil {
-				return err
-			}
-			if err := srv.daemon.Repositories().DeleteAll(img.ID); err != nil {
-				return err
-			}
-			if err := srv.daemon.Graph().Delete(img.ID); err != nil {
-				return err
-			}
-			out := &engine.Env{}
-			out.Set("Deleted", img.ID)
-			imgs.Add(out)
-			srv.LogEvent("delete", img.ID, "")
-			if img.Parent != "" && !noprune {
-				err := srv.DeleteImage(img.Parent, imgs, false, force, noprune)
-				if first {
-					return err
-				}
-
-			}
-
-		}
-	}
-	return nil
-}
-
-func (srv *Server) ImageDelete(job *engine.Job) engine.Status {
-	if n := len(job.Args); n != 1 {
-		return job.Errorf("Usage: %s IMAGE", job.Name)
-	}
-	imgs := engine.NewTable("", 0)
-	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 {
-		return job.Errorf("Conflict, %s wasn't deleted", job.Args[0])
-	}
-	if _, err := imgs.WriteListTo(job.Stdout); err != nil {
-		return job.Error(err)
-	}
-	return engine.StatusOK
-}
-
-func (srv *Server) canDeleteImage(imgID string, force, untagged bool) error {
-	var message string
-	if untagged {
-		message = " (docker untagged the image)"
-	}
-	for _, container := range srv.daemon.List() {
-		parent, err := srv.daemon.Repositories().LookupImage(container.Image)
-		if err != nil {
-			return err
-		}
-
-		if err := parent.WalkHistory(func(p *image.Image) error {
-			if imgID == p.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 {
-			return err
-		}
-	}
-	return nil
-}
-
 func (srv *Server) poolAdd(kind, key string) (chan struct{}, error) {
 	srv.Lock()
 	defer srv.Unlock()

+ 7 - 8
server/init.go

@@ -86,14 +86,13 @@ func InitServer(job *engine.Job) engine.Status {
 	job.Eng.Hack_SetGlobalVar("httpapi.daemon", srv.daemon)
 
 	for name, handler := range map[string]engine.Handler{
-		"tag":          srv.ImageTag, // FIXME merge with "image_tag"
-		"info":         srv.DockerInfo,
-		"log":          srv.Log,
-		"build":        srv.Build,
-		"pull":         srv.ImagePull,
-		"image_delete": srv.ImageDelete,
-		"events":       srv.Events,
-		"push":         srv.ImagePush,
+		"tag":    srv.ImageTag, // FIXME merge with "image_tag"
+		"info":   srv.DockerInfo,
+		"log":    srv.Log,
+		"build":  srv.Build,
+		"pull":   srv.ImagePull,
+		"events": srv.Events,
+		"push":   srv.ImagePush,
 	} {
 		if err := job.Eng.Register(name, srv.handlerWrap(handler)); err != nil {
 			return job.Error(err)