From e0ff591cce4f2217e154d9298926c2c0aacff1bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= Date: Mon, 25 Mar 2024 21:57:39 +0100 Subject: [PATCH] Consume SpecificVariantCompressor in CandidateTemplateWithCompression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support consuming zstd:chunked cache entries; return either zstd:chunked or zstd, based on what the user wants. Signed-off-by: Miloslav Trmač --- internal/manifest/manifest.go | 5 --- .../internal/prioritize/prioritize.go | 36 +++++++++++++++---- pkg/blobinfocache/internal/test/test.go | 5 +-- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/internal/manifest/manifest.go b/internal/manifest/manifest.go index ee0ddc772a..3fb52104a6 100644 --- a/internal/manifest/manifest.go +++ b/internal/manifest/manifest.go @@ -205,11 +205,6 @@ type ReuseConditions struct { // (which can be nil to represent uncompressed or unknown) matches reuseConditions. func CandidateCompressionMatchesReuseConditions(c ReuseConditions, candidateCompression *compressiontypes.Algorithm) bool { if c.RequiredCompression != nil { - if c.RequiredCompression.Name() == compressiontypes.ZstdChunkedAlgorithmName { - // HACK: Never match when the caller asks for zstd:chunked, because we don’t record the annotations required to use the chunked blobs. - // The caller must re-compress to build those annotations. - return false - } if candidateCompression == nil || (c.RequiredCompression.Name() != candidateCompression.Name() && c.RequiredCompression.Name() != candidateCompression.BaseVariantName()) { return false diff --git a/pkg/blobinfocache/internal/prioritize/prioritize.go b/pkg/blobinfocache/internal/prioritize/prioritize.go index f581896590..1c481e314f 100644 --- a/pkg/blobinfocache/internal/prioritize/prioritize.go +++ b/pkg/blobinfocache/internal/prioritize/prioritize.go @@ -54,26 +54,50 @@ func CandidateTemplateWithCompression(v2Options *blobinfocache.CandidateLocation logrus.Debugf("Ignoring BlobInfoCache record of digest %q with unknown compression", digest.String()) return nil // Not allowed with CandidateLocations2 default: + requiredCompresssion := "nil" + if v2Options.RequiredCompression != nil { + requiredCompresssion = v2Options.RequiredCompression.Name() + } + + // See if we can use the specific variant, first. + if data.SpecificVariantCompressor != blobinfocache.UnknownCompression { + algo, err := compression.AlgorithmByName(data.SpecificVariantCompressor) + if err != nil { + logrus.Debugf("Not considering unrecognized specific compression variant %q for BlobInfoCache record of digest %q: %v", + data.SpecificVariantCompressor, digest.String(), err) + } else { + if !manifest.CandidateCompressionMatchesReuseConditions(manifest.ReuseConditions{ + PossibleManifestFormats: v2Options.PossibleManifestFormats, + RequiredCompression: v2Options.RequiredCompression, + }, &algo) { + logrus.Debugf("Ignoring specific compression variant %q for BlobInfoCache record of digest %q, it does not match required %s or MIME types %#v", + data.SpecificVariantCompressor, digest.String(), requiredCompresssion, v2Options.PossibleManifestFormats) + } else { + return &blobinfocache.BICReplacementCandidate2{ + Digest: digest, + CompressionOperation: types.Compress, + CompressionAlgorithm: &algo, + CompressionAnnotations: data.SpecificVariantAnnotations, + } + } + } + } + + // Try the base variant. algo, err := compression.AlgorithmByName(data.BaseVariantCompressor) if err != nil { logrus.Debugf("Ignoring BlobInfoCache record of digest %q with unrecognized compression %q: %v", digest.String(), data.BaseVariantCompressor, err) return nil // The BICReplacementCandidate2.CompressionAlgorithm field is required } - if !manifest.CandidateCompressionMatchesReuseConditions(manifest.ReuseConditions{ PossibleManifestFormats: v2Options.PossibleManifestFormats, RequiredCompression: v2Options.RequiredCompression, }, &algo) { - requiredCompresssion := "nil" - if v2Options.RequiredCompression != nil { - requiredCompresssion = v2Options.RequiredCompression.Name() - } logrus.Debugf("Ignoring BlobInfoCache record of digest %q, compression %q does not match required %s or MIME types %#v", digest.String(), data.BaseVariantCompressor, requiredCompresssion, v2Options.PossibleManifestFormats) return nil } - return &blobinfocache.BICReplacementCandidate2{ Digest: digest, CompressionOperation: types.Compress, diff --git a/pkg/blobinfocache/internal/test/test.go b/pkg/blobinfocache/internal/test/test.go index b5cd682bad..cf5da09921 100644 --- a/pkg/blobinfocache/internal/test/test.go +++ b/pkg/blobinfocache/internal/test/test.go @@ -564,8 +564,9 @@ func testGenericCandidateLocations2(t *testing.T, cache blobinfocache.BlobInfoCa CanSubstitute: true, RequiredCompression: &compression.ZstdChunked, }) - // Right now, zstd:chunked requests never match a candidate, see CandidateCompressionMatchesReuseConditions(). - assertCandidatesMatch2(t, scopeName, []candidate{}, res) + assertCandidatesMatch2(t, scopeName, []candidate{ + {d: digestZstdChunked, cn: compressiontypes.ZstdChunkedAlgorithmName, lr: "zstdChunked"}, + }, res) res = cache.CandidateLocations2(transport, scope, digestFilteringUncompressed, blobinfocache.CandidateLocations2Options{ CanSubstitute: true, RequiredCompression: &compression.Zstd,