Move the tar-split digest value into the TOC

... so that we can uniquely identify partially-pulled layers
by the TOC digest.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač 2024-04-23 00:06:36 +02:00
parent dfb4b1ff87
commit b5413c2bd6
3 changed files with 16 additions and 8 deletions

View File

@ -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()
}

View File

@ -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
}

View File

@ -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