瀏覽代碼

Merge pull request #2184 from dotcloud/dm-rmi

Do not allow image to be deleted when containers are dependent
Solomon Hykes 11 年之前
父節點
當前提交
063ebbab68
共有 1 個文件被更改,包括 35 次插入0 次删除
  1. 35 0
      server.go

+ 35 - 0
server.go

@@ -996,6 +996,14 @@ func (srv *Server) ContainerDestroy(name string, removeVolume bool) error {
 
 var ErrImageReferenced = errors.New("Image referenced by a repository")
 
+func (srv *Server) getChildImages(id string) ([]*Image, error) {
+	byParents, err := srv.runtime.graph.ByParent()
+	if err != nil {
+		return nil, err
+	}
+	return byParents[id], nil
+}
+
 func (srv *Server) deleteImageAndChildren(id string, imgs *[]APIRmi) error {
 	// If the image is referenced by a repo, do not delete
 	if len(srv.runtime.repositories.ByID()[id]) != 0 {
@@ -1101,6 +1109,33 @@ func (srv *Server) ImageDelete(name string, autoPrune bool) ([]APIRmi, error) {
 	if err != nil {
 		return nil, fmt.Errorf("No such image: %s", name)
 	}
+	images := make(map[string]bool)
+	images[img.ID] = true
+
+	children, err := srv.getChildImages(img.ID)
+	if err != nil {
+		return nil, err
+	}
+
+	for _, i := range children {
+		images[i.ID] = true
+	}
+
+	// Check for any containers referencing the image or children of the image
+	referencedContainers := []string{}
+
+	for e := srv.runtime.containers.Front(); e != nil; e = e.Next() {
+		c := e.Value.(*Container)
+		if images[c.Image] {
+			referencedContainers = append(referencedContainers, c.ID)
+		}
+	}
+
+	if len(referencedContainers) > 0 {
+		return nil, fmt.Errorf("Cannot delete image with existing containers.  Please remove %s before deleting image.",
+			strings.Join(referencedContainers, ", "))
+	}
+
 	if !autoPrune {
 		if err := srv.runtime.DeleteImage(img.ID); err != nil {
 			return nil, fmt.Errorf("Error deleting image %s: %s", name, err)