From cbafe638a7a93a8adcad62908bd9a33a223decec Mon Sep 17 00:00:00 2001 From: Avi Deitcher Date: Tue, 9 Feb 2021 00:22:43 +0200 Subject: [PATCH] Remove blob for layout (#936) Signed-off-by: Avi Deitcher --- pkg/v1/layout/write.go | 13 ++++++++++++ pkg/v1/layout/write_test.go | 42 +++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/pkg/v1/layout/write.go b/pkg/v1/layout/write.go index 9437e3157..9de456ddd 100644 --- a/pkg/v1/layout/write.go +++ b/pkg/v1/layout/write.go @@ -264,6 +264,19 @@ func (l Path) writeLayer(layer v1.Layer) error { return l.WriteBlob(d, r) } +// RemoveBlob removes a file from the blobs directory in the Path +// at blobs/{hash.Algorithm}/{hash.Hex} +// It does *not* remove any reference to it from other manifests or indexes, or +// from the root index.json. +func (l Path) RemoveBlob(hash v1.Hash) error { + dir := l.path("blobs", hash.Algorithm) + err := os.Remove(filepath.Join(dir, hash.Hex)) + if err != nil && !os.IsNotExist(err) { + return err + } + return nil +} + // WriteImage writes an image, including its manifest, config and all of its // layers, to the blobs directory. If any blob already exists, as determined by // the hash filename, does not write it. diff --git a/pkg/v1/layout/write_test.go b/pkg/v1/layout/write_test.go index 6b1dfac61..15ea7c7f1 100644 --- a/pkg/v1/layout/write_test.go +++ b/pkg/v1/layout/write_test.go @@ -420,3 +420,45 @@ func TestReplaceImage(t *testing.T) { t.Fatal("could not find digest3", digest3) } } + +func TestRemoveBlob(t *testing.T) { + // need to set up a basic path + tmp, err := ioutil.TempDir("", "remove-blob-test") + if err != nil { + t.Fatal(err) + } + + defer os.RemoveAll(tmp) + + var ii v1.ImageIndex + ii = empty.Index + l, err := Write(tmp, ii) + if err != nil { + t.Fatal(err) + } + + // create a random blob + b := []byte("abcdefghijklmnop") + hash, _, err := v1.SHA256(bytes.NewReader(b)) + + if err := l.WriteBlob(hash, ioutil.NopCloser(bytes.NewReader(b))); err != nil { + t.Fatal(err) + } + // make sure it exists + b2, err := l.Bytes(hash) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(b, b2) { + t.Fatal("mismatched bytes") + } + // now the real test, delete it + if err := l.RemoveBlob(hash); err != nil { + t.Fatal(err) + } + // now it should not exist + b2, err = l.Bytes(hash) + if err == nil { + t.Fatal("still existed after deletion") + } +}