Explorar el Código

WIP needs to fix HTTP error codes

Victor Vieux hace 12 años
padre
commit
5aa95b667c
Se han modificado 2 ficheros con 58 adiciones y 70 borrados
  1. 37 69
      server.go
  2. 21 1
      tags.go

+ 37 - 69
server.go

@@ -705,26 +705,22 @@ func (srv *Server) ContainerDestroy(name string, removeVolume bool) error {
 	return nil
 }
 
-func (srv *Server) pruneImage(img *Image, repo, tag string) error {
-	return nil
-}
-
 var ErrImageReferenced = errors.New("Image referenced by a repository")
 
-func (srv *Server) deleteImageChildren(id string, byId map[string][]string, byParents map[string][]*Image) error {
+func (srv *Server) deleteImageAndChildren(id string) error {
 	// If the image is referenced by a repo, do not delete
-	if len(byId[id]) != 0 {
+	if len(srv.runtime.repositories.ById()[id]) != 0 {
 		return ErrImageReferenced
 	}
-	// If the image is not referenced and has no children, remove it
-	if len(byParents[id]) == 0 {
-		return srv.runtime.graph.Delete(id)
-	}
 
 	// If the image is not referenced but has children, go recursive
 	referenced := false
+	byParents, err := srv.runtime.graph.ByParent()
+	if err != nil {
+		return err
+	}
 	for _, img := range byParents[id] {
-		if err := srv.deleteImageChildren(img.Id, byId, byParents); err != nil {
+		if err := srv.deleteImageAndChildren(img.Id); err != nil {
 			if err != ErrImageReferenced {
 				return err
 			} else {
@@ -735,56 +731,61 @@ func (srv *Server) deleteImageChildren(id string, byId map[string][]string, byPa
 	if referenced {
 		return ErrImageReferenced
 	}
+
+	// If the image is not referenced and has no children, remove it
+	byParents, err = srv.runtime.graph.ByParent()
+	if err != nil {
+		return err
+	}
+	if len(byParents[id]) == 0 {
+		if err := srv.runtime.repositories.DeleteAll(id); err != nil {
+			return err
+		}
+		return srv.runtime.graph.Delete(id)
+	}
 	return nil
 }
 
-func (srv *Server) deleteImageParents(img *Image, byId map[string][]string, byParents map[string][]*Image) error {
+func (srv *Server) deleteImageParents(img *Image) error {
 	if img.Parent != "" {
 		parent, err := srv.runtime.graph.Get(img.Parent)
 		if err != nil {
 			return err
 		}
 		// Remove all children images
-		if err := srv.deleteImageChildren(img.Id, byId, byParents); err != nil {
+		if err := srv.deleteImageAndChildren(img.Parent); err != nil {
 			return err
 		}
-		// If no error (no referenced children), then remove the parent
-		if err := srv.runtime.graph.Delete(img.Parent); err != nil {
-			return err
-		}
-		return srv.deleteImageParents(parent, byId, byParents)
+		return srv.deleteImageParents(parent)
 	}
 	return nil
 }
 
-func (srv *Server) deleteImage(repoName, tag string) error {
-	img, err := srv.runtime.repositories.LookupImage(repoName + ":" + tag)
-	if err != nil {
-		return fmt.Errorf("No such image: %s:%s", repoName, tag)
-	}
-	utils.Debugf("Image %s referenced %d times", img.Id, len(srv.runtime.repositories.ById()[img.Id]))
-	if err := srv.runtime.repositories.Delete(repoName, tag, img.Id); err != nil {
+func (srv *Server) deleteImage(img *Image, repoName, tag string) error {
+	//Untag the current image
+	if err := srv.runtime.repositories.Delete(repoName, tag); err != nil {
 		return err
 	}
-	byId := srv.runtime.repositories.ById()
-	if len(byId[img.Id]) == 0 {
-		byParents, err := srv.runtime.graph.ByParent()
-		if err != nil {
-			return err
-		}
-		if err := srv.deleteImageChildren(img.Id, byId, byParents); err != nil {
+	if len(srv.runtime.repositories.ById()[img.Id]) == 0 {
+		if err := srv.deleteImageAndChildren(img.Id); err != nil {
+			if err != ErrImageReferenced {
+				return err
+			}
+		} else if err := srv.deleteImageParents(img); err != nil {
 			if err != ErrImageReferenced {
 				return err
 			}
-		} else {
-			srv.deleteImageParents(img)
 		}
-
 	}
 	return nil
 }
 
 func (srv *Server) ImageDelete(name string) error {
+	img, err := srv.runtime.repositories.LookupImage(name)
+	if err != nil {
+		return fmt.Errorf("No such image: %s", name)
+	}
+
 	var tag string
 	if strings.Contains(name, ":") {
 		nameParts := strings.Split(name, ":")
@@ -792,40 +793,7 @@ func (srv *Server) ImageDelete(name string) error {
 		tag = nameParts[1]
 	}
 
-	srv.deleteImage(name, tag)
-
-	// if the images is referenced several times
-
-	// check is the image to delete isn't parent of another image
-	byParent, _ := srv.runtime.graph.ByParent()
-	if childs, exists := byParent[img.Id]; exists {
-		if strings.Contains(img.Id, name) {
-			return fmt.Errorf("Conflict with %s, %s was not removed", childs[0].ShortId(), name)
-		}
-		if err := srv.runtime.repositories.Delete(name, tag, img.Id); err != nil {
-			return err
-		}
-		return nil
-	}
-	parents, _ := img.History()
-	for _, parent := range parents {
-		byParent, _ = srv.runtime.graph.ByParent()
-		//stop if image has children
-		if _, exists := byParent[parent.Id]; exists {
-			break
-		}
-		//stop if image is tagged and it is not the first image we delete
-		if _, hasTags := srv.runtime.repositories.ById()[parent.Id]; hasTags && img.Id != parent.Id {
-			break
-		}
-		if err := srv.runtime.graph.Delete(parent.Id); err != nil {
-			return fmt.Errorf("Error deleting image %s: %s", name, err.Error())
-		}
-		if err := srv.runtime.repositories.Delete(name, tag, img.Id); err != nil {
-			return err
-		}
-	}
-	return nil
+	return srv.deleteImage(img, name, tag)
 }
 
 func (srv *Server) ImageGetCached(imgId string, config *Config) (*Image, error) {

+ 21 - 1
tags.go

@@ -110,7 +110,27 @@ func (store *TagStore) ImageName(id string) string {
 	return utils.TruncateId(id)
 }
 
-func (store *TagStore) Delete(repoName, tag, imageName string) error {
+func (store *TagStore) DeleteAll(id string) error {
+	names, exists := store.ById()[id]
+	if !exists || len(names) == 0 {
+		return nil
+	}
+	for _, name := range names {
+		if strings.Contains(name, ":") {
+			nameParts := strings.Split(name, ":")
+			if err := store.Delete(nameParts[0], nameParts[1]); err != nil {
+				return err
+			}
+		} else {
+			if err := store.Delete(name, ""); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func (store *TagStore) Delete(repoName, tag string) error {
 	if err := store.Reload(); err != nil {
 		return err
 	}