go.mod: update to latest images@v0.115.0
This commit is contained in:
parent
7e87d1e124
commit
85e4efe966
60 changed files with 740 additions and 509 deletions
53
vendor/github.com/containers/image/v5/copy/copy.go
generated
vendored
53
vendor/github.com/containers/image/v5/copy/copy.go
generated
vendored
|
|
@ -137,6 +137,17 @@ type Options struct {
|
|||
// DestinationCtx.CompressionFormat is used exclusively, and blobs of other
|
||||
// compression algorithms are not reused.
|
||||
ForceCompressionFormat bool
|
||||
|
||||
// ReportResolvedReference, if set, asks the destination transport to store
|
||||
// a “resolved” (more detailed) reference to the created image
|
||||
// into the value this option points to.
|
||||
// What “resolved” means is transport-specific.
|
||||
// Most transports don’t support this, and cause the value to be set to nil.
|
||||
//
|
||||
// For the containers-storage: transport, the reference contains an image ID,
|
||||
// so that storage.ResolveReference returns exactly the created image.
|
||||
// WARNING: It is unspecified whether the reference also contains a reference.Named element.
|
||||
ReportResolvedReference *types.ImageReference
|
||||
}
|
||||
|
||||
// OptionCompressionVariant allows to supply information about
|
||||
|
|
@ -193,35 +204,33 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef,
|
|||
reportWriter = options.ReportWriter
|
||||
}
|
||||
|
||||
// safeClose amends retErr with an error from c.Close(), if any.
|
||||
safeClose := func(name string, c io.Closer) {
|
||||
err := c.Close()
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
// Do not use %w for err as we don't want it to be unwrapped by callers.
|
||||
if retErr != nil {
|
||||
retErr = fmt.Errorf(" (%s: %s): %w", name, err.Error(), retErr)
|
||||
} else {
|
||||
retErr = fmt.Errorf(" (%s: %s)", name, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
publicDest, err := destRef.NewImageDestination(ctx, options.DestinationCtx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("initializing destination %s: %w", transports.ImageName(destRef), err)
|
||||
}
|
||||
dest := imagedestination.FromPublic(publicDest)
|
||||
defer func() {
|
||||
if err := dest.Close(); err != nil {
|
||||
if retErr != nil {
|
||||
retErr = fmt.Errorf(" (dest: %v): %w", err, retErr)
|
||||
} else {
|
||||
retErr = fmt.Errorf(" (dest: %v)", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
defer safeClose("dest", dest)
|
||||
|
||||
publicRawSource, err := srcRef.NewImageSource(ctx, options.SourceCtx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("initializing source %s: %w", transports.ImageName(srcRef), err)
|
||||
}
|
||||
rawSource := imagesource.FromPublic(publicRawSource)
|
||||
defer func() {
|
||||
if err := rawSource.Close(); err != nil {
|
||||
if retErr != nil {
|
||||
retErr = fmt.Errorf(" (src: %v): %w", err, retErr)
|
||||
} else {
|
||||
retErr = fmt.Errorf(" (src: %v)", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
defer safeClose("src", rawSource)
|
||||
|
||||
// If reportWriter is not a TTY (e.g., when piping to a file), do not
|
||||
// print the progress bars to avoid long and hard to parse output.
|
||||
|
|
@ -339,7 +348,13 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef,
|
|||
}
|
||||
}
|
||||
|
||||
if err := c.dest.Commit(ctx, c.unparsedToplevel); err != nil {
|
||||
if options.ReportResolvedReference != nil {
|
||||
*options.ReportResolvedReference = nil // The default outcome, if not specifically supported by the transport.
|
||||
}
|
||||
if err := c.dest.CommitWithOptions(ctx, private.CommitOptions{
|
||||
UnparsedToplevel: c.unparsedToplevel,
|
||||
ReportResolvedReference: options.ReportResolvedReference,
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("committing the finished image: %w", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
13
vendor/github.com/containers/image/v5/copy/progress_bars.go
generated
vendored
13
vendor/github.com/containers/image/v5/copy/progress_bars.go
generated
vendored
|
|
@ -24,13 +24,18 @@ func (c *copier) newProgressPool() *mpb.Progress {
|
|||
|
||||
// customPartialBlobDecorFunc implements mpb.DecorFunc for the partial blobs retrieval progress bar
|
||||
func customPartialBlobDecorFunc(s decor.Statistics) string {
|
||||
current := decor.SizeB1024(s.Current)
|
||||
total := decor.SizeB1024(s.Total)
|
||||
refill := decor.SizeB1024(s.Refill)
|
||||
if s.Total == 0 {
|
||||
pairFmt := "%.1f / %.1f (skipped: %.1f)"
|
||||
return fmt.Sprintf(pairFmt, decor.SizeB1024(s.Current), decor.SizeB1024(s.Total), decor.SizeB1024(s.Refill))
|
||||
return fmt.Sprintf("%.1f / %.1f (skipped: %.1f)", current, total, refill)
|
||||
}
|
||||
// If we didn't do a partial fetch then let's not output a distracting ("skipped: 0.0b = 0.00%")
|
||||
if s.Refill == 0 {
|
||||
return fmt.Sprintf("%.1f / %.1f", current, total)
|
||||
}
|
||||
pairFmt := "%.1f / %.1f (skipped: %.1f = %.2f%%)"
|
||||
percentage := 100.0 * float64(s.Refill) / float64(s.Total)
|
||||
return fmt.Sprintf(pairFmt, decor.SizeB1024(s.Current), decor.SizeB1024(s.Total), decor.SizeB1024(s.Refill), percentage)
|
||||
return fmt.Sprintf("%.1f / %.1f (skipped: %.1f = %.2f%%)", current, total, refill, percentage)
|
||||
}
|
||||
|
||||
// progressBar wraps a *mpb.Bar, allowing us to add extra state and methods.
|
||||
|
|
|
|||
2
vendor/github.com/containers/image/v5/copy/sign.go
generated
vendored
2
vendor/github.com/containers/image/v5/copy/sign.go
generated
vendored
|
|
@ -106,7 +106,7 @@ func (c *copier) createSignatures(ctx context.Context, manifest []byte, identity
|
|||
if len(c.signers) == 1 {
|
||||
return nil, fmt.Errorf("creating signature: %w", err)
|
||||
} else {
|
||||
return nil, fmt.Errorf("creating signature %d: %w", signerIndex, err)
|
||||
return nil, fmt.Errorf("creating signature %d: %w", signerIndex+1, err)
|
||||
}
|
||||
}
|
||||
res = append(res, newSig)
|
||||
|
|
|
|||
16
vendor/github.com/containers/image/v5/copy/single.go
generated
vendored
16
vendor/github.com/containers/image/v5/copy/single.go
generated
vendored
|
|
@ -323,10 +323,7 @@ func checkImageDestinationForCurrentRuntime(ctx context.Context, sys *types.Syst
|
|||
if err != nil {
|
||||
return fmt.Errorf("parsing image configuration: %w", err)
|
||||
}
|
||||
wantedPlatforms, err := platform.WantedPlatforms(sys)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting current platform information %#v: %w", sys, err)
|
||||
}
|
||||
wantedPlatforms := platform.WantedPlatforms(sys)
|
||||
|
||||
options := newOrderedSet()
|
||||
match := false
|
||||
|
|
@ -822,11 +819,16 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to
|
|||
logrus.Debugf("Retrieved partial blob %v", srcInfo.Digest)
|
||||
return true, updatedBlobInfoFromUpload(srcInfo, uploadedBlob), nil
|
||||
}
|
||||
logrus.Debugf("Failed to retrieve partial blob: %v", err)
|
||||
return false, types.BlobInfo{}, nil
|
||||
// On a "partial content not available" error, ignore it and retrieve the whole layer.
|
||||
var perr private.ErrFallbackToOrdinaryLayerDownload
|
||||
if errors.As(err, &perr) {
|
||||
logrus.Debugf("Failed to retrieve partial blob: %v", err)
|
||||
return false, types.BlobInfo{}, nil
|
||||
}
|
||||
return false, types.BlobInfo{}, err
|
||||
}()
|
||||
if err != nil {
|
||||
return types.BlobInfo{}, "", err
|
||||
return types.BlobInfo{}, "", fmt.Errorf("partial pull of blob %s: %w", srcInfo.Digest, err)
|
||||
}
|
||||
if reused {
|
||||
return blobInfo, cachedDiffID, nil
|
||||
|
|
|
|||
11
vendor/github.com/containers/image/v5/directory/directory_dest.go
generated
vendored
11
vendor/github.com/containers/image/v5/directory/directory_dest.go
generated
vendored
|
|
@ -251,14 +251,11 @@ func (d *dirImageDestination) PutSignaturesWithFormat(ctx context.Context, signa
|
|||
return nil
|
||||
}
|
||||
|
||||
// Commit marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list
|
||||
// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the
|
||||
// original manifest list digest, if desired.
|
||||
// CommitWithOptions marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before Commit() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *dirImageDestination) Commit(context.Context, types.UnparsedImage) error {
|
||||
// - Uploaded data MAY be visible to others before CommitWithOptions() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without CommitWithOptions() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *dirImageDestination) CommitWithOptions(ctx context.Context, options private.CommitOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
26
vendor/github.com/containers/image/v5/docker/archive/dest.go
generated
vendored
26
vendor/github.com/containers/image/v5/docker/archive/dest.go
generated
vendored
|
|
@ -34,16 +34,17 @@ func newImageDestination(sys *types.SystemContext, ref archiveReference) (privat
|
|||
writer = w
|
||||
closeWriter = true
|
||||
}
|
||||
tarDest := tarfile.NewDestination(sys, writer.archive, ref.Transport().Name(), ref.ref)
|
||||
if sys != nil && sys.DockerArchiveAdditionalTags != nil {
|
||||
tarDest.AddRepoTags(sys.DockerArchiveAdditionalTags)
|
||||
}
|
||||
return &archiveImageDestination{
|
||||
Destination: tarDest,
|
||||
d := &archiveImageDestination{
|
||||
ref: ref,
|
||||
writer: writer,
|
||||
closeWriter: closeWriter,
|
||||
}, nil
|
||||
}
|
||||
tarDest := tarfile.NewDestination(sys, writer.archive, ref.Transport().Name(), ref.ref, d.CommitWithOptions)
|
||||
if sys != nil && sys.DockerArchiveAdditionalTags != nil {
|
||||
tarDest.AddRepoTags(sys.DockerArchiveAdditionalTags)
|
||||
}
|
||||
d.Destination = tarDest
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// Reference returns the reference used to set up this destination. Note that this should directly correspond to user's intent,
|
||||
|
|
@ -60,14 +61,11 @@ func (d *archiveImageDestination) Close() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Commit marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list
|
||||
// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the
|
||||
// original manifest list digest, if desired.
|
||||
// CommitWithOptions marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before Commit() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *archiveImageDestination) Commit(ctx context.Context, unparsedToplevel types.UnparsedImage) error {
|
||||
// - Uploaded data MAY be visible to others before CommitWithOptions() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without CommitWithOptions() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *archiveImageDestination) CommitWithOptions(ctx context.Context, options private.CommitOptions) error {
|
||||
d.writer.imageCommitted()
|
||||
if d.closeWriter {
|
||||
// We could do this only in .Close(), but failures in .Close() are much more likely to be
|
||||
|
|
|
|||
6
vendor/github.com/containers/image/v5/docker/body_reader.go
generated
vendored
6
vendor/github.com/containers/image/v5/docker/body_reader.go
generated
vendored
|
|
@ -6,7 +6,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"math/rand"
|
||||
"math/rand/v2"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
|
@ -158,7 +158,7 @@ func (br *bodyReader) Read(p []byte) (int, error) {
|
|||
logrus.Debugf("Error closing blob body: %v", err) // … and ignore err otherwise
|
||||
}
|
||||
br.body = nil
|
||||
time.Sleep(1*time.Second + time.Duration(rand.Intn(100_000))*time.Microsecond) // Some jitter so that a failure blip doesn’t cause a deterministic stampede
|
||||
time.Sleep(1*time.Second + rand.N(100_000*time.Microsecond)) // Some jitter so that a failure blip doesn’t cause a deterministic stampede
|
||||
|
||||
headers := map[string][]string{
|
||||
"Range": {fmt.Sprintf("bytes=%d-", br.offset)},
|
||||
|
|
@ -197,7 +197,7 @@ func (br *bodyReader) Read(p []byte) (int, error) {
|
|||
consumedBody = true
|
||||
br.body = res.Body
|
||||
br.lastRetryOffset = br.offset
|
||||
br.lastRetryTime = time.Time{}
|
||||
br.lastRetryTime = time.Now()
|
||||
return n, nil
|
||||
|
||||
default:
|
||||
|
|
|
|||
2
vendor/github.com/containers/image/v5/docker/daemon/client.go
generated
vendored
2
vendor/github.com/containers/image/v5/docker/daemon/client.go
generated
vendored
|
|
@ -80,6 +80,7 @@ func tlsConfig(sys *types.SystemContext) (*http.Client, error) {
|
|||
|
||||
return &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSClientConfig: tlsc,
|
||||
},
|
||||
CheckRedirect: dockerclient.CheckRedirect,
|
||||
|
|
@ -89,6 +90,7 @@ func tlsConfig(sys *types.SystemContext) (*http.Client, error) {
|
|||
func httpConfig() *http.Client {
|
||||
return &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSClientConfig: nil,
|
||||
},
|
||||
CheckRedirect: dockerclient.CheckRedirect,
|
||||
|
|
|
|||
20
vendor/github.com/containers/image/v5/docker/daemon/daemon_dest.go
generated
vendored
20
vendor/github.com/containers/image/v5/docker/daemon/daemon_dest.go
generated
vendored
|
|
@ -56,16 +56,17 @@ func newImageDestination(ctx context.Context, sys *types.SystemContext, ref daem
|
|||
goroutineContext, goroutineCancel := context.WithCancel(ctx)
|
||||
go imageLoadGoroutine(goroutineContext, c, reader, statusChannel)
|
||||
|
||||
return &daemonImageDestination{
|
||||
d := &daemonImageDestination{
|
||||
ref: ref,
|
||||
mustMatchRuntimeOS: mustMatchRuntimeOS,
|
||||
Destination: tarfile.NewDestination(sys, archive, ref.Transport().Name(), namedTaggedRef),
|
||||
archive: archive,
|
||||
goroutineCancel: goroutineCancel,
|
||||
statusChannel: statusChannel,
|
||||
writer: writer,
|
||||
committed: false,
|
||||
}, nil
|
||||
}
|
||||
d.Destination = tarfile.NewDestination(sys, archive, ref.Transport().Name(), namedTaggedRef, d.CommitWithOptions)
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// imageLoadGoroutine accepts tar stream on reader, sends it to c, and reports error or success by writing to statusChannel
|
||||
|
|
@ -146,7 +147,7 @@ func (d *daemonImageDestination) Close() error {
|
|||
// immediately, and hopefully, through terminating the sending which uses "Transfer-Encoding: chunked"" without sending
|
||||
// the terminating zero-length chunk, prevent the docker daemon from processing the tar stream at all.
|
||||
// Whether that works or not, closing the PipeWriter seems desirable in any case.
|
||||
if err := d.writer.CloseWithError(errors.New("Aborting upload, daemonImageDestination closed without a previous .Commit()")); err != nil {
|
||||
if err := d.writer.CloseWithError(errors.New("Aborting upload, daemonImageDestination closed without a previous .CommitWithOptions()")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -159,14 +160,11 @@ func (d *daemonImageDestination) Reference() types.ImageReference {
|
|||
return d.ref
|
||||
}
|
||||
|
||||
// Commit marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list
|
||||
// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the
|
||||
// original manifest list digest, if desired.
|
||||
// CommitWithOptions marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before Commit() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *daemonImageDestination) Commit(ctx context.Context, unparsedToplevel types.UnparsedImage) error {
|
||||
// - Uploaded data MAY be visible to others before CommitWithOptions() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without CommitWithOptions() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *daemonImageDestination) CommitWithOptions(ctx context.Context, options private.CommitOptions) error {
|
||||
logrus.Debugf("docker-daemon: Closing tar stream")
|
||||
if err := d.archive.Close(); err != nil {
|
||||
return err
|
||||
|
|
|
|||
29
vendor/github.com/containers/image/v5/docker/docker_client.go
generated
vendored
29
vendor/github.com/containers/image/v5/docker/docker_client.go
generated
vendored
|
|
@ -42,7 +42,6 @@ const (
|
|||
dockerRegistry = "registry-1.docker.io"
|
||||
|
||||
resolvedPingV2URL = "%s://%s/v2/"
|
||||
resolvedPingV1URL = "%s://%s/v1/_ping"
|
||||
tagsPath = "/v2/%s/tags/list"
|
||||
manifestPath = "/v2/%s/manifests/%s"
|
||||
blobsPath = "/v2/%s/blobs/%s"
|
||||
|
|
@ -936,34 +935,6 @@ func (c *dockerClient) detectPropertiesHelper(ctx context.Context) error {
|
|||
}
|
||||
if err != nil {
|
||||
err = fmt.Errorf("pinging container registry %s: %w", c.registry, err)
|
||||
if c.sys != nil && c.sys.DockerDisableV1Ping {
|
||||
return err
|
||||
}
|
||||
// best effort to understand if we're talking to a V1 registry
|
||||
pingV1 := func(scheme string) bool {
|
||||
pingURL, err := url.Parse(fmt.Sprintf(resolvedPingV1URL, scheme, c.registry))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
resp, err := c.makeRequestToResolvedURL(ctx, http.MethodGet, pingURL, nil, nil, -1, noAuth, nil)
|
||||
if err != nil {
|
||||
logrus.Debugf("Ping %s err %s (%#v)", pingURL.Redacted(), err.Error(), err)
|
||||
return false
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
logrus.Debugf("Ping %s status %d", pingURL.Redacted(), resp.StatusCode)
|
||||
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusUnauthorized {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
isV1 := pingV1("https")
|
||||
if !isV1 && c.tlsClientConfig.InsecureSkipVerify {
|
||||
isV1 = pingV1("http")
|
||||
}
|
||||
if isV1 {
|
||||
err = ErrV1NotSupported
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
6
vendor/github.com/containers/image/v5/docker/docker_image.go
generated
vendored
6
vendor/github.com/containers/image/v5/docker/docker_image.go
generated
vendored
|
|
@ -91,6 +91,12 @@ func GetRepositoryTags(ctx context.Context, sys *types.SystemContext, ref types.
|
|||
}
|
||||
for _, tag := range tagsHolder.Tags {
|
||||
if _, err := reference.WithTag(dr.ref, tag); err != nil { // Ensure the tag does not contain unexpected values
|
||||
// Per https://github.com/containers/skopeo/issues/2409 , Sonatype Nexus 3.58, contrary
|
||||
// to the spec, may include JSON null values in the list; and Go silently parses them as "".
|
||||
if tag == "" {
|
||||
logrus.Debugf("Ignoring invalid empty tag")
|
||||
continue
|
||||
}
|
||||
// Per https://github.com/containers/skopeo/issues/2346 , unknown versions of JFrog Artifactory,
|
||||
// contrary to the tag format specified in
|
||||
// https://github.com/opencontainers/distribution-spec/blob/8a871c8234977df058f1a14e299fe0a673853da2/spec.md?plain=1#L160 ,
|
||||
|
|
|
|||
11
vendor/github.com/containers/image/v5/docker/docker_image_dest.go
generated
vendored
11
vendor/github.com/containers/image/v5/docker/docker_image_dest.go
generated
vendored
|
|
@ -923,13 +923,10 @@ func (d *dockerImageDestination) putSignaturesToAPIExtension(ctx context.Context
|
|||
return nil
|
||||
}
|
||||
|
||||
// Commit marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list
|
||||
// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the
|
||||
// original manifest list digest, if desired.
|
||||
// CommitWithOptions marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before Commit() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *dockerImageDestination) Commit(context.Context, types.UnparsedImage) error {
|
||||
// - Uploaded data MAY be visible to others before CommitWithOptions() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without CommitWithOptions() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *dockerImageDestination) CommitWithOptions(ctx context.Context, options private.CommitOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
73
vendor/github.com/containers/image/v5/docker/docker_image_src.go
generated
vendored
73
vendor/github.com/containers/image/v5/docker/docker_image_src.go
generated
vendored
|
|
@ -116,10 +116,10 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref dockerRef
|
|||
// Don’t just build a string, try to preserve the typed error.
|
||||
primary := &attempts[len(attempts)-1]
|
||||
extras := []string{}
|
||||
for i := 0; i < len(attempts)-1; i++ {
|
||||
for _, attempt := range attempts[:len(attempts)-1] {
|
||||
// This is difficult to fit into a single-line string, when the error can contain arbitrary strings including any metacharacters we decide to use.
|
||||
// The paired [] at least have some chance of being unambiguous.
|
||||
extras = append(extras, fmt.Sprintf("[%s: %v]", attempts[i].ref.String(), attempts[i].err))
|
||||
extras = append(extras, fmt.Sprintf("[%s: %v]", attempt.ref.String(), attempt.err))
|
||||
}
|
||||
return nil, fmt.Errorf("(Mirrors also failed: %s): %s: %w", strings.Join(extras, "\n"), primary.ref.String(), primary.err)
|
||||
}
|
||||
|
|
@ -464,26 +464,20 @@ func (s *dockerImageSource) GetSignaturesWithFormat(ctx context.Context, instanc
|
|||
var res []signature.Signature
|
||||
switch {
|
||||
case s.c.supportsSignatures:
|
||||
sigs, err := s.getSignaturesFromAPIExtension(ctx, instanceDigest)
|
||||
if err != nil {
|
||||
if err := s.appendSignaturesFromAPIExtension(ctx, &res, instanceDigest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(res, sigs...)
|
||||
case s.c.signatureBase != nil:
|
||||
sigs, err := s.getSignaturesFromLookaside(ctx, instanceDigest)
|
||||
if err != nil {
|
||||
if err := s.appendSignaturesFromLookaside(ctx, &res, instanceDigest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(res, sigs...)
|
||||
default:
|
||||
return nil, errors.New("Internal error: X-Registry-Supports-Signatures extension not supported, and lookaside should not be empty configuration")
|
||||
}
|
||||
|
||||
sigstoreSigs, err := s.getSignaturesFromSigstoreAttachments(ctx, instanceDigest)
|
||||
if err != nil {
|
||||
if err := s.appendSignaturesFromSigstoreAttachments(ctx, &res, instanceDigest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(res, sigstoreSigs...)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
|
|
@ -505,35 +499,35 @@ func (s *dockerImageSource) manifestDigest(ctx context.Context, instanceDigest *
|
|||
return manifest.Digest(s.cachedManifest)
|
||||
}
|
||||
|
||||
// getSignaturesFromLookaside implements GetSignaturesWithFormat() from the lookaside location configured in s.c.signatureBase,
|
||||
// which is not nil.
|
||||
func (s *dockerImageSource) getSignaturesFromLookaside(ctx context.Context, instanceDigest *digest.Digest) ([]signature.Signature, error) {
|
||||
// appendSignaturesFromLookaside implements GetSignaturesWithFormat() from the lookaside location configured in s.c.signatureBase,
|
||||
// which is not nil, storing the signatures to *dest.
|
||||
// On error, the contents of *dest are undefined.
|
||||
func (s *dockerImageSource) appendSignaturesFromLookaside(ctx context.Context, dest *[]signature.Signature, instanceDigest *digest.Digest) error {
|
||||
manifestDigest, err := s.manifestDigest(ctx, instanceDigest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
// NOTE: Keep this in sync with docs/signature-protocols.md!
|
||||
signatures := []signature.Signature{}
|
||||
for i := 0; ; i++ {
|
||||
if i >= maxLookasideSignatures {
|
||||
return nil, fmt.Errorf("server provided %d signatures, assuming that's unreasonable and a server error", maxLookasideSignatures)
|
||||
return fmt.Errorf("server provided %d signatures, assuming that's unreasonable and a server error", maxLookasideSignatures)
|
||||
}
|
||||
|
||||
sigURL, err := lookasideStorageURL(s.c.signatureBase, manifestDigest, i)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
signature, missing, err := s.getOneSignature(ctx, sigURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if missing {
|
||||
break
|
||||
}
|
||||
signatures = append(signatures, signature)
|
||||
*dest = append(*dest, signature)
|
||||
}
|
||||
return signatures, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// getOneSignature downloads one signature from sigURL, and returns (signature, false, nil)
|
||||
|
|
@ -596,48 +590,51 @@ func (s *dockerImageSource) getOneSignature(ctx context.Context, sigURL *url.URL
|
|||
}
|
||||
}
|
||||
|
||||
// getSignaturesFromAPIExtension implements GetSignaturesWithFormat() using the X-Registry-Supports-Signatures API extension.
|
||||
func (s *dockerImageSource) getSignaturesFromAPIExtension(ctx context.Context, instanceDigest *digest.Digest) ([]signature.Signature, error) {
|
||||
// appendSignaturesFromAPIExtension implements GetSignaturesWithFormat() using the X-Registry-Supports-Signatures API extension,
|
||||
// storing the signatures to *dest.
|
||||
// On error, the contents of *dest are undefined.
|
||||
func (s *dockerImageSource) appendSignaturesFromAPIExtension(ctx context.Context, dest *[]signature.Signature, instanceDigest *digest.Digest) error {
|
||||
manifestDigest, err := s.manifestDigest(ctx, instanceDigest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
parsedBody, err := s.c.getExtensionsSignatures(ctx, s.physicalRef, manifestDigest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
var sigs []signature.Signature
|
||||
for _, sig := range parsedBody.Signatures {
|
||||
if sig.Version == extensionSignatureSchemaVersion && sig.Type == extensionSignatureTypeAtomic {
|
||||
sigs = append(sigs, signature.SimpleSigningFromBlob(sig.Content))
|
||||
*dest = append(*dest, signature.SimpleSigningFromBlob(sig.Content))
|
||||
}
|
||||
}
|
||||
return sigs, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *dockerImageSource) getSignaturesFromSigstoreAttachments(ctx context.Context, instanceDigest *digest.Digest) ([]signature.Signature, error) {
|
||||
// appendSignaturesFromSigstoreAttachments implements GetSignaturesWithFormat() using the sigstore tag convention,
|
||||
// storing the signatures to *dest.
|
||||
// On error, the contents of *dest are undefined.
|
||||
func (s *dockerImageSource) appendSignaturesFromSigstoreAttachments(ctx context.Context, dest *[]signature.Signature, instanceDigest *digest.Digest) error {
|
||||
if !s.c.useSigstoreAttachments {
|
||||
logrus.Debugf("Not looking for sigstore attachments: disabled by configuration")
|
||||
return nil, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
manifestDigest, err := s.manifestDigest(ctx, instanceDigest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
ociManifest, err := s.c.getSigstoreAttachmentManifest(ctx, s.physicalRef, manifestDigest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if ociManifest == nil {
|
||||
return nil, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
logrus.Debugf("Found a sigstore attachment manifest with %d layers", len(ociManifest.Layers))
|
||||
res := []signature.Signature{}
|
||||
for layerIndex, layer := range ociManifest.Layers {
|
||||
// Note that this copies all kinds of attachments: attestations, and whatever else is there,
|
||||
// not just signatures. We leave the signature consumers to decide based on the MIME type.
|
||||
|
|
@ -648,11 +645,11 @@ func (s *dockerImageSource) getSignaturesFromSigstoreAttachments(ctx context.Con
|
|||
payload, err := s.c.getOCIDescriptorContents(ctx, s.physicalRef, layer, iolimits.MaxSignatureBodySize,
|
||||
none.NoCache)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
res = append(res, signature.SigstoreFromComponents(layer.MediaType, payload, layer.Annotations))
|
||||
*dest = append(*dest, signature.SigstoreFromComponents(layer.MediaType, payload, layer.Annotations))
|
||||
}
|
||||
return res, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteImage deletes the named image from the registry, if supported.
|
||||
|
|
@ -830,7 +827,7 @@ func makeBufferedNetworkReader(stream io.ReadCloser, nBuffers, bufferSize uint)
|
|||
handleBufferedNetworkReader(&br)
|
||||
}()
|
||||
|
||||
for i := uint(0); i < nBuffers; i++ {
|
||||
for range nBuffers {
|
||||
b := bufferedNetworkReaderBuffer{
|
||||
data: make([]byte, bufferSize),
|
||||
}
|
||||
|
|
|
|||
1
vendor/github.com/containers/image/v5/docker/errors.go
generated
vendored
1
vendor/github.com/containers/image/v5/docker/errors.go
generated
vendored
|
|
@ -12,6 +12,7 @@ import (
|
|||
var (
|
||||
// ErrV1NotSupported is returned when we're trying to talk to a
|
||||
// docker V1 registry.
|
||||
// Deprecated: The V1 container registry detection is no longer performed, so this error is never returned.
|
||||
ErrV1NotSupported = errors.New("can't talk to a V1 container registry")
|
||||
// ErrTooManyRequests is returned when the status code returned is 429
|
||||
ErrTooManyRequests = errors.New("too many requests to registry")
|
||||
|
|
|
|||
28
vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go
generated
vendored
28
vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go
generated
vendored
|
|
@ -20,22 +20,25 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Destination is a partial implementation of private.ImageDestination for writing to an io.Writer.
|
||||
// Destination is a partial implementation of private.ImageDestination for writing to a Writer.
|
||||
type Destination struct {
|
||||
impl.Compat
|
||||
impl.PropertyMethodsInitialize
|
||||
stubs.NoPutBlobPartialInitialize
|
||||
stubs.NoSignaturesInitialize
|
||||
|
||||
archive *Writer
|
||||
repoTags []reference.NamedTagged
|
||||
archive *Writer
|
||||
commitWithOptions func(ctx context.Context, options private.CommitOptions) error
|
||||
repoTags []reference.NamedTagged
|
||||
// Other state.
|
||||
config []byte
|
||||
sysCtx *types.SystemContext
|
||||
}
|
||||
|
||||
// NewDestination returns a tarfile.Destination adding images to the specified Writer.
|
||||
func NewDestination(sys *types.SystemContext, archive *Writer, transportName string, ref reference.NamedTagged) *Destination {
|
||||
// commitWithOptions implements ImageDestination.CommitWithOptions.
|
||||
func NewDestination(sys *types.SystemContext, archive *Writer, transportName string, ref reference.NamedTagged,
|
||||
commitWithOptions func(ctx context.Context, options private.CommitOptions) error) *Destination {
|
||||
repoTags := []reference.NamedTagged{}
|
||||
if ref != nil {
|
||||
repoTags = append(repoTags, ref)
|
||||
|
|
@ -57,9 +60,10 @@ func NewDestination(sys *types.SystemContext, archive *Writer, transportName str
|
|||
NoPutBlobPartialInitialize: stubs.NoPutBlobPartialRaw(transportName),
|
||||
NoSignaturesInitialize: stubs.NoSignatures("Storing signatures for docker tar files is not supported"),
|
||||
|
||||
archive: archive,
|
||||
repoTags: repoTags,
|
||||
sysCtx: sys,
|
||||
archive: archive,
|
||||
commitWithOptions: commitWithOptions,
|
||||
repoTags: repoTags,
|
||||
sysCtx: sys,
|
||||
}
|
||||
dest.Compat = impl.AddCompat(dest)
|
||||
return dest
|
||||
|
|
@ -179,3 +183,13 @@ func (d *Destination) PutManifest(ctx context.Context, m []byte, instanceDigest
|
|||
|
||||
return d.archive.ensureManifestItemLocked(man.LayersDescriptors, man.ConfigDescriptor.Digest, d.repoTags)
|
||||
}
|
||||
|
||||
// CommitWithOptions marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before CommitWithOptions() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without CommitWithOptions() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *Destination) CommitWithOptions(ctx context.Context, options private.CommitOptions) error {
|
||||
// This indirection exists because impl.Compat expects all ImageDestinationInternalOnly methods
|
||||
// to be implemented in one place.
|
||||
return d.commitWithOptions(ctx, options)
|
||||
}
|
||||
|
|
|
|||
13
vendor/github.com/containers/image/v5/internal/imagedestination/impl/compat.go
generated
vendored
13
vendor/github.com/containers/image/v5/internal/imagedestination/impl/compat.go
generated
vendored
|
|
@ -99,3 +99,16 @@ func (c *Compat) PutSignatures(ctx context.Context, signatures [][]byte, instanc
|
|||
}
|
||||
return c.dest.PutSignaturesWithFormat(ctx, withFormat, instanceDigest)
|
||||
}
|
||||
|
||||
// Commit marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list
|
||||
// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the
|
||||
// original manifest list digest, if desired.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before Commit() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed)
|
||||
func (c *Compat) Commit(ctx context.Context, unparsedToplevel types.UnparsedImage) error {
|
||||
return c.dest.CommitWithOptions(ctx, private.CommitOptions{
|
||||
UnparsedToplevel: unparsedToplevel,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,9 @@ func (stub NoPutBlobPartialInitialize) SupportsPutBlobPartial() bool {
|
|||
// PutBlobPartial attempts to create a blob using the data that is already present
|
||||
// at the destination. chunkAccessor is accessed in a non-sequential way to retrieve the missing chunks.
|
||||
// It is available only if SupportsPutBlobPartial().
|
||||
// Even if SupportsPutBlobPartial() returns true, the call can fail, in which case the caller
|
||||
// should fall back to PutBlobWithOptions.
|
||||
// Even if SupportsPutBlobPartial() returns true, the call can fail.
|
||||
// If the call fails with ErrFallbackToOrdinaryLayerDownload, the caller can fall back to PutBlobWithOptions.
|
||||
// The fallback _must not_ be done otherwise.
|
||||
func (stub NoPutBlobPartialInitialize) PutBlobPartial(ctx context.Context, chunkAccessor private.BlobChunkAccessor, srcInfo types.BlobInfo, options private.PutBlobPartialOptions) (private.UploadedBlob, error) {
|
||||
return private.UploadedBlob{}, fmt.Errorf("internal error: PutBlobPartial is not supported by the %q transport", stub.transportName)
|
||||
}
|
||||
|
|
|
|||
8
vendor/github.com/containers/image/v5/internal/imagedestination/wrapper.go
generated
vendored
8
vendor/github.com/containers/image/v5/internal/imagedestination/wrapper.go
generated
vendored
|
|
@ -97,3 +97,11 @@ func (w *wrapped) PutSignaturesWithFormat(ctx context.Context, signatures []sign
|
|||
}
|
||||
return w.PutSignatures(ctx, simpleSigs, instanceDigest)
|
||||
}
|
||||
|
||||
// CommitWithOptions marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before CommitWithOptions() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without CommitWithOptions() (i.e. rollback is allowed but not guaranteed)
|
||||
func (w *wrapped) CommitWithOptions(ctx context.Context, options private.CommitOptions) error {
|
||||
return w.Commit(ctx, options.UnparsedToplevel)
|
||||
}
|
||||
|
|
|
|||
5
vendor/github.com/containers/image/v5/internal/manifest/docker_schema2_list.go
generated
vendored
5
vendor/github.com/containers/image/v5/internal/manifest/docker_schema2_list.go
generated
vendored
|
|
@ -152,10 +152,7 @@ func (list *Schema2ListPublic) ChooseInstanceByCompression(ctx *types.SystemCont
|
|||
// ChooseInstance parses blob as a schema2 manifest list, and returns the digest
|
||||
// of the image which is appropriate for the current environment.
|
||||
func (list *Schema2ListPublic) ChooseInstance(ctx *types.SystemContext) (digest.Digest, error) {
|
||||
wantedPlatforms, err := platform.WantedPlatforms(ctx)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("getting platform information %#v: %w", ctx, err)
|
||||
}
|
||||
wantedPlatforms := platform.WantedPlatforms(ctx)
|
||||
for _, wantedPlatform := range wantedPlatforms {
|
||||
for _, d := range list.Manifests {
|
||||
imagePlatform := ociPlatformFromSchema2PlatformSpec(d.Platform)
|
||||
|
|
|
|||
5
vendor/github.com/containers/image/v5/internal/manifest/oci_index.go
generated
vendored
5
vendor/github.com/containers/image/v5/internal/manifest/oci_index.go
generated
vendored
|
|
@ -236,10 +236,7 @@ func (index *OCI1IndexPublic) chooseInstance(ctx *types.SystemContext, preferGzi
|
|||
if preferGzip == types.OptionalBoolTrue {
|
||||
didPreferGzip = true
|
||||
}
|
||||
wantedPlatforms, err := platform.WantedPlatforms(ctx)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("getting platform information %#v: %w", ctx, err)
|
||||
}
|
||||
wantedPlatforms := platform.WantedPlatforms(ctx)
|
||||
var bestMatch *instanceCandidate
|
||||
bestMatch = nil
|
||||
for manifestIndex, d := range index.Manifests {
|
||||
|
|
|
|||
4
vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go
generated
vendored
4
vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go
generated
vendored
|
|
@ -153,7 +153,7 @@ var compatibility = map[string][]string{
|
|||
// WantedPlatforms returns all compatible platforms with the platform specifics possibly overridden by user,
|
||||
// the most compatible platform is first.
|
||||
// If some option (arch, os, variant) is not present, a value from current platform is detected.
|
||||
func WantedPlatforms(ctx *types.SystemContext) ([]imgspecv1.Platform, error) {
|
||||
func WantedPlatforms(ctx *types.SystemContext) []imgspecv1.Platform {
|
||||
// Note that this does not use Platform.OSFeatures and Platform.OSVersion at all.
|
||||
// The fields are not specified by the OCI specification, as of version 1.1, usefully enough
|
||||
// to be interoperable, anyway.
|
||||
|
|
@ -211,7 +211,7 @@ func WantedPlatforms(ctx *types.SystemContext) ([]imgspecv1.Platform, error) {
|
|||
Variant: v,
|
||||
})
|
||||
}
|
||||
return res, nil
|
||||
return res
|
||||
}
|
||||
|
||||
// MatchesPlatform returns true if a platform descriptor from a multi-arch image matches
|
||||
|
|
|
|||
43
vendor/github.com/containers/image/v5/internal/private/private.go
generated
vendored
43
vendor/github.com/containers/image/v5/internal/private/private.go
generated
vendored
|
|
@ -53,8 +53,9 @@ type ImageDestinationInternalOnly interface {
|
|||
// PutBlobPartial attempts to create a blob using the data that is already present
|
||||
// at the destination. chunkAccessor is accessed in a non-sequential way to retrieve the missing chunks.
|
||||
// It is available only if SupportsPutBlobPartial().
|
||||
// Even if SupportsPutBlobPartial() returns true, the call can fail, in which case the caller
|
||||
// should fall back to PutBlobWithOptions.
|
||||
// Even if SupportsPutBlobPartial() returns true, the call can fail.
|
||||
// If the call fails with ErrFallbackToOrdinaryLayerDownload, the caller can fall back to PutBlobWithOptions.
|
||||
// The fallback _must not_ be done otherwise.
|
||||
PutBlobPartial(ctx context.Context, chunkAccessor BlobChunkAccessor, srcInfo types.BlobInfo, options PutBlobPartialOptions) (UploadedBlob, error)
|
||||
|
||||
// TryReusingBlobWithOptions checks whether the transport already contains, or can efficiently reuse, a blob, and if so, applies it to the current destination
|
||||
|
|
@ -69,6 +70,12 @@ type ImageDestinationInternalOnly interface {
|
|||
// (when the primary manifest is a manifest list); this should always be nil if the primary manifest is not a manifest list.
|
||||
// MUST be called after PutManifest (signatures may reference manifest contents).
|
||||
PutSignaturesWithFormat(ctx context.Context, signatures []signature.Signature, instanceDigest *digest.Digest) error
|
||||
|
||||
// CommitWithOptions marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before CommitWithOptions() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without CommitWithOptions() (i.e. rollback is allowed but not guaranteed)
|
||||
CommitWithOptions(ctx context.Context, options CommitOptions) error
|
||||
}
|
||||
|
||||
// ImageDestination is an internal extension to the types.ImageDestination
|
||||
|
|
@ -145,6 +152,19 @@ type ReusedBlob struct {
|
|||
MatchedByTOCDigest bool // Whether the layer was reused/matched by TOC digest. Used only for UI purposes.
|
||||
}
|
||||
|
||||
// CommitOptions are used in CommitWithOptions
|
||||
type CommitOptions struct {
|
||||
// UnparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list
|
||||
// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the
|
||||
// original manifest list digest, if desired.
|
||||
UnparsedToplevel types.UnparsedImage
|
||||
// ReportResolvedReference, if set, asks the transport to store a “resolved” (more detailed) reference to the created image
|
||||
// into the value this option points to.
|
||||
// What “resolved” means is transport-specific.
|
||||
// Transports which don’t support reporting resolved references can ignore the field; the generic copy code writes "nil" into the value.
|
||||
ReportResolvedReference *types.ImageReference
|
||||
}
|
||||
|
||||
// ImageSourceChunk is a portion of a blob.
|
||||
// This API is experimental and can be changed without bumping the major version number.
|
||||
type ImageSourceChunk struct {
|
||||
|
|
@ -183,3 +203,22 @@ type UnparsedImage interface {
|
|||
// UntrustedSignatures is like ImageSource.GetSignaturesWithFormat, but the result is cached; it is OK to call this however often you need.
|
||||
UntrustedSignatures(ctx context.Context) ([]signature.Signature, error)
|
||||
}
|
||||
|
||||
// ErrFallbackToOrdinaryLayerDownload is a custom error type returned by PutBlobPartial.
|
||||
// It suggests to the caller that a fallback mechanism can be used instead of a hard failure;
|
||||
// otherwise the caller of PutBlobPartial _must not_ fall back to PutBlob.
|
||||
type ErrFallbackToOrdinaryLayerDownload struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (c ErrFallbackToOrdinaryLayerDownload) Error() string {
|
||||
return c.err.Error()
|
||||
}
|
||||
|
||||
func (c ErrFallbackToOrdinaryLayerDownload) Unwrap() error {
|
||||
return c.err
|
||||
}
|
||||
|
||||
func NewErrFallbackToOrdinaryLayerDownload(err error) error {
|
||||
return ErrFallbackToOrdinaryLayerDownload{err: err}
|
||||
}
|
||||
|
|
|
|||
6
vendor/github.com/containers/image/v5/manifest/docker_schema1.go
generated
vendored
6
vendor/github.com/containers/image/v5/manifest/docker_schema1.go
generated
vendored
|
|
@ -318,20 +318,20 @@ func (m *Schema1) ToSchema2Config(diffIDs []digest.Digest) ([]byte, error) {
|
|||
// Add the history and rootfs information.
|
||||
rootfs, err := json.Marshal(rootFS)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error encoding rootfs information %#v: %v", rootFS, err)
|
||||
return nil, fmt.Errorf("error encoding rootfs information %#v: %w", rootFS, err)
|
||||
}
|
||||
rawRootfs := json.RawMessage(rootfs)
|
||||
raw["rootfs"] = &rawRootfs
|
||||
history, err := json.Marshal(convertedHistory)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error encoding history information %#v: %v", convertedHistory, err)
|
||||
return nil, fmt.Errorf("error encoding history information %#v: %w", convertedHistory, err)
|
||||
}
|
||||
rawHistory := json.RawMessage(history)
|
||||
raw["history"] = &rawHistory
|
||||
// Encode the result.
|
||||
config, err = json.Marshal(raw)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error re-encoding compat image config %#v: %v", s1, err)
|
||||
return nil, fmt.Errorf("error re-encoding compat image config %#v: %w", s1, err)
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
|
|
|||
2
vendor/github.com/containers/image/v5/manifest/oci.go
generated
vendored
2
vendor/github.com/containers/image/v5/manifest/oci.go
generated
vendored
|
|
@ -60,7 +60,7 @@ func OCI1FromManifest(manifestBlob []byte) (*OCI1, error) {
|
|||
if err := json.Unmarshal(manifestBlob, &oci1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := manifest.ValidateUnambiguousManifestFormat(manifestBlob, imgspecv1.MediaTypeImageIndex,
|
||||
if err := manifest.ValidateUnambiguousManifestFormat(manifestBlob, imgspecv1.MediaTypeImageManifest,
|
||||
manifest.AllowedFieldConfig|manifest.AllowedFieldLayers); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
18
vendor/github.com/containers/image/v5/oci/archive/oci_dest.go
generated
vendored
18
vendor/github.com/containers/image/v5/oci/archive/oci_dest.go
generated
vendored
|
|
@ -117,8 +117,9 @@ func (d *ociArchiveImageDestination) PutBlobWithOptions(ctx context.Context, str
|
|||
// PutBlobPartial attempts to create a blob using the data that is already present
|
||||
// at the destination. chunkAccessor is accessed in a non-sequential way to retrieve the missing chunks.
|
||||
// It is available only if SupportsPutBlobPartial().
|
||||
// Even if SupportsPutBlobPartial() returns true, the call can fail, in which case the caller
|
||||
// should fall back to PutBlobWithOptions.
|
||||
// Even if SupportsPutBlobPartial() returns true, the call can fail.
|
||||
// If the call fails with ErrFallbackToOrdinaryLayerDownload, the caller can fall back to PutBlobWithOptions.
|
||||
// The fallback _must not_ be done otherwise.
|
||||
func (d *ociArchiveImageDestination) PutBlobPartial(ctx context.Context, chunkAccessor private.BlobChunkAccessor, srcInfo types.BlobInfo, options private.PutBlobPartialOptions) (private.UploadedBlob, error) {
|
||||
return d.unpackedDest.PutBlobPartial(ctx, chunkAccessor, srcInfo, options)
|
||||
}
|
||||
|
|
@ -149,13 +150,12 @@ func (d *ociArchiveImageDestination) PutSignaturesWithFormat(ctx context.Context
|
|||
return d.unpackedDest.PutSignaturesWithFormat(ctx, signatures, instanceDigest)
|
||||
}
|
||||
|
||||
// Commit marks the process of storing the image as successful and asks for the image to be persisted
|
||||
// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list
|
||||
// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the
|
||||
// original manifest list digest, if desired.
|
||||
// after the directory is made, it is tarred up into a file and the directory is deleted
|
||||
func (d *ociArchiveImageDestination) Commit(ctx context.Context, unparsedToplevel types.UnparsedImage) error {
|
||||
if err := d.unpackedDest.Commit(ctx, unparsedToplevel); err != nil {
|
||||
// CommitWithOptions marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before CommitWithOptions() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without CommitWithOptions() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *ociArchiveImageDestination) CommitWithOptions(ctx context.Context, options private.CommitOptions) error {
|
||||
if err := d.unpackedDest.CommitWithOptions(ctx, options); err != nil {
|
||||
return fmt.Errorf("storing image %q: %w", d.ref.image, err)
|
||||
}
|
||||
|
||||
|
|
|
|||
123
vendor/github.com/containers/image/v5/oci/layout/oci_delete.go
generated
vendored
123
vendor/github.com/containers/image/v5/oci/layout/oci_delete.go
generated
vendored
|
|
@ -27,17 +27,8 @@ func (ref ociReference) DeleteImage(ctx context.Context, sys *types.SystemContex
|
|||
return err
|
||||
}
|
||||
|
||||
var blobsUsedByImage map[digest.Digest]int
|
||||
|
||||
switch descriptor.MediaType {
|
||||
case imgspecv1.MediaTypeImageManifest:
|
||||
blobsUsedByImage, err = ref.getBlobsUsedInSingleImage(&descriptor, sharedBlobsDir)
|
||||
case imgspecv1.MediaTypeImageIndex:
|
||||
blobsUsedByImage, err = ref.getBlobsUsedInImageIndex(&descriptor, sharedBlobsDir)
|
||||
default:
|
||||
return fmt.Errorf("unsupported mediaType in index: %q", descriptor.MediaType)
|
||||
}
|
||||
if err != nil {
|
||||
blobsUsedByImage := make(map[digest.Digest]int)
|
||||
if err := ref.countBlobsForDescriptor(blobsUsedByImage, &descriptor, sharedBlobsDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -54,80 +45,46 @@ func (ref ociReference) DeleteImage(ctx context.Context, sys *types.SystemContex
|
|||
return ref.deleteReferenceFromIndex(descriptorIndex)
|
||||
}
|
||||
|
||||
func (ref ociReference) getBlobsUsedInSingleImage(descriptor *imgspecv1.Descriptor, sharedBlobsDir string) (map[digest.Digest]int, error) {
|
||||
manifest, err := ref.getManifest(descriptor, sharedBlobsDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blobsUsedInManifest := ref.getBlobsUsedInManifest(manifest)
|
||||
blobsUsedInManifest[descriptor.Digest]++ // Add the current manifest to the list of blobs used by this reference
|
||||
|
||||
return blobsUsedInManifest, nil
|
||||
}
|
||||
|
||||
func (ref ociReference) getBlobsUsedInImageIndex(descriptor *imgspecv1.Descriptor, sharedBlobsDir string) (map[digest.Digest]int, error) {
|
||||
// countBlobsForDescriptor updates dest with usage counts of blobs required for descriptor, INCLUDING descriptor itself.
|
||||
func (ref ociReference) countBlobsForDescriptor(dest map[digest.Digest]int, descriptor *imgspecv1.Descriptor, sharedBlobsDir string) error {
|
||||
blobPath, err := ref.blobPath(descriptor.Digest, sharedBlobsDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
index, err := parseIndex(blobPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
blobsUsedInImageRefIndex := make(map[digest.Digest]int)
|
||||
err = ref.addBlobsUsedInIndex(blobsUsedInImageRefIndex, index, sharedBlobsDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blobsUsedInImageRefIndex[descriptor.Digest]++ // Add the nested index in the list of blobs used by this reference
|
||||
|
||||
return blobsUsedInImageRefIndex, nil
|
||||
}
|
||||
|
||||
// Updates a map of digest with the usage count, so a blob that is referenced three times will have 3 in the map
|
||||
func (ref ociReference) addBlobsUsedInIndex(destination map[digest.Digest]int, index *imgspecv1.Index, sharedBlobsDir string) error {
|
||||
for _, descriptor := range index.Manifests {
|
||||
destination[descriptor.Digest]++
|
||||
switch descriptor.MediaType {
|
||||
case imgspecv1.MediaTypeImageManifest:
|
||||
manifest, err := ref.getManifest(&descriptor, sharedBlobsDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for digest, count := range ref.getBlobsUsedInManifest(manifest) {
|
||||
destination[digest] += count
|
||||
}
|
||||
case imgspecv1.MediaTypeImageIndex:
|
||||
blobPath, err := ref.blobPath(descriptor.Digest, sharedBlobsDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
index, err := parseIndex(blobPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ref.addBlobsUsedInIndex(destination, index, sharedBlobsDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unsupported mediaType in index: %q", descriptor.MediaType)
|
||||
dest[descriptor.Digest]++
|
||||
switch descriptor.MediaType {
|
||||
case imgspecv1.MediaTypeImageManifest:
|
||||
manifest, err := parseJSON[imgspecv1.Manifest](blobPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dest[manifest.Config.Digest]++
|
||||
for _, layer := range manifest.Layers {
|
||||
dest[layer.Digest]++
|
||||
}
|
||||
case imgspecv1.MediaTypeImageIndex:
|
||||
index, err := parseIndex(blobPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ref.countBlobsReferencedByIndex(dest, index, sharedBlobsDir); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unsupported mediaType in index: %q", descriptor.MediaType)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ref ociReference) getBlobsUsedInManifest(manifest *imgspecv1.Manifest) map[digest.Digest]int {
|
||||
blobsUsedInManifest := make(map[digest.Digest]int, 0)
|
||||
|
||||
blobsUsedInManifest[manifest.Config.Digest]++
|
||||
for _, layer := range manifest.Layers {
|
||||
blobsUsedInManifest[layer.Digest]++
|
||||
// countBlobsReferencedByIndex updates dest with usage counts of blobs required for index, EXCLUDING the index itself.
|
||||
func (ref ociReference) countBlobsReferencedByIndex(destination map[digest.Digest]int, index *imgspecv1.Index, sharedBlobsDir string) error {
|
||||
for _, descriptor := range index.Manifests {
|
||||
if err := ref.countBlobsForDescriptor(destination, &descriptor, sharedBlobsDir); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return blobsUsedInManifest
|
||||
return nil
|
||||
}
|
||||
|
||||
// This takes in a map of the digest and their usage count in the manifest to be deleted
|
||||
|
|
@ -138,7 +95,7 @@ func (ref ociReference) getBlobsToDelete(blobsUsedByDescriptorToDelete map[diges
|
|||
return nil, err
|
||||
}
|
||||
blobsUsedInRootIndex := make(map[digest.Digest]int)
|
||||
err = ref.addBlobsUsedInIndex(blobsUsedInRootIndex, rootIndex, sharedBlobsDir)
|
||||
err = ref.countBlobsReferencedByIndex(blobsUsedInRootIndex, rootIndex, sharedBlobsDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -224,17 +181,3 @@ func saveJSON(path string, content any) error {
|
|||
|
||||
return json.NewEncoder(file).Encode(content)
|
||||
}
|
||||
|
||||
func (ref ociReference) getManifest(descriptor *imgspecv1.Descriptor, sharedBlobsDir string) (*imgspecv1.Manifest, error) {
|
||||
manifestPath, err := ref.blobPath(descriptor.Digest, sharedBlobsDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
manifest, err := parseJSON[imgspecv1.Manifest](manifestPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return manifest, nil
|
||||
}
|
||||
|
|
|
|||
11
vendor/github.com/containers/image/v5/oci/layout/oci_dest.go
generated
vendored
11
vendor/github.com/containers/image/v5/oci/layout/oci_dest.go
generated
vendored
|
|
@ -278,14 +278,11 @@ func (d *ociImageDestination) addManifest(desc *imgspecv1.Descriptor) {
|
|||
d.index.Manifests = append(slices.Clone(d.index.Manifests), *desc)
|
||||
}
|
||||
|
||||
// Commit marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list
|
||||
// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the
|
||||
// original manifest list digest, if desired.
|
||||
// CommitWithOptions marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before Commit() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *ociImageDestination) Commit(context.Context, types.UnparsedImage) error {
|
||||
// - Uploaded data MAY be visible to others before CommitWithOptions() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without CommitWithOptions() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *ociImageDestination) CommitWithOptions(ctx context.Context, options private.CommitOptions) error {
|
||||
layoutBytes, err := json.Marshal(imgspecv1.ImageLayout{
|
||||
Version: imgspecv1.ImageLayoutVersion,
|
||||
})
|
||||
|
|
|
|||
6
vendor/github.com/containers/image/v5/openshift/openshift-copies.go
generated
vendored
6
vendor/github.com/containers/image/v5/openshift/openshift-copies.go
generated
vendored
|
|
@ -365,7 +365,7 @@ func validateClusterInfo(clusterName string, clusterInfo clientcmdCluster) []err
|
|||
if len(clusterInfo.CertificateAuthority) != 0 {
|
||||
err := validateFileIsReadable(clusterInfo.CertificateAuthority)
|
||||
if err != nil {
|
||||
validationErrors = append(validationErrors, fmt.Errorf("unable to read certificate-authority %v for %v due to %v", clusterInfo.CertificateAuthority, clusterName, err))
|
||||
validationErrors = append(validationErrors, fmt.Errorf("unable to read certificate-authority %v for %v due to %w", clusterInfo.CertificateAuthority, clusterName, err))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -403,13 +403,13 @@ func validateAuthInfo(authInfoName string, authInfo clientcmdAuthInfo) []error {
|
|||
if len(authInfo.ClientCertificate) != 0 {
|
||||
err := validateFileIsReadable(authInfo.ClientCertificate)
|
||||
if err != nil {
|
||||
validationErrors = append(validationErrors, fmt.Errorf("unable to read client-cert %v for %v due to %v", authInfo.ClientCertificate, authInfoName, err))
|
||||
validationErrors = append(validationErrors, fmt.Errorf("unable to read client-cert %v for %v due to %w", authInfo.ClientCertificate, authInfoName, err))
|
||||
}
|
||||
}
|
||||
if len(authInfo.ClientKey) != 0 {
|
||||
err := validateFileIsReadable(authInfo.ClientKey)
|
||||
if err != nil {
|
||||
validationErrors = append(validationErrors, fmt.Errorf("unable to read client-key %v for %v due to %v", authInfo.ClientKey, authInfoName, err))
|
||||
validationErrors = append(validationErrors, fmt.Errorf("unable to read client-key %v for %v due to %w", authInfo.ClientKey, authInfoName, err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
18
vendor/github.com/containers/image/v5/openshift/openshift_dest.go
generated
vendored
18
vendor/github.com/containers/image/v5/openshift/openshift_dest.go
generated
vendored
|
|
@ -125,8 +125,9 @@ func (d *openshiftImageDestination) PutBlobWithOptions(ctx context.Context, stre
|
|||
// PutBlobPartial attempts to create a blob using the data that is already present
|
||||
// at the destination. chunkAccessor is accessed in a non-sequential way to retrieve the missing chunks.
|
||||
// It is available only if SupportsPutBlobPartial().
|
||||
// Even if SupportsPutBlobPartial() returns true, the call can fail, in which case the caller
|
||||
// should fall back to PutBlobWithOptions.
|
||||
// Even if SupportsPutBlobPartial() returns true, the call can fail.
|
||||
// If the call fails with ErrFallbackToOrdinaryLayerDownload, the caller can fall back to PutBlobWithOptions.
|
||||
// The fallback _must not_ be done otherwise.
|
||||
func (d *openshiftImageDestination) PutBlobPartial(ctx context.Context, chunkAccessor private.BlobChunkAccessor, srcInfo types.BlobInfo, options private.PutBlobPartialOptions) (private.UploadedBlob, error) {
|
||||
return d.docker.PutBlobPartial(ctx, chunkAccessor, srcInfo, options)
|
||||
}
|
||||
|
|
@ -235,13 +236,10 @@ func (d *openshiftImageDestination) PutSignaturesWithFormat(ctx context.Context,
|
|||
return nil
|
||||
}
|
||||
|
||||
// Commit marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list
|
||||
// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the
|
||||
// original manifest list digest, if desired.
|
||||
// CommitWithOptions marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before Commit() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *openshiftImageDestination) Commit(ctx context.Context, unparsedToplevel types.UnparsedImage) error {
|
||||
return d.docker.Commit(ctx, unparsedToplevel)
|
||||
// - Uploaded data MAY be visible to others before CommitWithOptions() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without CommitWithOptions() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *openshiftImageDestination) CommitWithOptions(ctx context.Context, options private.CommitOptions) error {
|
||||
return d.docker.CommitWithOptions(ctx, options)
|
||||
}
|
||||
|
|
|
|||
6
vendor/github.com/containers/image/v5/ostree/ostree_dest.go
generated
vendored
6
vendor/github.com/containers/image/v5/ostree/ostree_dest.go
generated
vendored
|
|
@ -435,7 +435,11 @@ func (d *ostreeImageDestination) PutSignaturesWithFormat(ctx context.Context, si
|
|||
return nil
|
||||
}
|
||||
|
||||
func (d *ostreeImageDestination) Commit(context.Context, types.UnparsedImage) error {
|
||||
// CommitWithOptions marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before CommitWithOptions() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without CommitWithOptions() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *ostreeImageDestination) CommitWithOptions(ctx context.Context, options private.CommitOptions) error {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
|
|
|
|||
|
|
@ -200,8 +200,6 @@ func (css *candidateSortState) compare(xi, xj CandidateWithTime) int {
|
|||
|
||||
// destructivelyPrioritizeReplacementCandidatesWithMax is destructivelyPrioritizeReplacementCandidates with parameters for the
|
||||
// number of entries to limit for known and unknown location separately, only to make testing simpler.
|
||||
// TODO: following function is not destructive any more in the nature instead prioritized result is actually copies of the original
|
||||
// candidate set, so In future we might wanna re-name this public API and remove the destructive prefix.
|
||||
func destructivelyPrioritizeReplacementCandidatesWithMax(cs []CandidateWithTime, primaryDigest, uncompressedDigest digest.Digest, totalLimit int, noLocationLimit int) []blobinfocache.BICReplacementCandidate2 {
|
||||
// split unknown candidates and known candidates
|
||||
// and limit them separately.
|
||||
|
|
|
|||
14
vendor/github.com/containers/image/v5/pkg/compression/compression.go
generated
vendored
14
vendor/github.com/containers/image/v5/pkg/compression/compression.go
generated
vendored
|
|
@ -99,8 +99,18 @@ func CompressStream(dest io.Writer, algo Algorithm, level *int) (io.WriteCloser,
|
|||
return internal.AlgorithmCompressor(algo)(dest, m, level)
|
||||
}
|
||||
|
||||
// CompressStreamWithMetadata returns the compressor by its name. If the compression
|
||||
// generates any metadata, it is written to the provided metadata map.
|
||||
// CompressStreamWithMetadata returns the compressor by its name.
|
||||
//
|
||||
// Compressing a stream may create integrity data that allows consuming the compressed byte stream
|
||||
// while only using subsets of the compressed data (if the compressed data is seekable and most
|
||||
// of the uncompressed data is already present via other means), while still protecting integrity
|
||||
// of the compressed stream against unwanted modification. (In OCI container images, this metadata
|
||||
// is usually carried in manifest annotations.)
|
||||
//
|
||||
// Such a partial decompression is not implemented by this package; it is consumed e.g. by
|
||||
// github.com/containers/storage/pkg/chunked .
|
||||
//
|
||||
// If the compression generates such metadata, it is written to the provided metadata map.
|
||||
func CompressStreamWithMetadata(dest io.Writer, metadata map[string]string, algo Algorithm, level *int) (io.WriteCloser, error) {
|
||||
return internal.AlgorithmCompressor(algo)(dest, metadata, level)
|
||||
}
|
||||
|
|
|
|||
9
vendor/github.com/containers/image/v5/pkg/compression/internal/types.go
generated
vendored
9
vendor/github.com/containers/image/v5/pkg/compression/internal/types.go
generated
vendored
|
|
@ -3,6 +3,15 @@ package internal
|
|||
import "io"
|
||||
|
||||
// CompressorFunc writes the compressed stream to the given writer using the specified compression level.
|
||||
//
|
||||
// Compressing a stream may create integrity data that allows consuming the compressed byte stream
|
||||
// while only using subsets of the compressed data (if the compressed data is seekable and most
|
||||
// of the uncompressed data is already present via other means), while still protecting integrity
|
||||
// of the compressed stream against unwanted modification. (In OCI container images, this metadata
|
||||
// is usually carried in manifest annotations.)
|
||||
//
|
||||
// If the compression generates such metadata, it is written to the provided metadata map.
|
||||
//
|
||||
// The caller must call Close() on the stream (even if the input stream does not need closing!).
|
||||
type CompressorFunc func(io.Writer, map[string]string, *int) (io.WriteCloser, error)
|
||||
|
||||
|
|
|
|||
25
vendor/github.com/containers/image/v5/signature/internal/rekor_set.go
generated
vendored
25
vendor/github.com/containers/image/v5/signature/internal/rekor_set.go
generated
vendored
|
|
@ -40,17 +40,20 @@ type UntrustedRekorPayload struct {
|
|||
// A compile-time check that UntrustedRekorSET implements json.Unmarshaler
|
||||
var _ json.Unmarshaler = (*UntrustedRekorSET)(nil)
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface
|
||||
func (s *UntrustedRekorSET) UnmarshalJSON(data []byte) error {
|
||||
err := s.strictUnmarshalJSON(data)
|
||||
if err != nil {
|
||||
if formatErr, ok := err.(JSONFormatError); ok {
|
||||
err = NewInvalidSignatureError(formatErr.Error())
|
||||
}
|
||||
// JSONFormatToInvalidSignatureError converts JSONFormatError to InvalidSignatureError.
|
||||
// All other errors are returned as is.
|
||||
func JSONFormatToInvalidSignatureError(err error) error {
|
||||
if formatErr, ok := err.(JSONFormatError); ok {
|
||||
err = NewInvalidSignatureError(formatErr.Error())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface
|
||||
func (s *UntrustedRekorSET) UnmarshalJSON(data []byte) error {
|
||||
return JSONFormatToInvalidSignatureError(s.strictUnmarshalJSON(data))
|
||||
}
|
||||
|
||||
// strictUnmarshalJSON is UnmarshalJSON, except that it may return the internal JSONFormatError error type.
|
||||
// Splitting it into a separate function allows us to do the JSONFormatError → InvalidSignatureError in a single place, the caller.
|
||||
func (s *UntrustedRekorSET) strictUnmarshalJSON(data []byte) error {
|
||||
|
|
@ -77,13 +80,7 @@ var _ json.Unmarshaler = (*UntrustedRekorPayload)(nil)
|
|||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface
|
||||
func (p *UntrustedRekorPayload) UnmarshalJSON(data []byte) error {
|
||||
err := p.strictUnmarshalJSON(data)
|
||||
if err != nil {
|
||||
if formatErr, ok := err.(JSONFormatError); ok {
|
||||
err = NewInvalidSignatureError(formatErr.Error())
|
||||
}
|
||||
}
|
||||
return err
|
||||
return JSONFormatToInvalidSignatureError(p.strictUnmarshalJSON(data))
|
||||
}
|
||||
|
||||
// strictUnmarshalJSON is UnmarshalJSON, except that it may return the internal JSONFormatError error type.
|
||||
|
|
|
|||
10
vendor/github.com/containers/image/v5/signature/internal/sigstore_payload.go
generated
vendored
10
vendor/github.com/containers/image/v5/signature/internal/sigstore_payload.go
generated
vendored
|
|
@ -80,13 +80,7 @@ var _ json.Unmarshaler = (*UntrustedSigstorePayload)(nil)
|
|||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface
|
||||
func (s *UntrustedSigstorePayload) UnmarshalJSON(data []byte) error {
|
||||
err := s.strictUnmarshalJSON(data)
|
||||
if err != nil {
|
||||
if formatErr, ok := err.(JSONFormatError); ok {
|
||||
err = NewInvalidSignatureError(formatErr.Error())
|
||||
}
|
||||
}
|
||||
return err
|
||||
return JSONFormatToInvalidSignatureError(s.strictUnmarshalJSON(data))
|
||||
}
|
||||
|
||||
// strictUnmarshalJSON is UnmarshalJSON, except that it may return the internal JSONFormatError error type.
|
||||
|
|
@ -127,7 +121,7 @@ func (s *UntrustedSigstorePayload) strictUnmarshalJSON(data []byte) error {
|
|||
if gotTimestamp {
|
||||
intTimestamp := int64(timestamp)
|
||||
if float64(intTimestamp) != timestamp {
|
||||
return NewInvalidSignatureError("Field optional.timestamp is not is not an integer")
|
||||
return NewInvalidSignatureError("Field optional.timestamp is not an integer")
|
||||
}
|
||||
s.untrustedTimestamp = &intTimestamp
|
||||
}
|
||||
|
|
|
|||
31
vendor/github.com/containers/image/v5/signature/policy_config.go
generated
vendored
31
vendor/github.com/containers/image/v5/signature/policy_config.go
generated
vendored
|
|
@ -51,28 +51,39 @@ func (err InvalidPolicyFormatError) Error() string {
|
|||
// NOTE: When this function returns an error, report it to the user and abort.
|
||||
// DO NOT hard-code fallback policies in your application.
|
||||
func DefaultPolicy(sys *types.SystemContext) (*Policy, error) {
|
||||
return NewPolicyFromFile(defaultPolicyPath(sys))
|
||||
policyPath, err := defaultPolicyPath(sys)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewPolicyFromFile(policyPath)
|
||||
}
|
||||
|
||||
// defaultPolicyPath returns a path to the default policy of the system.
|
||||
func defaultPolicyPath(sys *types.SystemContext) string {
|
||||
return defaultPolicyPathWithHomeDir(sys, homedir.Get())
|
||||
// defaultPolicyPath returns a path to the relevant policy of the system, or an error if the policy is missing.
|
||||
func defaultPolicyPath(sys *types.SystemContext) (string, error) {
|
||||
policyFilePath, err := defaultPolicyPathWithHomeDir(sys, homedir.Get(), systemDefaultPolicyPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return policyFilePath, nil
|
||||
}
|
||||
|
||||
// defaultPolicyPathWithHomeDir is an internal implementation detail of defaultPolicyPath,
|
||||
// it exists only to allow testing it with an artificial home directory.
|
||||
func defaultPolicyPathWithHomeDir(sys *types.SystemContext, homeDir string) string {
|
||||
// it exists only to allow testing it with artificial paths.
|
||||
func defaultPolicyPathWithHomeDir(sys *types.SystemContext, homeDir string, systemPolicyPath string) (string, error) {
|
||||
if sys != nil && sys.SignaturePolicyPath != "" {
|
||||
return sys.SignaturePolicyPath
|
||||
return sys.SignaturePolicyPath, nil
|
||||
}
|
||||
userPolicyFilePath := filepath.Join(homeDir, userPolicyFile)
|
||||
if err := fileutils.Exists(userPolicyFilePath); err == nil {
|
||||
return userPolicyFilePath
|
||||
return userPolicyFilePath, nil
|
||||
}
|
||||
if sys != nil && sys.RootForImplicitAbsolutePaths != "" {
|
||||
return filepath.Join(sys.RootForImplicitAbsolutePaths, systemDefaultPolicyPath)
|
||||
return filepath.Join(sys.RootForImplicitAbsolutePaths, systemPolicyPath), nil
|
||||
}
|
||||
return systemDefaultPolicyPath
|
||||
if err := fileutils.Exists(systemPolicyPath); err == nil {
|
||||
return systemPolicyPath, nil
|
||||
}
|
||||
return "", fmt.Errorf("no policy.json file found at any of the following: %q, %q", userPolicyFilePath, systemPolicyPath)
|
||||
}
|
||||
|
||||
// NewPolicyFromFile returns a policy configured in the specified file.
|
||||
|
|
|
|||
2
vendor/github.com/containers/image/v5/signature/policy_reference_match.go
generated
vendored
2
vendor/github.com/containers/image/v5/signature/policy_reference_match.go
generated
vendored
|
|
@ -136,7 +136,7 @@ func (prm *prmRemapIdentity) remapReferencePrefix(ref reference.Named) (referenc
|
|||
newNamedRef := strings.Replace(refString, prm.Prefix, prm.SignedPrefix, 1)
|
||||
newParsedRef, err := reference.ParseNamed(newNamedRef)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(`error rewriting reference from %q to %q: %v`, refString, newNamedRef, err)
|
||||
return nil, fmt.Errorf(`error rewriting reference from %q to %q: %w`, refString, newNamedRef, err)
|
||||
}
|
||||
return newParsedRef, nil
|
||||
}
|
||||
|
|
|
|||
10
vendor/github.com/containers/image/v5/signature/simple.go
generated
vendored
10
vendor/github.com/containers/image/v5/signature/simple.go
generated
vendored
|
|
@ -105,13 +105,7 @@ var _ json.Unmarshaler = (*untrustedSignature)(nil)
|
|||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface
|
||||
func (s *untrustedSignature) UnmarshalJSON(data []byte) error {
|
||||
err := s.strictUnmarshalJSON(data)
|
||||
if err != nil {
|
||||
if formatErr, ok := err.(internal.JSONFormatError); ok {
|
||||
err = internal.NewInvalidSignatureError(formatErr.Error())
|
||||
}
|
||||
}
|
||||
return err
|
||||
return internal.JSONFormatToInvalidSignatureError(s.strictUnmarshalJSON(data))
|
||||
}
|
||||
|
||||
// strictUnmarshalJSON is UnmarshalJSON, except that it may return the internal.JSONFormatError error type.
|
||||
|
|
@ -149,7 +143,7 @@ func (s *untrustedSignature) strictUnmarshalJSON(data []byte) error {
|
|||
if gotTimestamp {
|
||||
intTimestamp := int64(timestamp)
|
||||
if float64(intTimestamp) != timestamp {
|
||||
return internal.NewInvalidSignatureError("Field optional.timestamp is not is not an integer")
|
||||
return internal.NewInvalidSignatureError("Field optional.timestamp is not an integer")
|
||||
}
|
||||
s.untrustedTimestamp = &intTimestamp
|
||||
}
|
||||
|
|
|
|||
94
vendor/github.com/containers/image/v5/storage/storage_dest.go
generated
vendored
94
vendor/github.com/containers/image/v5/storage/storage_dest.go
generated
vendored
|
|
@ -311,23 +311,31 @@ func (f *zstdFetcher) GetBlobAt(chunks []chunked.ImageSourceChunk) (chan io.Read
|
|||
// PutBlobPartial attempts to create a blob using the data that is already present
|
||||
// at the destination. chunkAccessor is accessed in a non-sequential way to retrieve the missing chunks.
|
||||
// It is available only if SupportsPutBlobPartial().
|
||||
// Even if SupportsPutBlobPartial() returns true, the call can fail, in which case the caller
|
||||
// should fall back to PutBlobWithOptions.
|
||||
func (s *storageImageDestination) PutBlobPartial(ctx context.Context, chunkAccessor private.BlobChunkAccessor, srcInfo types.BlobInfo, options private.PutBlobPartialOptions) (private.UploadedBlob, error) {
|
||||
// Even if SupportsPutBlobPartial() returns true, the call can fail.
|
||||
// If the call fails with ErrFallbackToOrdinaryLayerDownload, the caller can fall back to PutBlobWithOptions.
|
||||
// The fallback _must not_ be done otherwise.
|
||||
func (s *storageImageDestination) PutBlobPartial(ctx context.Context, chunkAccessor private.BlobChunkAccessor, srcInfo types.BlobInfo, options private.PutBlobPartialOptions) (_ private.UploadedBlob, retErr error) {
|
||||
fetcher := zstdFetcher{
|
||||
chunkAccessor: chunkAccessor,
|
||||
ctx: ctx,
|
||||
blobInfo: srcInfo,
|
||||
}
|
||||
|
||||
defer func() {
|
||||
var perr chunked.ErrFallbackToOrdinaryLayerDownload
|
||||
if errors.As(retErr, &perr) {
|
||||
retErr = private.NewErrFallbackToOrdinaryLayerDownload(retErr)
|
||||
}
|
||||
}()
|
||||
|
||||
differ, err := chunked.GetDiffer(ctx, s.imageRef.transport.store, srcInfo.Digest, srcInfo.Size, srcInfo.Annotations, &fetcher)
|
||||
if err != nil {
|
||||
return private.UploadedBlob{}, err
|
||||
}
|
||||
|
||||
out, err := s.imageRef.transport.store.ApplyDiffWithDiffer("", nil, differ)
|
||||
out, err := s.imageRef.transport.store.PrepareStagedLayer(nil, differ)
|
||||
if err != nil {
|
||||
return private.UploadedBlob{}, err
|
||||
return private.UploadedBlob{}, fmt.Errorf("staging a partially-pulled layer: %w", err)
|
||||
}
|
||||
succeeded := false
|
||||
defer func() {
|
||||
|
|
@ -337,7 +345,7 @@ func (s *storageImageDestination) PutBlobPartial(ctx context.Context, chunkAcces
|
|||
}()
|
||||
|
||||
if out.TOCDigest == "" && out.UncompressedDigest == "" {
|
||||
return private.UploadedBlob{}, errors.New("internal error: ApplyDiffWithDiffer succeeded with neither TOCDigest nor UncompressedDigest set")
|
||||
return private.UploadedBlob{}, errors.New("internal error: PrepareStagedLayer succeeded with neither TOCDigest nor UncompressedDigest set")
|
||||
}
|
||||
|
||||
blobDigest := srcInfo.Digest
|
||||
|
|
@ -356,11 +364,11 @@ func (s *storageImageDestination) PutBlobPartial(ctx context.Context, chunkAcces
|
|||
// The computation of UncompressedDigest means the whole layer has been consumed; while doing that, chunked.GetDiffer is
|
||||
// responsible for ensuring blobDigest has been validated.
|
||||
if out.CompressedDigest != blobDigest {
|
||||
return private.UploadedBlob{}, fmt.Errorf("internal error: ApplyDiffWithDiffer returned CompressedDigest %q not matching expected %q",
|
||||
return private.UploadedBlob{}, fmt.Errorf("internal error: PrepareStagedLayer returned CompressedDigest %q not matching expected %q",
|
||||
out.CompressedDigest, blobDigest)
|
||||
}
|
||||
// So, record also information about blobDigest, that might benefit reuse.
|
||||
// We trust ApplyDiffWithDiffer to validate or create both values correctly.
|
||||
// We trust PrepareStagedLayer to validate or create both values correctly.
|
||||
s.lockProtected.blobDiffIDs[blobDigest] = out.UncompressedDigest
|
||||
options.Cache.RecordDigestUncompressedPair(out.CompressedDigest, out.UncompressedDigest)
|
||||
} else {
|
||||
|
|
@ -922,7 +930,7 @@ func (s *storageImageDestination) createNewLayer(index int, layerDigest digest.D
|
|||
|
||||
flags := make(map[string]interface{})
|
||||
if untrustedUncompressedDigest != "" {
|
||||
flags[expectedLayerDiffIDFlag] = untrustedUncompressedDigest
|
||||
flags[expectedLayerDiffIDFlag] = untrustedUncompressedDigest.String()
|
||||
logrus.Debugf("Setting uncompressed digest to %q for layer %q", untrustedUncompressedDigest, newLayerID)
|
||||
}
|
||||
|
||||
|
|
@ -1116,26 +1124,23 @@ func (s *storageImageDestination) untrustedLayerDiffID(layerIndex int) (digest.D
|
|||
return s.untrustedDiffIDValues[layerIndex], nil
|
||||
}
|
||||
|
||||
// Commit marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// unparsedToplevel contains data about the top-level manifest of the source (which may be a single-arch image or a manifest list
|
||||
// if PutManifest was only called for the single-arch image with instanceDigest == nil), primarily to allow lookups by the
|
||||
// original manifest list digest, if desired.
|
||||
// CommitWithOptions marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before Commit() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed)
|
||||
func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel types.UnparsedImage) error {
|
||||
// - Uploaded data MAY be visible to others before CommitWithOptions() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without CommitWithOptions() (i.e. rollback is allowed but not guaranteed)
|
||||
func (s *storageImageDestination) CommitWithOptions(ctx context.Context, options private.CommitOptions) error {
|
||||
// This function is outside of the scope of HasThreadSafePutBlob, so we don’t need to hold s.lock.
|
||||
|
||||
if len(s.manifest) == 0 {
|
||||
return errors.New("Internal error: storageImageDestination.Commit() called without PutManifest()")
|
||||
return errors.New("Internal error: storageImageDestination.CommitWithOptions() called without PutManifest()")
|
||||
}
|
||||
toplevelManifest, _, err := unparsedToplevel.Manifest(ctx)
|
||||
toplevelManifest, _, err := options.UnparsedToplevel.Manifest(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("retrieving top-level manifest: %w", err)
|
||||
}
|
||||
// If the name we're saving to includes a digest, then check that the
|
||||
// manifests that we're about to save all either match the one from the
|
||||
// unparsedToplevel, or match the digest in the name that we're using.
|
||||
// options.UnparsedToplevel, or match the digest in the name that we're using.
|
||||
if s.imageRef.named != nil {
|
||||
if digested, ok := s.imageRef.named.(reference.Digested); ok {
|
||||
matches, err := manifest.MatchesDigest(s.manifest, digested.Digest())
|
||||
|
|
@ -1168,24 +1173,24 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
|
|||
}, blob.Size); err != nil {
|
||||
return err
|
||||
} else if stopQueue {
|
||||
return fmt.Errorf("Internal error: storageImageDestination.Commit(): commitLayer() not ready to commit for layer %q", blob.Digest)
|
||||
return fmt.Errorf("Internal error: storageImageDestination.CommitWithOptions(): commitLayer() not ready to commit for layer %q", blob.Digest)
|
||||
}
|
||||
}
|
||||
var lastLayer string
|
||||
if len(layerBlobs) > 0 { // Zero-layer images rarely make sense, but it is technically possible, and may happen for non-image artifacts.
|
||||
prev, ok := s.indexToStorageID[len(layerBlobs)-1]
|
||||
if !ok {
|
||||
return fmt.Errorf("Internal error: storageImageDestination.Commit(): previous layer %d hasn't been committed (lastLayer == nil)", len(layerBlobs)-1)
|
||||
return fmt.Errorf("Internal error: storageImageDestination.CommitWithOptions(): previous layer %d hasn't been committed (lastLayer == nil)", len(layerBlobs)-1)
|
||||
}
|
||||
lastLayer = prev
|
||||
}
|
||||
|
||||
// If one of those blobs was a configuration blob, then we can try to dig out the date when the image
|
||||
// was originally created, in case we're just copying it. If not, no harm done.
|
||||
options := &storage.ImageOptions{}
|
||||
imgOptions := &storage.ImageOptions{}
|
||||
if inspect, err := man.Inspect(s.getConfigBlob); err == nil && inspect.Created != nil {
|
||||
logrus.Debugf("setting image creation date to %s", inspect.Created)
|
||||
options.CreationDate = *inspect.Created
|
||||
imgOptions.CreationDate = *inspect.Created
|
||||
}
|
||||
|
||||
// Set up to save the non-layer blobs as data items. Since we only share layers, they should all be in files, so
|
||||
|
|
@ -1202,13 +1207,13 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
|
|||
if err != nil {
|
||||
return fmt.Errorf("copying non-layer blob %q to image: %w", blob, err)
|
||||
}
|
||||
options.BigData = append(options.BigData, storage.ImageBigDataOption{
|
||||
imgOptions.BigData = append(imgOptions.BigData, storage.ImageBigDataOption{
|
||||
Key: blob.String(),
|
||||
Data: v,
|
||||
Digest: digest.Canonical.FromBytes(v),
|
||||
})
|
||||
}
|
||||
// Set up to save the unparsedToplevel's manifest if it differs from
|
||||
// Set up to save the options.UnparsedToplevel's manifest if it differs from
|
||||
// the per-platform one, which is saved below.
|
||||
if len(toplevelManifest) != 0 && !bytes.Equal(toplevelManifest, s.manifest) {
|
||||
manifestDigest, err := manifest.Digest(toplevelManifest)
|
||||
|
|
@ -1219,7 +1224,7 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
options.BigData = append(options.BigData, storage.ImageBigDataOption{
|
||||
imgOptions.BigData = append(imgOptions.BigData, storage.ImageBigDataOption{
|
||||
Key: key,
|
||||
Data: toplevelManifest,
|
||||
Digest: manifestDigest,
|
||||
|
|
@ -1232,19 +1237,19 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
options.BigData = append(options.BigData, storage.ImageBigDataOption{
|
||||
imgOptions.BigData = append(imgOptions.BigData, storage.ImageBigDataOption{
|
||||
Key: key,
|
||||
Data: s.manifest,
|
||||
Digest: s.manifestDigest,
|
||||
})
|
||||
options.BigData = append(options.BigData, storage.ImageBigDataOption{
|
||||
imgOptions.BigData = append(imgOptions.BigData, storage.ImageBigDataOption{
|
||||
Key: storage.ImageDigestBigDataKey,
|
||||
Data: s.manifest,
|
||||
Digest: s.manifestDigest,
|
||||
})
|
||||
// Set up to save the signatures, if we have any.
|
||||
if len(s.signatures) > 0 {
|
||||
options.BigData = append(options.BigData, storage.ImageBigDataOption{
|
||||
imgOptions.BigData = append(imgOptions.BigData, storage.ImageBigDataOption{
|
||||
Key: "signatures",
|
||||
Data: s.signatures,
|
||||
Digest: digest.Canonical.FromBytes(s.signatures),
|
||||
|
|
@ -1255,7 +1260,7 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
options.BigData = append(options.BigData, storage.ImageBigDataOption{
|
||||
imgOptions.BigData = append(imgOptions.BigData, storage.ImageBigDataOption{
|
||||
Key: key,
|
||||
Data: signatures,
|
||||
Digest: digest.Canonical.FromBytes(signatures),
|
||||
|
|
@ -1268,7 +1273,7 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
|
|||
return fmt.Errorf("encoding metadata for image: %w", err)
|
||||
}
|
||||
if len(metadata) != 0 {
|
||||
options.Metadata = string(metadata)
|
||||
imgOptions.Metadata = string(metadata)
|
||||
}
|
||||
|
||||
// Create the image record, pointing to the most-recently added layer.
|
||||
|
|
@ -1280,7 +1285,7 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
|
|||
}
|
||||
}
|
||||
oldNames := []string{}
|
||||
img, err := s.imageRef.transport.store.CreateImage(intendedID, nil, lastLayer, "", options)
|
||||
img, err := s.imageRef.transport.store.CreateImage(intendedID, nil, lastLayer, "", imgOptions)
|
||||
if err != nil {
|
||||
if !errors.Is(err, storage.ErrDuplicateID) {
|
||||
logrus.Debugf("error creating image: %q", err)
|
||||
|
|
@ -1301,21 +1306,21 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
|
|||
// sizes (tracked in the metadata) which might have already
|
||||
// been present with new values, when ideally we'd find a way
|
||||
// to merge them since they all apply to the same image
|
||||
for _, data := range options.BigData {
|
||||
for _, data := range imgOptions.BigData {
|
||||
if err := s.imageRef.transport.store.SetImageBigData(img.ID, data.Key, data.Data, manifest.Digest); err != nil {
|
||||
logrus.Debugf("error saving big data %q for image %q: %v", data.Key, img.ID, err)
|
||||
return fmt.Errorf("saving big data %q for image %q: %w", data.Key, img.ID, err)
|
||||
}
|
||||
}
|
||||
if options.Metadata != "" {
|
||||
if err := s.imageRef.transport.store.SetMetadata(img.ID, options.Metadata); err != nil {
|
||||
if imgOptions.Metadata != "" {
|
||||
if err := s.imageRef.transport.store.SetMetadata(img.ID, imgOptions.Metadata); err != nil {
|
||||
logrus.Debugf("error saving metadata for image %q: %v", img.ID, err)
|
||||
return fmt.Errorf("saving metadata for image %q: %w", img.ID, err)
|
||||
}
|
||||
logrus.Debugf("saved image metadata %q", options.Metadata)
|
||||
logrus.Debugf("saved image metadata %q", imgOptions.Metadata)
|
||||
}
|
||||
} else {
|
||||
logrus.Debugf("created new image ID %q with metadata %q", img.ID, options.Metadata)
|
||||
logrus.Debugf("created new image ID %q with metadata %q", img.ID, imgOptions.Metadata)
|
||||
}
|
||||
|
||||
// Clean up the unfinished image on any error.
|
||||
|
|
@ -1338,6 +1343,21 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
|
|||
}
|
||||
logrus.Debugf("added name %q to image %q", name, img.ID)
|
||||
}
|
||||
if options.ReportResolvedReference != nil {
|
||||
// FIXME? This is using nil for the named reference.
|
||||
// It would be better to also use s.imageRef.named, because that allows us to resolve to the right
|
||||
// digest / manifest (and corresponding signatures).
|
||||
// The problem with that is that resolving such a reference fails if the s.imageRef.named name is moved to a different image
|
||||
// (because it is a tag that moved, or because we have pulled “the same” image for a different architecture).
|
||||
// Right now (2024-11), ReportResolvedReference is only used in c/common/libimage, where the caller only extracts the image ID,
|
||||
// so the name does not matter; to give us options, copy.Options.ReportResolvedReference is explicitly refusing to document
|
||||
// whether the value contains a name.
|
||||
resolved, err := newReference(s.imageRef.transport, nil, intendedID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating a resolved reference for (%s, %s): %w", s.imageRef.StringWithinTransport(), intendedID, err)
|
||||
}
|
||||
*options.ReportResolvedReference = resolved
|
||||
}
|
||||
|
||||
commitSucceeded = true
|
||||
return nil
|
||||
|
|
|
|||
2
vendor/github.com/containers/image/v5/storage/storage_reference.go
generated
vendored
2
vendor/github.com/containers/image/v5/storage/storage_reference.go
generated
vendored
|
|
@ -37,7 +37,7 @@ func newReference(transport storageTransport, named reference.Named, id string)
|
|||
}
|
||||
if id != "" {
|
||||
if err := validateImageID(id); err != nil {
|
||||
return nil, fmt.Errorf("invalid ID value %q: %v: %w", id, err, ErrInvalidReference)
|
||||
return nil, fmt.Errorf("invalid ID value %q: %v: %w", id, err.Error(), ErrInvalidReference)
|
||||
}
|
||||
}
|
||||
// We take a copy of the transport, which contains a pointer to the
|
||||
|
|
|
|||
6
vendor/github.com/containers/image/v5/storage/storage_src.go
generated
vendored
6
vendor/github.com/containers/image/v5/storage/storage_src.go
generated
vendored
|
|
@ -11,6 +11,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"slices"
|
||||
"sync"
|
||||
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
|
|
@ -300,7 +301,7 @@ func (s *storageImageSource) LayerInfosForCopy(ctx context.Context, instanceDige
|
|||
uncompressedLayerType = manifest.DockerV2SchemaLayerMediaTypeUncompressed
|
||||
}
|
||||
|
||||
physicalBlobInfos := []types.BlobInfo{}
|
||||
physicalBlobInfos := []types.BlobInfo{} // Built reversed
|
||||
layerID := s.image.TopLayer
|
||||
for layerID != "" {
|
||||
layer, err := s.imageRef.transport.store.Layer(layerID)
|
||||
|
|
@ -340,9 +341,10 @@ func (s *storageImageSource) LayerInfosForCopy(ctx context.Context, instanceDige
|
|||
Size: size,
|
||||
MediaType: uncompressedLayerType,
|
||||
}
|
||||
physicalBlobInfos = append([]types.BlobInfo{blobInfo}, physicalBlobInfos...)
|
||||
physicalBlobInfos = append(physicalBlobInfos, blobInfo)
|
||||
layerID = layer.Parent
|
||||
}
|
||||
slices.Reverse(physicalBlobInfos)
|
||||
|
||||
res, err := buildLayerInfosForCopy(man.LayerInfos(), physicalBlobInfos)
|
||||
if err != nil {
|
||||
|
|
|
|||
6
vendor/github.com/containers/image/v5/tarball/tarball_src.go
generated
vendored
6
vendor/github.com/containers/image/v5/tarball/tarball_src.go
generated
vendored
|
|
@ -103,7 +103,7 @@ func (r *tarballReference) NewImageSource(ctx context.Context, sys *types.System
|
|||
}
|
||||
// TODO: This can take quite some time, and should ideally be cancellable using ctx.Done().
|
||||
if _, err := io.Copy(io.Discard, reader); err != nil {
|
||||
return nil, fmt.Errorf("error reading %q: %v", filename, err)
|
||||
return nil, fmt.Errorf("error reading %q: %w", filename, err)
|
||||
}
|
||||
if uncompressed != nil {
|
||||
uncompressed.Close()
|
||||
|
|
@ -152,7 +152,7 @@ func (r *tarballReference) NewImageSource(ctx context.Context, sys *types.System
|
|||
// Encode and digest the image configuration blob.
|
||||
configBytes, err := json.Marshal(&config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error generating configuration blob for %q: %v", strings.Join(r.filenames, separator), err)
|
||||
return nil, fmt.Errorf("error generating configuration blob for %q: %w", strings.Join(r.filenames, separator), err)
|
||||
}
|
||||
configID := digest.Canonical.FromBytes(configBytes)
|
||||
blobs[configID] = tarballBlob{
|
||||
|
|
@ -177,7 +177,7 @@ func (r *tarballReference) NewImageSource(ctx context.Context, sys *types.System
|
|||
// Encode the manifest.
|
||||
manifestBytes, err := json.Marshal(&manifest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error generating manifest for %q: %v", strings.Join(r.filenames, separator), err)
|
||||
return nil, fmt.Errorf("error generating manifest for %q: %w", strings.Join(r.filenames, separator), err)
|
||||
}
|
||||
|
||||
// Return the image.
|
||||
|
|
|
|||
4
vendor/github.com/containers/image/v5/tarball/tarball_transport.go
generated
vendored
4
vendor/github.com/containers/image/v5/tarball/tarball_transport.go
generated
vendored
|
|
@ -38,13 +38,13 @@ func (t *tarballTransport) ParseReference(reference string) (types.ImageReferenc
|
|||
if filename == "-" {
|
||||
stdin, err = io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error buffering stdin: %v", err)
|
||||
return nil, fmt.Errorf("error buffering stdin: %w", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error opening %q: %v", filename, err)
|
||||
return nil, fmt.Errorf("error opening %q: %w", filename, err)
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
|
|
|
|||
1
vendor/github.com/containers/image/v5/types/types.go
generated
vendored
1
vendor/github.com/containers/image/v5/types/types.go
generated
vendored
|
|
@ -643,6 +643,7 @@ type SystemContext struct {
|
|||
// if true, a V1 ping attempt isn't done to give users a better error. Default is false.
|
||||
// Note that this field is used mainly to integrate containers/image into projectatomic/docker
|
||||
// in order to not break any existing docker's integration tests.
|
||||
// Deprecated: The V1 container registry detection is no longer performed, so setting this flag has no effect.
|
||||
DockerDisableV1Ping bool
|
||||
// If true, dockerImageDestination.SupportedManifestMIMETypes will omit the Schema1 media types from the supported list
|
||||
DockerDisableDestSchema1MIMETypes bool
|
||||
|
|
|
|||
4
vendor/github.com/containers/image/v5/version/version.go
generated
vendored
4
vendor/github.com/containers/image/v5/version/version.go
generated
vendored
|
|
@ -6,9 +6,9 @@ const (
|
|||
// VersionMajor is for an API incompatible changes
|
||||
VersionMajor = 5
|
||||
// VersionMinor is for functionality in a backwards-compatible manner
|
||||
VersionMinor = 32
|
||||
VersionMinor = 33
|
||||
// VersionPatch is for backwards-compatible bug fixes
|
||||
VersionPatch = 2
|
||||
VersionPatch = 1
|
||||
|
||||
// VersionDev indicates development branch. Releases will be empty string.
|
||||
VersionDev = ""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue