From c9260b973a0d3ac5ed37284a587ef1f5fe5169f2 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Tue, 29 Apr 2025 21:54:01 +0200 Subject: [PATCH] chunked: rename GetDiffer to NewDiffer it is an explicit API breaking change, so that cannot be used by old users (e.g. an older containers/image version) that are not ported to support the new semantic that only one ApplyDiffWithDiffer call is supported for one differ object. Signed-off-by: Giuseppe Scrivano --- cmd/containers-storage/diff.go | 2 +- pkg/chunked/storage_linux.go | 13 +++++++------ pkg/chunked/storage_unsupported.go | 5 +++-- store.go | 2 ++ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/cmd/containers-storage/diff.go b/cmd/containers-storage/diff.go index 30d3399c8..140163006 100644 --- a/cmd/containers-storage/diff.go +++ b/cmd/containers-storage/diff.go @@ -176,7 +176,7 @@ func applyDiffUsingStagingDirectory(flags *mflag.FlagSet, action string, m stora file: tar, } - differ, err := chunked.GetDiffer(context.Background(), m, digesterCompressed.Digest(), size, metadata, &fetcher) + differ, err := chunked.NewDiffer(context.Background(), m, digesterCompressed.Digest(), size, metadata, &fetcher) if err != nil { return 1, err } diff --git a/pkg/chunked/storage_linux.go b/pkg/chunked/storage_linux.go index 64631e786..0ed449a0b 100644 --- a/pkg/chunked/storage_linux.go +++ b/pkg/chunked/storage_linux.go @@ -80,7 +80,7 @@ type chunkedDiffer struct { convertToZstdChunked bool // Chunked metadata - // This is usually set in GetDiffer, but if convertToZstdChunked, it is only computed in chunkedDiffer.ApplyDiff + // This is usually set in NewDiffer, but if convertToZstdChunked, it is only computed in chunkedDiffer.ApplyDiff // ========== // tocDigest is the digest of the TOC document when the layer // is partially pulled, or "" if not relevant to consumers. @@ -95,7 +95,7 @@ type chunkedDiffer struct { skipValidation bool // Long-term caches - // This is set in GetDiffer, when the caller must not hold any storage locks, and later consumed in .ApplyDiff() + // This is set in NewDiffer, when the caller must not hold any storage locks, and later consumed in .ApplyDiff() // ========== layersCache *layersCache copyBuffer []byte @@ -200,10 +200,11 @@ func (c *chunkedDiffer) Close() error { return nil } -// GetDiffer returns a differ than can be used with [Store.PrepareStagedLayer]. +// NewDiffer returns a differ than can be used with [Store.PrepareStagedLayer]. // If it returns an error that matches ErrFallbackToOrdinaryLayerDownload, the caller can // retry the operation with a different method. -func GetDiffer(ctx context.Context, store storage.Store, blobDigest digest.Digest, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (graphdriver.Differ, error) { +// The caller must call Close() on the returned Differ. +func NewDiffer(ctx context.Context, store storage.Store, blobDigest digest.Digest, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (graphdriver.Differ, error) { pullOptions := parsePullOptions(store) if !pullOptions.enablePartialImages { @@ -266,7 +267,7 @@ func (e errFallbackCanConvert) Unwrap() error { return e.err } -// getProperDiffer is an implementation detail of GetDiffer. +// getProperDiffer is an implementation detail of NewDiffer. // It returns a “proper” differ (not a convert_images one) if possible. // May return an error matching ErrFallbackToOrdinaryLayerDownload if a fallback to an alternative // (either makeConvertFromRawDiffer, or a non-partial pull) is permissible. @@ -1873,7 +1874,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions, diff } output.UncompressedDigest = digester.Digest() default: - // We are checking for this earlier in GetDiffer, so this should not be reachable. + // We are checking for this earlier in NewDiffer, so this should not be reachable. return output, fmt.Errorf(`internal error: layer's UncompressedDigest is unknown and "insecure_allow_unpredictable_image_contents" is not set`) } } diff --git a/pkg/chunked/storage_unsupported.go b/pkg/chunked/storage_unsupported.go index daed1359e..7e73a145b 100644 --- a/pkg/chunked/storage_unsupported.go +++ b/pkg/chunked/storage_unsupported.go @@ -11,7 +11,8 @@ import ( digest "github.com/opencontainers/go-digest" ) -// GetDiffer returns a differ than can be used with [Store.PrepareStagedLayer]. -func GetDiffer(ctx context.Context, store storage.Store, blobDigest digest.Digest, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (graphdriver.Differ, error) { +// NewDiffer returns a differ than can be used with [Store.PrepareStagedLayer]. +// The caller must call Close() on the returned Differ. +func NewDiffer(ctx context.Context, store storage.Store, blobDigest digest.Digest, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (graphdriver.Differ, error) { return nil, newErrFallbackToOrdinaryLayerDownload(errors.New("format not supported on this system")) } diff --git a/store.go b/store.go index af1da7a6f..1c5973623 100644 --- a/store.go +++ b/store.go @@ -365,6 +365,8 @@ type Store interface { // PrepareStagedLayer applies a diff to a layer. // It is the caller responsibility to clean the staging directory if it is not // successfully applied with ApplyStagedLayer. + // The caller must ensure [Store.ApplyStagedLayer] or [Store.CleanupStagedLayer] is called eventually + // with the returned [drivers.DriverWithDifferOutput] object. PrepareStagedLayer(options *drivers.ApplyDiffWithDifferOpts, differ drivers.Differ) (*drivers.DriverWithDifferOutput, error) // ApplyStagedLayer combines the functions of creating a layer and using the staging