From fcb083c6ac0fdb71e8db7a58f07a561342d631d3 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Fri, 4 Dec 2015 13:15:54 -0800 Subject: [PATCH] Fix image deletion conflicts with search Removed images were not cleaned up from the digest-set that is used for the search index. Fixes #18437 Signed-off-by: Tonis Tiigi --- image/store.go | 3 ++ image/store_test.go | 39 ++++++++++++++++++++++ integration-cli/docker_cli_inspect_test.go | 4 +-- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/image/store.go b/image/store.go index a9c02d6ed3..302be2f380 100644 --- a/image/store.go +++ b/image/store.go @@ -212,6 +212,9 @@ func (is *store) Delete(id ID) ([]layer.Metadata, error) { delete(is.images[parent].children, id) } + if err := is.digestSet.Remove(digest.Digest(id)); err != nil { + logrus.Errorf("error removing %s from digest set: %q", id, err) + } delete(is.images, id) is.fs.Delete(id) diff --git a/image/store_test.go b/image/store_test.go index 756b3922d6..279708fcba 100644 --- a/image/store_test.go +++ b/image/store_test.go @@ -194,6 +194,45 @@ func TestAddDelete(t *testing.T) { } +func TestSearchAfterDelete(t *testing.T) { + tmpdir, err := ioutil.TempDir("", "images-fs-store") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + fs, err := NewFSStoreBackend(tmpdir) + if err != nil { + t.Fatal(err) + } + + is, err := NewImageStore(fs, &mockLayerGetReleaser{}) + if err != nil { + t.Fatal(err) + } + + id, err := is.Create([]byte(`{"comment": "abc", "rootfs": {"type": "layers"}}`)) + if err != nil { + t.Fatal(err) + } + + id1, err := is.Search(string(id)[:15]) + if err != nil { + t.Fatal(err) + } + + if actual, expected := id1, id; expected != actual { + t.Fatalf("wrong id returned from search: expected %q, got %q", expected, actual) + } + + if _, err := is.Delete(id); err != nil { + t.Fatal(err) + } + + if _, err := is.Search(string(id)[:15]); err == nil { + t.Fatal("expected search after deletion to fail") + } +} + type mockLayerGetReleaser struct{} func (ls *mockLayerGetReleaser) Get(layer.ChainID) (layer.Layer, error) { diff --git a/integration-cli/docker_cli_inspect_test.go b/integration-cli/docker_cli_inspect_test.go index a4387f9707..9a30ace533 100644 --- a/integration-cli/docker_cli_inspect_test.go +++ b/integration-cli/docker_cli_inspect_test.go @@ -348,11 +348,11 @@ func (s *DockerSuite) TestInspectByPrefix(c *check.C) { c.Assert(err, checker.IsNil) c.Assert(id, checker.HasPrefix, "sha256:") - id2, err := inspectField(id[:10], "Id") + id2, err := inspectField(id[:12], "Id") c.Assert(err, checker.IsNil) c.Assert(id, checker.Equals, id2) - id3, err := inspectField(strings.TrimPrefix(id, "sha256:")[:10], "Id") + id3, err := inspectField(strings.TrimPrefix(id, "sha256:")[:12], "Id") c.Assert(err, checker.IsNil) c.Assert(id, checker.Equals, id3) }