@@ -34,16 +34,17 @@ import (
3434type ociImageDestination struct {
3535 impl.Compat
3636 impl.PropertyMethodsInitialize
37+ stubs.AlwaysSupportsSignatures
3738 stubs.IgnoresOriginalOCIConfig
3839 stubs.NoPutBlobPartialInitialize
3940
4041 ref ociReference
4142 index imgspecv1.Index
4243 sharedBlobDir string
43- sys * types. SystemContext
44- manifestDigest digest. Digest
45- // blobsToDelete is a set of digests which may be deleted
46- blobsToDelete * set.Set [digest.Digest ]
44+ manifestDigest digest. Digest // or "" if not yet known.
45+ // blobDeleteCandidates is a set of digests which may be deleted _if_ we find no other references to them;
46+ // it’s safe to optimistically include entries which may have other references
47+ blobDeleteCandidates * set.Set [digest.Digest ]
4748}
4849
4950// newImageDestination returns an ImageDestination for writing to an existing directory.
@@ -86,10 +87,9 @@ func newImageDestination(sys *types.SystemContext, ref ociReference) (private.Im
8687 }),
8788 NoPutBlobPartialInitialize : stubs .NoPutBlobPartial (ref ),
8889
89- ref : ref ,
90- index : * index ,
91- sys : sys ,
92- blobsToDelete : set .New [digest.Digest ](),
90+ ref : ref ,
91+ index : * index ,
92+ blobDeleteCandidates : set .New [digest.Digest ](),
9393 }
9494 d .Compat = impl .AddCompat (d )
9595 if sys != nil {
@@ -352,24 +352,24 @@ func (d *ociImageDestination) CommitWithOptions(ctx context.Context, options pri
352352 return err
353353 }
354354 // Delete unreferenced blobs (e.g. old signature manifest and its config)
355- if ! d .blobsToDelete .Empty () {
356- count := make (map [digest.Digest ]int )
357- err = d .ref .countBlobsReferencedByIndex (count , & d .index , d .sharedBlobDir )
355+ if ! d .blobDeleteCandidates .Empty () {
356+ blobsUsedInRootIndex := make (map [digest.Digest ]int )
357+ err = d .ref .countBlobsReferencedByIndex (blobsUsedInRootIndex , & d .index , d .sharedBlobDir )
358358 if err != nil {
359359 return fmt .Errorf ("error counting blobs to delete: %w" , err )
360360 }
361361 // Don't delete blobs which are referenced
362362 actualBlobsToDelete := set .New [digest.Digest ]()
363- for dgst := range d .blobsToDelete .All () {
364- if count [dgst ] == 0 {
363+ for dgst := range d .blobDeleteCandidates .All () {
364+ if blobsUsedInRootIndex [dgst ] == 0 {
365365 actualBlobsToDelete .Add (dgst )
366366 }
367367 }
368368 err := d .ref .deleteBlobs (actualBlobsToDelete )
369369 if err != nil {
370370 return fmt .Errorf ("error deleting blobs: %w" , err )
371371 }
372- d .blobsToDelete = set .New [digest.Digest ]()
372+ d .blobDeleteCandidates = set .New [digest.Digest ]()
373373 }
374374 if err := os .WriteFile (d .ref .ociLayoutPath (), layoutBytes , 0644 ); err != nil {
375375 return err
@@ -384,6 +384,7 @@ func (d *ociImageDestination) CommitWithOptions(ctx context.Context, options pri
384384func (d * ociImageDestination ) PutSignaturesWithFormat (ctx context.Context , signatures []signature.Signature , instanceDigest * digest.Digest ) error {
385385 if instanceDigest == nil {
386386 if d .manifestDigest == "" {
387+ // This shouldn’t happen, ImageDestination users are required to call PutManifest before PutSignatures
387388 return errors .New ("unknown manifest digest, can't add signatures" )
388389 }
389390 instanceDigest = & d .manifestDigest
@@ -394,12 +395,11 @@ func (d *ociImageDestination) PutSignaturesWithFormat(ctx context.Context, signa
394395 if sigstoreSig , ok := sig .(signature.Sigstore ); ok {
395396 sigstoreSignatures = append (sigstoreSignatures , sigstoreSig )
396397 } else {
397- return errors .New ("OCI Layout only supports sigstoreSignatures " )
398+ return errors .New ("oci: layout only supports sigstore signatures " )
398399 }
399400 }
400401
401- err := d .putSignaturesToSigstoreAttachment (ctx , sigstoreSignatures , * instanceDigest )
402- if err != nil {
402+ if err := d .putSignaturesToSigstoreAttachment (ctx , sigstoreSignatures , * instanceDigest ); err != nil {
403403 return err
404404 }
405405
@@ -431,7 +431,7 @@ func (d *ociImageDestination) putSignaturesToSigstoreAttachment(ctx context.Cont
431431 d .ref .StringWithinTransport (), err )
432432 }
433433 // The config of the signature manifest will be updated and unreferenced when a new config is created.
434- d .blobsToDelete .Add (signManifest .Config .Digest )
434+ d .blobDeleteCandidates .Add (signManifest .Config .Digest )
435435 }
436436
437437 desc , err := d .getDescriptor (& manifestDigest )
@@ -516,7 +516,7 @@ func (d *ociImageDestination) putSignaturesToSigstoreAttachment(ctx context.Cont
516516 if err != nil {
517517 return fmt .Errorf ("error counting blobs for digest %s: %w" , oldDesc .Digest .String (), err )
518518 }
519- d .blobsToDelete .AddSeq (maps .Keys (referencedBlobs ))
519+ d .blobDeleteCandidates .AddSeq (maps .Keys (referencedBlobs ))
520520 }
521521 return nil
522522}
@@ -553,10 +553,6 @@ func (d *ociImageDestination) putBlobBytesAsOCI(ctx context.Context, contents []
553553 }, nil
554554}
555555
556- func (d * ociImageDestination ) SupportsSignatures (ctx context.Context ) error {
557- return nil
558- }
559-
560556// PutBlobFromLocalFileOption is unused but may receive functionality in the future.
561557type PutBlobFromLocalFileOption struct {}
562558
0 commit comments