> go get github.com/containers/image/v5@main
> make vendor

This moves c/image to a commit that includes both the work on main
that we were already vendoring, and the last tagged version 5.27.0.

That should prevent Renovate from proposing downgrades which fail tests:
- https://github.com/containers/skopeo/pull/2065
- https://github.com/containers/skopeo/pull/2066

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač
2023-08-14 20:24:51 +02:00
parent 9c8ed62f91
commit 4ee2946bbc
33 changed files with 1596 additions and 206 deletions

View File

@@ -10,13 +10,18 @@ package sif
import (
"bytes"
"crypto"
"crypto/sha256"
"encoding"
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"hash"
"io"
"strings"
"time"
v1 "github.com/google/go-containerregistry/pkg/v1"
)
// rawDescriptor represents an on-disk object descriptor.
@@ -67,6 +72,40 @@ type sbom struct {
Format SBOMFormat
}
// ociBlob represents the OCI Blob data object descriptor.
type ociBlob struct {
hasher hash.Hash // accumulates hash while writing blob.
digest v1.Hash
}
// newOCIBlobDigest returns a new ociBlob, that accumulates the digest of an OCI blob as it is
// read. The caller should take care to ensure that the entire contents of the blob have been
// written to the returned ociBlob prior to calling MarshalBinary.
func newOCIBlobDigest() *ociBlob {
return &ociBlob{
hasher: sha256.New(),
digest: v1.Hash{
Algorithm: "sha256",
},
}
}
// MarshalBinary encodes ob into binary format.
func (ob *ociBlob) MarshalBinary() ([]byte, error) {
ob.digest.Hex = hex.EncodeToString(ob.hasher.Sum(nil))
return ob.digest.MarshalText()
}
// UnmarshalBinary decodes b into ob.
func (ob *ociBlob) UnmarshalBinary(b []byte) error {
if before, _, ok := bytes.Cut(b, []byte{0x00}); ok {
b = before
}
return ob.digest.UnmarshalText(b)
}
// The binaryMarshaler type is an adapter that allows a type suitable for use with the
// encoding/binary package to be used as an encoding.BinaryMarshaler.
type binaryMarshaler struct{ any }
@@ -295,6 +334,21 @@ func (d Descriptor) SBOMMetadata() (SBOMFormat, error) {
return s.Format, nil
}
// OCIBlobDigest returns the digest for a OCI blob object.
func (d Descriptor) OCIBlobDigest() (v1.Hash, error) {
if got := d.raw.DataType; got != DataOCIRootIndex && got != DataOCIBlob {
return v1.Hash{}, &unexpectedDataTypeError{got, []DataType{DataOCIRootIndex, DataOCIBlob}}
}
var o ociBlob
if err := d.raw.getExtra(&o); err != nil {
return v1.Hash{}, fmt.Errorf("%w", err)
}
return o.digest, nil
}
// GetData returns the data object associated with descriptor d.
func (d Descriptor) GetData() ([]byte, error) {
b := make([]byte, d.raw.Size)

View File

@@ -293,6 +293,15 @@ func NewDescriptorInput(t DataType, r io.Reader, opts ...DescriptorInputOpt) (De
dopts.alignment = 4096
}
// Accumulate hash for OCI blobs as they are written.
if t == DataOCIRootIndex || t == DataOCIBlob {
md := newOCIBlobDigest()
r = io.TeeReader(r, md.hasher)
dopts.md = md
}
for _, opt := range opts {
if err := opt(t, &dopts); err != nil {
return DescriptorInput{}, fmt.Errorf("%w", err)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2021, Sylabs Inc. All rights reserved.
// Copyright (c) 2021-2023, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.
@@ -8,6 +8,8 @@ package sif
import (
"errors"
"fmt"
v1 "github.com/google/go-containerregistry/pkg/v1"
)
// ErrNoObjects is the error returned when an image contains no data objects.
@@ -92,6 +94,16 @@ func WithPartitionType(pt PartType) DescriptorSelectorFunc {
}
}
// WithOCIBlobDigest selects descriptors that contain a OCI blob with the specified digest.
func WithOCIBlobDigest(digest v1.Hash) DescriptorSelectorFunc {
return func(d Descriptor) (bool, error) {
if h, err := d.OCIBlobDigest(); err == nil {
return h.String() == digest.String(), nil
}
return false, nil
}
}
// descriptorFromRaw populates a Descriptor from rd.
func (f *FileImage) descriptorFromRaw(rd *rawDescriptor) Descriptor {
return Descriptor{

View File

@@ -133,6 +133,8 @@ const (
DataGeneric // generic / raw data
DataCryptoMessage // cryptographic message data object
DataSBOM // software bill of materials
DataOCIRootIndex // root OCI index
DataOCIBlob // oci blob data object
)
// String returns a human-readable representation of t.
@@ -156,6 +158,10 @@ func (t DataType) String() string {
return "Cryptographic Message"
case DataSBOM:
return "SBOM"
case DataOCIRootIndex:
return "OCI.RootIndex"
case DataOCIBlob:
return "OCI.Blob"
}
return "Unknown"
}