From b5413c2bd64742a08384300f09616a66231b21d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= Date: Tue, 23 Apr 2024 00:06:36 +0200 Subject: [PATCH] Move the tar-split digest value into the TOC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... so that we can uniquely identify partially-pulled layers by the TOC digest. Signed-off-by: Miloslav Trmač --- pkg/chunked/cache_linux.go | 8 ++++++++ pkg/chunked/compression_linux.go | 4 +--- pkg/chunked/internal/compression.go | 12 +++++++----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/pkg/chunked/cache_linux.go b/pkg/chunked/cache_linux.go index 4cfde5c4f4..34d1b92f4e 100644 --- a/pkg/chunked/cache_linux.go +++ b/pkg/chunked/cache_linux.go @@ -897,6 +897,14 @@ func unmarshalToc(manifest []byte) (*internal.TOC, error) { toc.Entries = append(toc.Entries, m) } + case "tarsplitdigest": // strings.ToLower("tarSplitDigest") + s := iter.ReadString() + d, err := digest.Parse(s) + if err != nil { + return nil, fmt.Errorf("Invalid tarSplitDigest %q: %w", s, err) + } + toc.TarSplitDigest = d + default: iter.Skip() } diff --git a/pkg/chunked/compression_linux.go b/pkg/chunked/compression_linux.go index c1042da1fa..5b2c556725 100644 --- a/pkg/chunked/compression_linux.go +++ b/pkg/chunked/compression_linux.go @@ -147,12 +147,10 @@ func readZstdChunkedManifest(blobStream ImageSourceSeekable, tocDigest digest.Di // The tarSplit… values are valid if tarSplitChunk.Offset > 0 var tarSplitChunk ImageSourceChunk var tarSplitLengthUncompressed uint64 - var tarSplitChecksum string if tarSplitInfoKeyAnnotation, found := annotations[internal.TarSplitInfoKey]; found { if _, err := fmt.Sscanf(tarSplitInfoKeyAnnotation, "%d:%d:%d", &tarSplitChunk.Offset, &tarSplitChunk.Length, &tarSplitLengthUncompressed); err != nil { return nil, nil, nil, 0, err } - tarSplitChecksum = annotations[internal.TarSplitChecksumKey] } if manifestType != internal.ManifestTypeCRFS { @@ -217,7 +215,7 @@ func readZstdChunkedManifest(blobStream ImageSourceSeekable, tocDigest digest.Di return nil, nil, nil, 0, err } - decodedTarSplit, err = decodeAndValidateBlob(tarSplit, tarSplitLengthUncompressed, tarSplitChecksum) + decodedTarSplit, err = decodeAndValidateBlob(tarSplit, tarSplitLengthUncompressed, toc.TarSplitDigest.String()) if err != nil { return nil, nil, nil, 0, err } diff --git a/pkg/chunked/internal/compression.go b/pkg/chunked/internal/compression.go index 52c9ce341a..6cb07a60c1 100644 --- a/pkg/chunked/internal/compression.go +++ b/pkg/chunked/internal/compression.go @@ -18,8 +18,9 @@ import ( ) type TOC struct { - Version int `json:"version"` - Entries []FileMetadata `json:"entries"` + Version int `json:"version"` + Entries []FileMetadata `json:"entries"` + TarSplitDigest digest.Digest `json:"tarSplitDigest,omitempty"` } type FileMetadata struct { @@ -84,7 +85,7 @@ func GetType(t byte) (string, error) { const ( ManifestChecksumKey = "io.github.containers.zstd-chunked.manifest-checksum" ManifestInfoKey = "io.github.containers.zstd-chunked.manifest-position" - TarSplitChecksumKey = "io.github.containers.zstd-chunked.tarsplit-checksum" + TarSplitChecksumKey = "io.github.containers.zstd-chunked.tarsplit-checksum" // Deprecated: Use the TOC.TarSplitDigest field instead, this one is not authenticated by ManifestChecksumKey. TarSplitInfoKey = "io.github.containers.zstd-chunked.tarsplit-position" // ManifestTypeCRFS is a manifest file compatible with the CRFS TOC file. @@ -133,8 +134,9 @@ func WriteZstdChunkedManifest(dest io.Writer, outMetadata map[string]string, off manifestOffset := offset + zstdSkippableFrameHeader toc := TOC{ - Version: 1, - Entries: metadata, + Version: 1, + Entries: metadata, + TarSplitDigest: tarSplitData.Digest, } json := jsoniter.ConfigCompatibleWithStandardLibrary