Skip to content

Commit

Permalink
done implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Xiaoxuan Wang <wangxiaoxuan119@gmail.com>
  • Loading branch information
wangxiaoxuan273 committed Dec 27, 2023
1 parent 984974f commit 81e0b9c
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 22 deletions.
52 changes: 42 additions & 10 deletions content/oci/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"oras.land/oras-go/v2/internal/descriptor"
"oras.land/oras-go/v2/internal/graph"
"oras.land/oras-go/v2/internal/resolver"
"oras.land/oras-go/v2/registry"
)

// Store implements `oras.Target`, and represents a content store
Expand All @@ -61,6 +62,11 @@ type Store struct {
// - Default value: true.
AutoGC bool

// AutoRemoveReferrers controls if the OCI store will automatically delete its
// referrers when a manifest is deleted.
// - Default value: true.
AutoRemoveReferrers bool

root string
indexPath string
index *ocispec.Index
Expand Down Expand Up @@ -93,13 +99,14 @@ func NewWithContext(ctx context.Context, root string) (*Store, error) {
}

store := &Store{
AutoSaveIndex: true,
AutoGC: true,
root: rootAbs,
indexPath: filepath.Join(rootAbs, ocispec.ImageIndexFile),
storage: storage,
tagResolver: resolver.NewMemory(),
graph: graph.NewMemory(),
AutoSaveIndex: true,
AutoGC: true,
AutoRemoveReferrers: true,
root: rootAbs,
indexPath: filepath.Join(rootAbs, ocispec.ImageIndexFile),
storage: storage,
tagResolver: resolver.NewMemory(),
graph: graph.NewMemory(),
}

if err := ensureDir(filepath.Join(rootAbs, ocispec.ImageBlobsDir)); err != nil {
Expand Down Expand Up @@ -155,6 +162,16 @@ func (s *Store) Exists(ctx context.Context, target ocispec.Descriptor) (bool, er
// fail on certain systems (i.e. NTFS), if there is a process (i.e. an unclosed
// Reader) using target.
func (s *Store) Delete(ctx context.Context, target ocispec.Descriptor) error {
// get referrers first to avoid deadlock
var referrers []ocispec.Descriptor
if descriptor.IsManifest(target) && s.AutoRemoveReferrers {
res, err := registry.Referrers(ctx, s, target, "")
referrers = append(referrers, res...)
if err != nil {
return err
}
}

s.sync.Lock()
defer s.sync.Unlock()

Expand All @@ -166,8 +183,24 @@ func (s *Store) Delete(ctx context.Context, target ocispec.Descriptor) error {

// delete the dangling nodes caused by the delete
if s.AutoGC {
return s.cleanGraphs(ctx, danglings)
if err := s.cleanGraphs(ctx, danglings); err != nil {
return err
}
}

// delete the referrers
for _, desc := range referrers {
danglings, err := s.delete(ctx, desc)
if err != nil {
return err
}
if s.AutoGC {
if err := s.cleanGraphs(ctx, danglings); err != nil {
return err
}
}
}

return nil
}

Expand Down Expand Up @@ -195,8 +228,7 @@ func (s *Store) delete(ctx context.Context, target ocispec.Descriptor) ([]ocispe
}

func (s *Store) cleanGraphs(ctx context.Context, danglings []ocispec.Descriptor) error {
// for each item in dangling, if it exists and it is dangling, remove it and
// add new dangling nodes into dangling
// for each item in danglings, remove it and add new dangling nodes into danglings
for len(danglings) > 0 {
node := danglings[0]
danglings = danglings[1:]
Expand Down
24 changes: 12 additions & 12 deletions content/oci/oci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2375,13 +2375,13 @@ func TestStore_DeleteWithGarbageCollection(t *testing.T) {
}

// blob 1, 3, 4, 6 and 8 are now deleted, and other blobs are still present
notPresent = []ocispec.Descriptor{descs[1], descs[3], descs[4], descs[6], descs[8]}
notPresent = []ocispec.Descriptor{descs[1], descs[3], descs[4], descs[6], descs[8], descs[9]}
for _, node := range notPresent {
if exists, _ := s.Exists(egCtx, node); exists {
t.Errorf("%v should not exist in store", node)
}
}
stillPresent = []ocispec.Descriptor{descs[0], descs[2], descs[5], descs[7], descs[9]}
stillPresent = []ocispec.Descriptor{descs[0], descs[2], descs[5], descs[7]}
for _, node := range stillPresent {
if exists, _ := s.Exists(egCtx, node); !exists {
t.Errorf("%v should exist in store", node)
Expand All @@ -2390,16 +2390,16 @@ func TestStore_DeleteWithGarbageCollection(t *testing.T) {

// verify predecessors information
wants := [][]ocispec.Descriptor{
{descs[5], descs[9]}, // Blob 0
nil, // Blob 1
{descs[5], descs[9]}, // Blob 2
nil, // Blob 3
{descs[7]}, // Blob 4's predecessor is descs[7], even though blob 4 no longer exist
{descs[7]}, // Blob 5
{descs[9]}, // Blob 6's predecessor is descs[9], even though blob 6 no longer exist
nil, // Blob 7
nil, // Blob 8
nil, // Blob 9
{descs[5]}, // Blob 0
nil, // Blob 1
{descs[5]}, // Blob 2
nil, // Blob 3
{descs[7]}, // Blob 4's predecessor is descs[7], even though blob 4 no longer exist
{descs[7]}, // Blob 5
nil, // Blob 6
nil, // Blob 7
nil, // Blob 8
nil, // Blob 9
}
for i, want := range wants {
predecessors, err := s.Predecessors(ctx, descs[i])
Expand Down

0 comments on commit 81e0b9c

Please sign in to comment.