diff --git a/content/oci/storage.go b/content/oci/storage.go index 9d4d03b3..6acf5b34 100644 --- a/content/oci/storage.go +++ b/content/oci/storage.go @@ -106,6 +106,16 @@ func (s *Storage) Push(_ context.Context, expected ocispec.Descriptor, content i return nil } +// Delete removes the target from the system. +func (s *Storage) Delete(ctx context.Context, target ocispec.Descriptor) error { + path, err := blobPath(target.Digest) + if err != nil { + return fmt.Errorf("%s: %s: %w", target.Digest, target.MediaType, errdef.ErrInvalidDigest) + } + targetPath := filepath.Join(s.root, path) + return os.Remove(targetPath) +} + // ingest write the content into a temporary ingest file. func (s *Storage) ingest(expected ocispec.Descriptor, content io.Reader) (path string, ingestErr error) { if err := ensureDir(s.ingestRoot); err != nil { diff --git a/content/oci/storage_test.go b/content/oci/storage_test.go index ac6ae8dd..6c30cba2 100644 --- a/content/oci/storage_test.go +++ b/content/oci/storage_test.go @@ -377,3 +377,39 @@ func TestStorage_Fetch_Concurrent(t *testing.T) { t.Fatal(err) } } + +func TestStorage_Delete(t *testing.T) { + content := []byte("test delete") + desc := ocispec.Descriptor{ + MediaType: "test", + Digest: digest.FromBytes(content), + Size: int64(len(content)), + } + tempDir := t.TempDir() + s, err := NewStorage(tempDir) + if err != nil { + t.Fatal("New() error =", err) + } + ctx := context.Background() + if err := s.Push(ctx, desc, bytes.NewReader(content)); err != nil { + t.Fatal("Storage.Push() error =", err) + } + exists, err := s.Exists(ctx, desc) + if err != nil { + t.Fatal("Storage.Exists() error =", err) + } + if !exists { + t.Errorf("Storage.Exists() = %v, want %v", exists, true) + } + err = s.Delete(ctx, desc) + if err != nil { + t.Fatal("Storage.Delete() error =", err) + } + exists, err = s.Exists(ctx, desc) + if err != nil { + t.Fatal("Storage.Exists() error =", err) + } + if exists { + t.Errorf("Storage.Exists() = %v, want %v", exists, false) + } +}