@@ -23,6 +23,7 @@ import (
2323 "go.podman.io/image/v5/internal/iolimits"
2424 "go.podman.io/image/v5/internal/private"
2525 "go.podman.io/image/v5/internal/putblobdigest"
26+ "go.podman.io/image/v5/internal/set"
2627 "go.podman.io/image/v5/internal/signature"
2728 "go.podman.io/image/v5/manifest"
2829 "go.podman.io/image/v5/pkg/blobinfocache/none"
@@ -41,6 +42,8 @@ type ociImageDestination struct {
4142 sharedBlobDir string
4243 sys * types.SystemContext
4344 manifestDigest digest.Digest
45+ // blobsToDelete is a set of digests which may be deleted
46+ blobsToDelete * set.Set [digest.Digest ]
4447}
4548
4649// newImageDestination returns an ImageDestination for writing to an existing directory.
@@ -83,9 +86,10 @@ func newImageDestination(sys *types.SystemContext, ref ociReference) (private.Im
8386 }),
8487 NoPutBlobPartialInitialize : stubs .NoPutBlobPartial (ref ),
8588
86- ref : ref ,
87- index : * index ,
88- sys : sys ,
89+ ref : ref ,
90+ index : * index ,
91+ sys : sys ,
92+ blobsToDelete : set .New [digest.Digest ](),
8993 }
9094 d .Compat = impl .AddCompat (d )
9195 if sys != nil {
@@ -320,6 +324,26 @@ func (d *ociImageDestination) CommitWithOptions(ctx context.Context, options pri
320324 if err != nil {
321325 return err
322326 }
327+ // Delete unreferenced blobs (e.g. old signature manifest config)
328+ if ! d .blobsToDelete .Empty () {
329+ count := make (map [digest.Digest ]int )
330+ err = d .ref .countBlobsReferencedByIndex (count , & d .index , d .sharedBlobDir )
331+ if err != nil {
332+ return fmt .Errorf ("error counting blobs to delete: %w" , err )
333+ }
334+ // Don't delete blobs which are referenced
335+ actualBlobsToDelete := set .New [digest.Digest ]()
336+ for dgst := range d .blobsToDelete .All () {
337+ if count [dgst ] == 0 {
338+ actualBlobsToDelete .Add (dgst )
339+ }
340+ }
341+ err := d .ref .deleteBlobs (actualBlobsToDelete )
342+ if err != nil {
343+ return fmt .Errorf ("error deleting blobs: %w" , err )
344+ }
345+ d .blobsToDelete = set .New [digest.Digest ]()
346+ }
323347 if err := os .WriteFile (d .ref .ociLayoutPath (), layoutBytes , 0644 ); err != nil {
324348 return err
325349 }
@@ -379,6 +403,8 @@ func (d *ociImageDestination) putSignaturesToSigstoreAttachment(ctx context.Cont
379403 return fmt .Errorf ("parsing sigstore attachment config %s in %s: %w" , signManifest .Config .Digest .String (),
380404 d .ref .StringWithinTransport (), err )
381405 }
406+ // The config of the signature manifest will be updated and unreferenced when a new config is created.
407+ d .blobsToDelete .Add (signManifest .Config .Digest )
382408 }
383409
384410 desc , err := d .getDescriptor (& manifestDigest )
0 commit comments