Skip to content

Commit

Permalink
fix: push an empty index when deleting the last referrer with SkipRef…
Browse files Browse the repository at this point in the history
…errersGC (oras-project#593)

Fix: oras-project#592
Signed-off-by: Lixia (Sylvia) Lei <lixlei@microsoft.com>
  • Loading branch information
Wwwsylvia committed Sep 12, 2023
1 parent c130949 commit 577bffe
Show file tree
Hide file tree
Showing 2 changed files with 572 additions and 64 deletions.
39 changes: 22 additions & 17 deletions registry/remote/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -1425,26 +1425,25 @@ func (s *manifestStore) indexReferrersForPush(ctx context.Context, desc ocispec.
func (s *manifestStore) updateReferrersIndex(ctx context.Context, subject ocispec.Descriptor, change referrerChange) (err error) {
referrersTag := buildReferrersTag(subject)

skipDelete := s.repo.SkipReferrersGC
var oldIndexDesc ocispec.Descriptor
var referrers []ocispec.Descriptor
var oldIndexDesc *ocispec.Descriptor
var oldReferrers []ocispec.Descriptor
prepare := func() error {
// 1. pull the original referrers list using the referrers tag schema
var err error
oldIndexDesc, referrers, err = s.repo.referrersFromIndex(ctx, referrersTag)
indexDesc, referrers, err := s.repo.referrersFromIndex(ctx, referrersTag)
if err != nil {
if errors.Is(err, errdef.ErrNotFound) {
// no old index found, skip delete
skipDelete = true
// valid case: no old referrers index
return nil
}
return err
}
oldIndexDesc = &indexDesc
oldReferrers = referrers
return nil
}
update := func(referrerChanges []referrerChange) error {
// 2. apply the referrer changes on the referrers list
updatedReferrers, err := applyReferrerChanges(referrers, referrerChanges)
updatedReferrers, err := applyReferrerChanges(oldReferrers, referrerChanges)
if err != nil {
if err == errNoReferrerUpdate {
return nil
Expand All @@ -1453,7 +1452,12 @@ func (s *manifestStore) updateReferrersIndex(ctx context.Context, subject ocispe
}

// 3. push the updated referrers list using referrers tag schema
if len(updatedReferrers) > 0 {
if len(updatedReferrers) > 0 || s.repo.SkipReferrersGC {
// push a new index in either case:
// 1. the referrers list has been updated with a non-zero size
// 2. OR the updated referrers list is empty but referrers GC
// is skipped, in this case an empty index should still be pushed
// as the old index won't get deleted
newIndexDesc, newIndex, err := generateIndex(updatedReferrers)
if err != nil {
return fmt.Errorf("failed to generate referrers index for referrers tag %s: %w", referrersTag, err)
Expand All @@ -1463,14 +1467,15 @@ func (s *manifestStore) updateReferrersIndex(ctx context.Context, subject ocispe
}
}

// 4. delete the dangling original referrers index
if !skipDelete {
if err := s.repo.delete(ctx, oldIndexDesc, true); err != nil {
return &ReferrersError{
Op: opDeleteReferrersIndex,
Err: fmt.Errorf("failed to delete dangling referrers index %s for referrers tag %s: %w", oldIndexDesc.Digest.String(), referrersTag, err),
Subject: subject,
}
// 4. delete the dangling original referrers index, if applicable
if s.repo.SkipReferrersGC || oldIndexDesc == nil {
return nil
}
if err := s.repo.delete(ctx, *oldIndexDesc, true); err != nil {
return &ReferrersError{
Op: opDeleteReferrersIndex,
Err: fmt.Errorf("failed to delete dangling referrers index %s for referrers tag %s: %w", oldIndexDesc.Digest.String(), referrersTag, err),
Subject: subject,
}
}
return nil
Expand Down

0 comments on commit 577bffe

Please sign in to comment.