Victor Vieux %!s(int64=12) %!d(string=hai) anos
pai
achega
c80448c4d1
Modificáronse 4 ficheiros con 156 adicións e 2 borrados
  1. 45 2
      api_test.go
  2. 36 0
      server.go
  3. 52 0
      server_test.go
  4. 23 0
      tags.go

+ 45 - 2
api_test.go

@@ -1189,8 +1189,51 @@ func TestDeleteContainers(t *testing.T) {
 }
 }
 
 
 func TestDeleteImages(t *testing.T) {
 func TestDeleteImages(t *testing.T) {
-	//FIXME: Implement this test
-	t.Log("Test not implemented")
+	runtime, err := newTestRuntime()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer nuke(runtime)
+
+	srv := &Server{runtime: runtime}
+
+	if err := srv.runtime.repositories.Set("test", "test", unitTestImageName, true); err != nil {
+		t.Fatal(err)
+	}
+
+	images, err := srv.Images(false, "")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(images) != 2 {
+		t.Errorf("Excepted 2 images, %d found", len(images))
+	}
+
+	r := httptest.NewRecorder()
+	if err := deleteImages(srv, r, nil, map[string]string{"name": "test:test"}); err != nil {
+		t.Fatal(err)
+	}
+	if r.Code != http.StatusNoContent {
+		t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
+	}
+
+	images, err = srv.Images(false, "")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(images) != 1 {
+		t.Errorf("Excepted 1 image, %d found", len(images))
+	}
+
+	/*	if c := runtime.Get(container.Id); c != nil {
+			t.Fatalf("The container as not been deleted")
+		}
+
+		if _, err := os.Stat(path.Join(container.rwPath(), "test")); err == nil {
+			t.Fatalf("The test file has not been deleted")
+		} */
 }
 }
 
 
 // Mocked types for tests
 // Mocked types for tests

+ 36 - 0
server.go

@@ -439,9 +439,45 @@ func (srv *Server) ImageDelete(name string) error {
 	if err != nil {
 	if err != nil {
 		return fmt.Errorf("No such image: %s", name)
 		return fmt.Errorf("No such image: %s", name)
 	} else {
 	} else {
+		tag := ""
+		if strings.Contains(name, ":") {
+			nameParts := strings.Split(name, ":")
+			name = nameParts[0]
+			tag = nameParts[1]
+		}
+		// if the images is referenced several times
+		Debugf("Image %s referenced %d times", img.Id, len(srv.runtime.repositories.ById()[img.Id]))
+		if len(srv.runtime.repositories.ById()[img.Id]) > 1 {
+			// if it's repo:tag, try to delete the tag (docker rmi base:latest)
+			if tag != "" {
+				if err := srv.runtime.repositories.Delete(name, tag, img.Id); err != nil {
+					return err
+				}
+				return nil
+			} else {
+				// check if the image is referenced in another repo (base and user/base are the same, docker rmi user/base)
+				var other bool
+				for _, repoTag := range srv.runtime.repositories.ById()[img.Id] {
+					if !strings.Contains(repoTag, name+":") {
+						other = true
+						break
+					}
+				}
+				// if found in another repo, delete the repo, other delete the whole image (docker rmi base)
+				if other {
+					if err := srv.runtime.repositories.Delete(name, "", img.Id); err != nil {
+						return err
+					}
+					return nil
+				}
+			}
+		}
 		if err := srv.runtime.graph.Delete(img.Id); err != nil {
 		if err := srv.runtime.graph.Delete(img.Id); err != nil {
 			return fmt.Errorf("Error deleting image %s: %s", name, err.Error())
 			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 nil
 }
 }

+ 52 - 0
server_test.go

@@ -4,6 +4,58 @@ import (
 	"testing"
 	"testing"
 )
 )
 
 
+func TestContainerTagImageDelete(t *testing.T) {
+	runtime, err := newTestRuntime()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer nuke(runtime)
+
+	srv := &Server{runtime: runtime}
+
+	if err := srv.runtime.repositories.Set("utest", "tag1", unitTestImageName, false); err != nil {
+		t.Fatal(err)
+	}
+	if err := srv.runtime.repositories.Set("utest/docker", "tag2", unitTestImageName, false); err != nil {
+		t.Fatal(err)
+	}
+
+	images, err := srv.Images(false, "")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(images) != 3 {
+		t.Errorf("Excepted 3 images, %d found", len(images))
+	}
+
+	if err := srv.ImageDelete("utest/docker:tag2"); err != nil {
+		t.Fatal(err)
+	}
+
+	images, err = srv.Images(false, "")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(images) != 2 {
+		t.Errorf("Excepted 2 images, %d found", len(images))
+	}
+
+	if err := srv.ImageDelete("utest:tag1"); err != nil {
+		t.Fatal(err)
+	}
+
+	images, err = srv.Images(false, "")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(images) != 1 {
+		t.Errorf("Excepted 1 image, %d found", len(images))
+	}
+}
+
 func TestCreateRm(t *testing.T) {
 func TestCreateRm(t *testing.T) {
 	runtime, err := newTestRuntime()
 	runtime, err := newTestRuntime()
 	if err != nil {
 	if err != nil {

+ 23 - 0
tags.go

@@ -109,6 +109,29 @@ func (store *TagStore) ImageName(id string) string {
 	return TruncateId(id)
 	return TruncateId(id)
 }
 }
 
 
+func (store *TagStore) Delete(repoName, tag, imageName string) error {
+	if err := store.Reload(); err != nil {
+		return err
+	}
+	if r, exists := store.Repositories[repoName]; exists {
+		if tag != "" {
+			if _, exists2 := r[tag]; exists2 {
+				delete(r, tag)
+				if len(r) == 0 {
+					delete(store.Repositories, repoName)
+				}
+			} else {
+				return fmt.Errorf("No such tag: %s:%s", repoName, tag)
+			}
+		} else {
+			delete(store.Repositories, repoName)
+		}
+	} else {
+		fmt.Errorf("No such repository: %s", repoName)
+	}
+	return store.Save()
+}
+
 func (store *TagStore) Set(repoName, tag, imageName string, force bool) error {
 func (store *TagStore) Set(repoName, tag, imageName string, force bool) error {
 	img, err := store.LookupImage(imageName)
 	img, err := store.LookupImage(imageName)
 	if err != nil {
 	if err != nil {