From 39410b54619bfd13bc19b36b5a19b33f5aeebaca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= Date: Thu, 20 Mar 2025 18:45:23 +0100 Subject: [PATCH] Queue a partially-pulled layer for commit immediately after staging it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't block all other layer commits until all layers are downloaded / staged. Signed-off-by: Miloslav Trmač --- copy/single.go | 1 + internal/private/private.go | 1 + storage/storage_dest.go | 9 ++++++--- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/copy/single.go b/copy/single.go index f7aca838..19d410a6 100644 --- a/copy/single.go +++ b/copy/single.go @@ -812,6 +812,7 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to } uploadedBlob, err := ic.c.dest.PutBlobPartial(ctx, &proxy, srcInfo, private.PutBlobPartialOptions{ Cache: ic.c.blobInfoCache, + EmptyLayer: emptyLayer, LayerIndex: layerIndex, }) if err == nil { diff --git a/internal/private/private.go b/internal/private/private.go index d9466e90..ae0cbdf2 100644 --- a/internal/private/private.go +++ b/internal/private/private.go @@ -118,6 +118,7 @@ type PutBlobOptions struct { // PutBlobPartialOptions are used in PutBlobPartial. type PutBlobPartialOptions struct { Cache blobinfocache.BlobInfoCache2 // Cache to use and/or update. + EmptyLayer bool // True if the blob is an "empty"/"throwaway" layer, and may not necessarily be physically represented. LayerIndex int // A zero-based index of the layer within the image (PutBlobPartial is only called with layer-like blobs, not configs) } diff --git a/storage/storage_dest.go b/storage/storage_dest.go index 827d422a..6d9b8cbf 100644 --- a/storage/storage_dest.go +++ b/storage/storage_dest.go @@ -497,9 +497,12 @@ func (s *storageImageDestination) PutBlobPartial(ctx context.Context, chunkAcces succeeded = true return private.UploadedBlob{ - Digest: blobDigest, - Size: srcInfo.Size, - }, nil + Digest: blobDigest, + Size: srcInfo.Size, + }, s.queueOrCommit(options.LayerIndex, addedLayerInfo{ + digest: blobDigest, + emptyLayer: options.EmptyLayer, + }) } // TryReusingBlobWithOptions checks whether the transport already contains, or can efficiently reuse, a blob, and if so, applies it to the current destination