@@ -1425,26 +1425,25 @@ func (s *manifestStore) indexReferrersForPush(ctx context.Context, desc ocispec.
1425
1425
func (s * manifestStore ) updateReferrersIndex (ctx context.Context , subject ocispec.Descriptor , change referrerChange ) (err error ) {
1426
1426
referrersTag := buildReferrersTag (subject )
1427
1427
1428
- skipDelete := s .repo .SkipReferrersGC
1429
- var oldIndexDesc ocispec.Descriptor
1430
- var referrers []ocispec.Descriptor
1428
+ var oldIndexDesc * ocispec.Descriptor
1429
+ var oldReferrers []ocispec.Descriptor
1431
1430
prepare := func () error {
1432
1431
// 1. pull the original referrers list using the referrers tag schema
1433
- var err error
1434
- oldIndexDesc , referrers , err = s .repo .referrersFromIndex (ctx , referrersTag )
1432
+ indexDesc , referrers , err := s .repo .referrersFromIndex (ctx , referrersTag )
1435
1433
if err != nil {
1436
1434
if errors .Is (err , errdef .ErrNotFound ) {
1437
- // no old index found, skip delete
1438
- skipDelete = true
1435
+ // valid case: no old referrers index
1439
1436
return nil
1440
1437
}
1441
1438
return err
1442
1439
}
1440
+ oldIndexDesc = & indexDesc
1441
+ oldReferrers = referrers
1443
1442
return nil
1444
1443
}
1445
1444
update := func (referrerChanges []referrerChange ) error {
1446
1445
// 2. apply the referrer changes on the referrers list
1447
- updatedReferrers , err := applyReferrerChanges (referrers , referrerChanges )
1446
+ updatedReferrers , err := applyReferrerChanges (oldReferrers , referrerChanges )
1448
1447
if err != nil {
1449
1448
if err == errNoReferrerUpdate {
1450
1449
return nil
@@ -1453,7 +1452,12 @@ func (s *manifestStore) updateReferrersIndex(ctx context.Context, subject ocispe
1453
1452
}
1454
1453
1455
1454
// 3. push the updated referrers list using referrers tag schema
1456
- if len (updatedReferrers ) > 0 {
1455
+ if len (updatedReferrers ) > 0 || s .repo .SkipReferrersGC {
1456
+ // push a new index in either case:
1457
+ // 1. the referrers list has been updated with a non-zero size
1458
+ // 2. OR the updated referrers list is empty but referrers GC
1459
+ // is skipped, in this case an empty index should still be pushed
1460
+ // as the old index won't get deleted
1457
1461
newIndexDesc , newIndex , err := generateIndex (updatedReferrers )
1458
1462
if err != nil {
1459
1463
return fmt .Errorf ("failed to generate referrers index for referrers tag %s: %w" , referrersTag , err )
@@ -1463,14 +1467,15 @@ func (s *manifestStore) updateReferrersIndex(ctx context.Context, subject ocispe
1463
1467
}
1464
1468
}
1465
1469
1466
- // 4. delete the dangling original referrers index
1467
- if ! skipDelete {
1468
- if err := s .repo .delete (ctx , oldIndexDesc , true ); err != nil {
1469
- return & ReferrersError {
1470
- Op : opDeleteReferrersIndex ,
1471
- Err : fmt .Errorf ("failed to delete dangling referrers index %s for referrers tag %s: %w" , oldIndexDesc .Digest .String (), referrersTag , err ),
1472
- Subject : subject ,
1473
- }
1470
+ // 4. delete the dangling original referrers index, if applicable
1471
+ if s .repo .SkipReferrersGC || oldIndexDesc == nil {
1472
+ return nil
1473
+ }
1474
+ if err := s .repo .delete (ctx , * oldIndexDesc , true ); err != nil {
1475
+ return & ReferrersError {
1476
+ Op : opDeleteReferrersIndex ,
1477
+ Err : fmt .Errorf ("failed to delete dangling referrers index %s for referrers tag %s: %w" , oldIndexDesc .Digest .String (), referrersTag , err ),
1478
+ Subject : subject ,
1474
1479
}
1475
1480
}
1476
1481
return nil
0 commit comments