mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
improve rmi
This commit is contained in:
parent
d586662ce5
commit
c80448c4d1
4 changed files with 156 additions and 2 deletions
47
api_test.go
47
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
|
runtime, err := newTestRuntime()
|
||||||
t.Log("Test not implemented")
|
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
server.go
36
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
tags.go
23
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 {
|
||||||
|
|
Loading…
Reference in a new issue