Push the "canFallback" logic from getProperDiffer into the format handlers

We will add more, format-specific, logic to the decision.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač 2024-12-12 22:32:38 +01:00
parent 25b8040272
commit 3c62db3445
1 changed files with 26 additions and 18 deletions

View File

@ -220,7 +220,7 @@ func GetDiffer(ctx context.Context, store storage.Store, blobDigest digest.Diges
// getProperDiffer is an implementation detail of GetDiffer. // getProperDiffer is an implementation detail of GetDiffer.
// It returns a “proper” differ (not a convert_images one) if possible. // It returns a “proper” differ (not a convert_images one) if possible.
// On error, the second parameter is true if a fallback to an alternative (either the makeConverToRaw differ, or a non-partial pull) // On error, the second return value is true if a fallback to an alternative (either the makeConverToRaw differ, or a non-partial pull)
// is permissible. // is permissible.
func getProperDiffer(store storage.Store, blobDigest digest.Digest, blobSize int64, annotations map[string]string, iss ImageSourceSeekable, pullOptions pullOptions) (graphdriver.Differ, bool, error) { func getProperDiffer(store storage.Store, blobDigest digest.Digest, blobSize int64, annotations map[string]string, iss ImageSourceSeekable, pullOptions pullOptions) (graphdriver.Differ, bool, error) {
zstdChunkedTOCDigestString, hasZstdChunkedTOC := annotations[minimal.ManifestChecksumKey] zstdChunkedTOCDigestString, hasZstdChunkedTOC := annotations[minimal.ManifestChecksumKey]
@ -235,12 +235,10 @@ func getProperDiffer(store storage.Store, blobDigest digest.Digest, blobSize int
if err != nil { if err != nil {
return nil, false, err return nil, false, err
} }
differ, err := makeZstdChunkedDiffer(store, blobSize, zstdChunkedTOCDigest, annotations, iss, pullOptions) differ, canFallback, err := makeZstdChunkedDiffer(store, blobSize, zstdChunkedTOCDigest, annotations, iss, pullOptions)
if err != nil { if err != nil {
logrus.Debugf("Could not create zstd:chunked differ for blob %q: %v", blobDigest, err) logrus.Debugf("Could not create zstd:chunked differ for blob %q: %v", blobDigest, err)
// If the error is a bad request to the server, then signal to the caller that it can try a different method. return nil, canFallback, err
var badRequestErr ErrBadRequest
return nil, errors.As(err, &badRequestErr), err
} }
logrus.Debugf("Created zstd:chunked differ for blob %q", blobDigest) logrus.Debugf("Created zstd:chunked differ for blob %q", blobDigest)
return differ, false, nil return differ, false, nil
@ -250,12 +248,10 @@ func getProperDiffer(store storage.Store, blobDigest digest.Digest, blobSize int
if err != nil { if err != nil {
return nil, false, err return nil, false, err
} }
differ, err := makeEstargzChunkedDiffer(store, blobSize, estargzTOCDigest, iss, pullOptions) differ, canFallback, err := makeEstargzChunkedDiffer(store, blobSize, estargzTOCDigest, iss, pullOptions)
if err != nil { if err != nil {
logrus.Debugf("Could not create estargz differ for blob %q: %v", blobDigest, err) logrus.Debugf("Could not create estargz differ for blob %q: %v", blobDigest, err)
// If the error is a bad request to the server, then signal to the caller that it can try a different method. return nil, canFallback, err
var badRequestErr ErrBadRequest
return nil, errors.As(err, &badRequestErr), err
} }
logrus.Debugf("Created eStargz differ for blob %q", blobDigest) logrus.Debugf("Created eStargz differ for blob %q", blobDigest)
return differ, false, nil return differ, false, nil
@ -287,22 +283,28 @@ func makeConvertFromRawDiffer(store storage.Store, blobDigest digest.Digest, blo
}, nil }, nil
} }
func makeZstdChunkedDiffer(store storage.Store, blobSize int64, tocDigest digest.Digest, annotations map[string]string, iss ImageSourceSeekable, pullOptions pullOptions) (*chunkedDiffer, error) { // makeZstdChunkedDiffer sets up a chunkedDiffer for a zstd:chunked layer.
//
// On error, the second return value is true if a fallback to an alternative (either the makeConverToRaw differ, or a non-partial pull)
// is permissible.
func makeZstdChunkedDiffer(store storage.Store, blobSize int64, tocDigest digest.Digest, annotations map[string]string, iss ImageSourceSeekable, pullOptions pullOptions) (*chunkedDiffer, bool, error) {
manifest, toc, tarSplit, tocOffset, err := readZstdChunkedManifest(iss, tocDigest, annotations) manifest, toc, tarSplit, tocOffset, err := readZstdChunkedManifest(iss, tocDigest, annotations)
if err != nil { if err != nil {
return nil, fmt.Errorf("read zstd:chunked manifest: %w", err) // If the error is a bad request to the server, then signal to the caller that it can try a different method.
var badRequestErr ErrBadRequest
return nil, errors.As(err, &badRequestErr), fmt.Errorf("read zstd:chunked manifest: %w", err)
} }
var uncompressedTarSize int64 = -1 var uncompressedTarSize int64 = -1
if tarSplit != nil { if tarSplit != nil {
uncompressedTarSize, err = tarSizeFromTarSplit(tarSplit) uncompressedTarSize, err = tarSizeFromTarSplit(tarSplit)
if err != nil { if err != nil {
return nil, fmt.Errorf("computing size from tar-split: %w", err) return nil, false, fmt.Errorf("computing size from tar-split: %w", err)
} }
} }
layersCache, err := getLayersCache(store) layersCache, err := getLayersCache(store)
if err != nil { if err != nil {
return nil, err return nil, false, err
} }
return &chunkedDiffer{ return &chunkedDiffer{
@ -319,17 +321,23 @@ func makeZstdChunkedDiffer(store storage.Store, blobSize int64, tocDigest digest
stream: iss, stream: iss,
tarSplit: tarSplit, tarSplit: tarSplit,
tocOffset: tocOffset, tocOffset: tocOffset,
}, nil }, false, nil
} }
func makeEstargzChunkedDiffer(store storage.Store, blobSize int64, tocDigest digest.Digest, iss ImageSourceSeekable, pullOptions pullOptions) (*chunkedDiffer, error) { // makeZstdChunkedDiffer sets up a chunkedDiffer for an estargz layer.
//
// On error, the second return value is true if a fallback to an alternative (either the makeConverToRaw differ, or a non-partial pull)
// is permissible.
func makeEstargzChunkedDiffer(store storage.Store, blobSize int64, tocDigest digest.Digest, iss ImageSourceSeekable, pullOptions pullOptions) (*chunkedDiffer, bool, error) {
manifest, tocOffset, err := readEstargzChunkedManifest(iss, blobSize, tocDigest) manifest, tocOffset, err := readEstargzChunkedManifest(iss, blobSize, tocDigest)
if err != nil { if err != nil {
return nil, fmt.Errorf("read zstd:chunked manifest: %w", err) // If the error is a bad request to the server, then signal to the caller that it can try a different method.
var badRequestErr ErrBadRequest
return nil, errors.As(err, &badRequestErr), fmt.Errorf("read zstd:chunked manifest: %w", err)
} }
layersCache, err := getLayersCache(store) layersCache, err := getLayersCache(store)
if err != nil { if err != nil {
return nil, err return nil, false, err
} }
return &chunkedDiffer{ return &chunkedDiffer{
@ -344,7 +352,7 @@ func makeEstargzChunkedDiffer(store storage.Store, blobSize int64, tocDigest dig
pullOptions: pullOptions, pullOptions: pullOptions,
stream: iss, stream: iss,
tocOffset: tocOffset, tocOffset: tocOffset,
}, nil }, false, nil
} }
func makeCopyBuffer() []byte { func makeCopyBuffer() []byte {