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 = ""
|
||||
|
|
|
|||
78
vendor/github.com/osbuild/images/pkg/container/resolver.go
generated
vendored
78
vendor/github.com/osbuild/images/pkg/container/resolver.go
generated
vendored
|
|
@ -12,7 +12,12 @@ type resolveResult struct {
|
|||
err error
|
||||
}
|
||||
|
||||
type Resolver struct {
|
||||
type Resolver interface {
|
||||
Add(spec SourceSpec)
|
||||
Finish() ([]Spec, error)
|
||||
}
|
||||
|
||||
type asyncResolver struct {
|
||||
jobs int
|
||||
queue chan resolveResult
|
||||
|
||||
|
|
@ -33,8 +38,10 @@ type SourceSpec struct {
|
|||
}
|
||||
|
||||
// XXX: use arch.Arch here?
|
||||
func NewResolver(arch string) *Resolver {
|
||||
return &Resolver{
|
||||
func NewResolver(arch string) *asyncResolver {
|
||||
// NOTE: this should return the Resolver interface, but osbuild-composer
|
||||
// sets the AuthFilePath and for now we don't want to break the API.
|
||||
return &asyncResolver{
|
||||
ctx: context.Background(),
|
||||
queue: make(chan resolveResult, 2),
|
||||
Arch: arch,
|
||||
|
|
@ -43,7 +50,7 @@ func NewResolver(arch string) *Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *Resolver) Add(spec SourceSpec) {
|
||||
func (r *asyncResolver) Add(spec SourceSpec) {
|
||||
client, err := r.newClient(spec.Source)
|
||||
r.jobs += 1
|
||||
|
||||
|
|
@ -67,7 +74,7 @@ func (r *Resolver) Add(spec SourceSpec) {
|
|||
}()
|
||||
}
|
||||
|
||||
func (r *Resolver) Finish() ([]Spec, error) {
|
||||
func (r *asyncResolver) Finish() ([]Spec, error) {
|
||||
|
||||
specs := make([]Spec, 0, r.jobs)
|
||||
errs := make([]string, 0, r.jobs)
|
||||
|
|
@ -92,3 +99,64 @@ func (r *Resolver) Finish() ([]Spec, error) {
|
|||
|
||||
return specs, nil
|
||||
}
|
||||
|
||||
type blockingResolver struct {
|
||||
Arch string
|
||||
AuthFilePath string
|
||||
|
||||
newClient func(string) (*Client, error)
|
||||
|
||||
results []resolveResult
|
||||
}
|
||||
|
||||
// NewBlockingResolver returns a [asyncResolver] that resolves container refs
|
||||
// synchronously (blocking).
|
||||
// TODO: Make this the only resolver after all clients have migrated to this.
|
||||
func NewBlockingResolver(arch string) Resolver {
|
||||
return &blockingResolver{
|
||||
Arch: arch,
|
||||
newClient: NewClient,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *blockingResolver) Add(src SourceSpec) {
|
||||
client, err := r.newClient(src.Source)
|
||||
if err != nil {
|
||||
r.results = append(r.results, resolveResult{err: err})
|
||||
return
|
||||
}
|
||||
|
||||
client.SetTLSVerify(src.TLSVerify)
|
||||
client.SetArchitectureChoice(r.Arch)
|
||||
if r.AuthFilePath != "" {
|
||||
client.SetAuthFilePath(r.AuthFilePath)
|
||||
}
|
||||
|
||||
spec, err := client.Resolve(context.TODO(), src.Name, src.Local)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("'%s': %w", src.Source, err)
|
||||
}
|
||||
r.results = append(r.results, resolveResult{spec: spec, err: err})
|
||||
}
|
||||
|
||||
func (r *blockingResolver) Finish() ([]Spec, error) {
|
||||
specs := make([]Spec, 0, len(r.results))
|
||||
errs := make([]string, 0, len(r.results))
|
||||
for _, result := range r.results {
|
||||
if result.err == nil {
|
||||
specs = append(specs, result.spec)
|
||||
} else {
|
||||
errs = append(errs, result.err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
detail := strings.Join(errs, "; ")
|
||||
return specs, fmt.Errorf("failed to resolve container: %s", detail)
|
||||
}
|
||||
|
||||
// Return a stable result, sorted by Digest
|
||||
sort.Slice(specs, func(i, j int) bool { return specs[i].Digest < specs[j].Digest })
|
||||
|
||||
return specs, nil
|
||||
}
|
||||
|
|
|
|||
5
vendor/github.com/osbuild/images/pkg/distro/distro.go
generated
vendored
5
vendor/github.com/osbuild/images/pkg/distro/distro.go
generated
vendored
|
|
@ -1,7 +1,7 @@
|
|||
package distro
|
||||
|
||||
import (
|
||||
"time"
|
||||
"math/rand"
|
||||
|
||||
"github.com/osbuild/images/pkg/blueprint"
|
||||
"github.com/osbuild/images/pkg/customizations/subscription"
|
||||
|
|
@ -162,7 +162,8 @@ func PayloadPackageSets() []string {
|
|||
|
||||
func SeedFrom(p *int64) int64 {
|
||||
if p == nil {
|
||||
return time.Now().UnixNano()
|
||||
// #nosec G404
|
||||
return rand.Int63()
|
||||
}
|
||||
return *p
|
||||
}
|
||||
|
|
|
|||
1
vendor/github.com/osbuild/images/pkg/distro/rhel/rhel10/bare_metal.go
generated
vendored
1
vendor/github.com/osbuild/images/pkg/distro/rhel/rhel10/bare_metal.go
generated
vendored
|
|
@ -190,6 +190,7 @@ func anacondaPackageSet(t *rhel.ImageType) rpmmd.PackageSet {
|
|||
|
||||
ps = ps.Append(rpmmd.PackageSet{
|
||||
Include: []string{
|
||||
"@hardware-support",
|
||||
"alsa-firmware",
|
||||
"alsa-tools-firmware",
|
||||
"anaconda",
|
||||
|
|
|
|||
1
vendor/github.com/osbuild/images/pkg/distro/rhel/rhel9/edge.go
generated
vendored
1
vendor/github.com/osbuild/images/pkg/distro/rhel/rhel9/edge.go
generated
vendored
|
|
@ -710,6 +710,7 @@ func edgeCommitPackageSet(t *rhel.ImageType) rpmmd.PackageSet {
|
|||
},
|
||||
Exclude: []string{
|
||||
"rng-tools",
|
||||
"bootupd",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
24
vendor/github.com/osbuild/images/pkg/dnfjson/dnfjson.go
generated
vendored
24
vendor/github.com/osbuild/images/pkg/dnfjson/dnfjson.go
generated
vendored
|
|
@ -18,6 +18,7 @@ import (
|
|||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
|
@ -154,6 +155,14 @@ type Solver struct {
|
|||
proxy string
|
||||
|
||||
subscriptions *rhsm.Subscriptions
|
||||
|
||||
// Stderr is the stderr output from dnfjson, if unset os.Stderr
|
||||
// will be used.
|
||||
//
|
||||
// XXX: ideally this would not be public but just passed via
|
||||
// NewSolver() but it already has 5 args so ideally we would
|
||||
// add a SolverOptions struct here with "CacheDir" and "Stderr"?
|
||||
Stderr io.Writer
|
||||
}
|
||||
|
||||
// DepsolveResult contains the results of a depsolve operation.
|
||||
|
|
@ -212,7 +221,7 @@ func (s *Solver) Depsolve(pkgSets []rpmmd.PackageSet, sbomType sbom.StandardType
|
|||
s.cache.locker.RLock()
|
||||
defer s.cache.locker.RUnlock()
|
||||
|
||||
output, err := run(s.dnfJsonCmd, req)
|
||||
output, err := run(s.dnfJsonCmd, req, s.Stderr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("running osbuild-depsolve-dnf failed:\n%w", err)
|
||||
}
|
||||
|
|
@ -266,7 +275,7 @@ func (s *Solver) FetchMetadata(repos []rpmmd.RepoConfig) (rpmmd.PackageList, err
|
|||
return pkgs, nil
|
||||
}
|
||||
|
||||
result, err := run(s.dnfJsonCmd, req)
|
||||
result, err := run(s.dnfJsonCmd, req, s.Stderr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -312,7 +321,7 @@ func (s *Solver) SearchMetadata(repos []rpmmd.RepoConfig, packages []string) (rp
|
|||
return pkgs, nil
|
||||
}
|
||||
|
||||
result, err := run(s.dnfJsonCmd, req)
|
||||
result, err := run(s.dnfJsonCmd, req, s.Stderr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -835,7 +844,7 @@ func ParseError(data []byte) Error {
|
|||
return e
|
||||
}
|
||||
|
||||
func run(dnfJsonCmd []string, req *Request) ([]byte, error) {
|
||||
func run(dnfJsonCmd []string, req *Request, stderr io.Writer) ([]byte, error) {
|
||||
if len(dnfJsonCmd) == 0 {
|
||||
dnfJsonCmd = []string{findDepsolveDnf()}
|
||||
}
|
||||
|
|
@ -853,7 +862,11 @@ func run(dnfJsonCmd []string, req *Request) ([]byte, error) {
|
|||
return nil, fmt.Errorf("creating stdin pipe for %s failed: %w", ex, err)
|
||||
}
|
||||
|
||||
cmd.Stderr = os.Stderr
|
||||
if stderr != nil {
|
||||
cmd.Stderr = stderr
|
||||
} else {
|
||||
cmd.Stderr = os.Stderr
|
||||
}
|
||||
stdout := new(bytes.Buffer)
|
||||
cmd.Stdout = stdout
|
||||
|
||||
|
|
@ -873,6 +886,5 @@ func run(dnfJsonCmd []string, req *Request) ([]byte, error) {
|
|||
if runError, ok := err.(*exec.ExitError); ok && runError.ExitCode() != 0 {
|
||||
return nil, parseError(output, req.Arguments.Repos)
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
|
|
|||
8
vendor/github.com/osbuild/images/pkg/manifest/ostree_deployment.go
generated
vendored
8
vendor/github.com/osbuild/images/pkg/manifest/ostree_deployment.go
generated
vendored
|
|
@ -513,13 +513,13 @@ func createMountpointService(serviceName string, mountpoints []string) *osbuild.
|
|||
for _, mountpoint := range mountpoints {
|
||||
conditionPathIsDirectory = append(conditionPathIsDirectory, "|!"+mountpoint)
|
||||
}
|
||||
unit := osbuild.Unit{
|
||||
unit := osbuild.UnitSection{
|
||||
Description: "Ensure custom filesystem mountpoints exist",
|
||||
DefaultDependencies: common.ToPtr(false), // Default dependencies would interfere with our custom order (before mountpoints)
|
||||
ConditionPathIsDirectory: conditionPathIsDirectory,
|
||||
After: []string{"ostree-remount.service"},
|
||||
}
|
||||
service := osbuild.Service{
|
||||
service := osbuild.ServiceSection{
|
||||
Type: osbuild.OneshotServiceType,
|
||||
RemainAfterExit: false,
|
||||
// compatibility with composefs, will require transient rootfs to be enabled too.
|
||||
|
|
@ -541,14 +541,14 @@ func createMountpointService(serviceName string, mountpoints []string) *osbuild.
|
|||
}
|
||||
unit.Before = befores
|
||||
|
||||
install := osbuild.Install{
|
||||
install := osbuild.InstallSection{
|
||||
WantedBy: []string{"local-fs.target"},
|
||||
}
|
||||
options := osbuild.SystemdUnitCreateStageOptions{
|
||||
Filename: serviceName,
|
||||
UnitPath: osbuild.EtcUnitPath,
|
||||
UnitType: osbuild.System,
|
||||
Config: osbuild.SystemdServiceUnit{
|
||||
Config: osbuild.SystemdUnit{
|
||||
Unit: &unit,
|
||||
Service: &service,
|
||||
Install: &install,
|
||||
|
|
|
|||
8
vendor/github.com/osbuild/images/pkg/manifest/subscription.go
generated
vendored
8
vendor/github.com/osbuild/images/pkg/manifest/subscription.go
generated
vendored
|
|
@ -156,20 +156,20 @@ func subscriptionService(subscriptionOptions subscription.ImageOptions, serviceO
|
|||
Filename: subscribeServiceFile,
|
||||
UnitType: "system",
|
||||
UnitPath: unitPath,
|
||||
Config: osbuild.SystemdServiceUnit{
|
||||
Unit: &osbuild.Unit{
|
||||
Config: osbuild.SystemdUnit{
|
||||
Unit: &osbuild.UnitSection{
|
||||
Description: "First-boot service for registering with Red Hat subscription manager and/or insights",
|
||||
ConditionPathExists: []string{subkeyFilepath},
|
||||
Wants: []string{"network-online.target"},
|
||||
After: []string{"network-online.target"},
|
||||
},
|
||||
Service: &osbuild.Service{
|
||||
Service: &osbuild.ServiceSection{
|
||||
Type: osbuild.OneshotServiceType,
|
||||
RemainAfterExit: false,
|
||||
ExecStart: commands,
|
||||
EnvironmentFile: []string{subkeyFilepath},
|
||||
},
|
||||
Install: &osbuild.Install{
|
||||
Install: &osbuild.InstallSection{
|
||||
WantedBy: []string{"default.target"},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
118
vendor/github.com/osbuild/images/pkg/osbuild/systemd_unit_create_stage.go
generated
vendored
118
vendor/github.com/osbuild/images/pkg/osbuild/systemd_unit_create_stage.go
generated
vendored
|
|
@ -2,6 +2,7 @@ package osbuild
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
|
|
@ -22,7 +23,7 @@ const (
|
|||
UsrUnitPath SystemdUnitPath = "usr"
|
||||
)
|
||||
|
||||
type Unit struct {
|
||||
type UnitSection struct {
|
||||
Description string `json:"Description,omitempty"`
|
||||
DefaultDependencies *bool `json:"DefaultDependencies,omitempty"`
|
||||
ConditionPathExists []string `json:"ConditionPathExists,omitempty"`
|
||||
|
|
@ -33,7 +34,7 @@ type Unit struct {
|
|||
Before []string `json:"Before,omitempty"`
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
type ServiceSection struct {
|
||||
Type SystemdServiceType `json:"Type,omitempty"`
|
||||
RemainAfterExit bool `json:"RemainAfterExit,omitempty"`
|
||||
ExecStartPre []string `json:"ExecStartPre,omitempty"`
|
||||
|
|
@ -43,34 +44,63 @@ type Service struct {
|
|||
EnvironmentFile []string `json:"EnvironmentFile,omitempty"`
|
||||
}
|
||||
|
||||
type Install struct {
|
||||
type MountSection struct {
|
||||
What string `json:"What"`
|
||||
Where string `json:"Where"`
|
||||
Type string `json:"Type,omitempty"`
|
||||
Options string `json:"Options,omitempty"`
|
||||
}
|
||||
|
||||
type SocketSection struct {
|
||||
Service string `json:"Service,omitempty"`
|
||||
ListenStream string `json:"ListenStream,omitempty"`
|
||||
ListenDatagram string `json:"ListenDatagram,omitempty"`
|
||||
ListenSequentialPacket string `json:"ListenSequentialPacket,omitempty"`
|
||||
ListenFifo string `json:"ListenFifo,omitempty"`
|
||||
SocketUser string `json:"SocketUser,omitempty"`
|
||||
SocketGroup string `json:"SocketGroup,omitempty"`
|
||||
SocketMode string `json:"SocketMode,omitempty"`
|
||||
DirectoryMode string `json:"DirectoryMode,omitempty"`
|
||||
Accept string `json:"Accept,omitempty"`
|
||||
RuntimeDirectory string `json:"RuntimeDirectory,omitempty"`
|
||||
RemoveOnStop string `json:"RemoveOnStop,omitempty"`
|
||||
}
|
||||
|
||||
type InstallSection struct {
|
||||
RequiredBy []string `json:"RequiredBy,omitempty"`
|
||||
WantedBy []string `json:"WantedBy,omitempty"`
|
||||
}
|
||||
|
||||
type SystemdServiceUnit struct {
|
||||
Unit *Unit `json:"Unit"`
|
||||
Service *Service `json:"Service"`
|
||||
Install *Install `json:"Install"`
|
||||
type SystemdUnit struct {
|
||||
Unit *UnitSection `json:"Unit"`
|
||||
Service *ServiceSection `json:"Service"`
|
||||
Mount *MountSection `json:"Mount,omitempty"`
|
||||
Socket *SocketSection `json:"Socket,omitempty"`
|
||||
Install *InstallSection `json:"Install"`
|
||||
}
|
||||
|
||||
type SystemdUnitCreateStageOptions struct {
|
||||
Filename string `json:"filename"`
|
||||
UnitType unitType `json:"unit-type,omitempty"` // unitType defined in ./systemd_unit_stage.go
|
||||
UnitPath SystemdUnitPath `json:"unit-path,omitempty"`
|
||||
Config SystemdServiceUnit `json:"config"`
|
||||
Filename string `json:"filename"`
|
||||
UnitType unitType `json:"unit-type,omitempty"` // unitType defined in ./systemd_unit_stage.go
|
||||
UnitPath SystemdUnitPath `json:"unit-path,omitempty"`
|
||||
Config SystemdUnit `json:"config"`
|
||||
}
|
||||
|
||||
func (SystemdUnitCreateStageOptions) isStageOptions() {}
|
||||
|
||||
func (o *SystemdUnitCreateStageOptions) validate() error {
|
||||
fre := regexp.MustCompile(filenameRegex)
|
||||
if !fre.MatchString(o.Filename) {
|
||||
return fmt.Errorf("filename %q doesn't conform to schema (%s)", o.Filename, filenameRegex)
|
||||
func (o *SystemdUnitCreateStageOptions) validateService() error {
|
||||
if o.Config.Service == nil {
|
||||
return fmt.Errorf("systemd service unit %q requires a Service section", o.Filename)
|
||||
}
|
||||
if o.Config.Install == nil {
|
||||
return fmt.Errorf("systemd service unit %q requires an Install section", o.Filename)
|
||||
}
|
||||
|
||||
if o.Config.Install == nil {
|
||||
return fmt.Errorf("Install section of systemd unit is required")
|
||||
if o.Config.Mount != nil {
|
||||
return fmt.Errorf("systemd service unit %q contains invalid section Mount", o.Filename)
|
||||
}
|
||||
if o.Config.Socket != nil {
|
||||
return fmt.Errorf("systemd service unit %q contains invalid section Socket", o.Filename)
|
||||
}
|
||||
|
||||
vre := regexp.MustCompile(envVarRegex)
|
||||
|
|
@ -81,9 +111,63 @@ func (o *SystemdUnitCreateStageOptions) validate() error {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *SystemdUnitCreateStageOptions) validateMount() error {
|
||||
if o.Config.Mount == nil {
|
||||
return fmt.Errorf("systemd mount unit %q requires a Mount section", o.Filename)
|
||||
}
|
||||
if o.Config.Service != nil {
|
||||
return fmt.Errorf("systemd mount unit %q contains invalid section Service", o.Filename)
|
||||
}
|
||||
if o.Config.Socket != nil {
|
||||
return fmt.Errorf("systemd mount unit %q contains invalid section Socket", o.Filename)
|
||||
}
|
||||
|
||||
if o.Config.Mount.What == "" {
|
||||
return fmt.Errorf("What option for Mount section of systemd unit %q is required", o.Filename)
|
||||
}
|
||||
|
||||
if o.Config.Mount.Where == "" {
|
||||
return fmt.Errorf("Where option for Mount section of systemd unit %q is required", o.Filename)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func (o *SystemdUnitCreateStageOptions) validateSocket() error {
|
||||
if o.Config.Socket == nil {
|
||||
return fmt.Errorf("systemd socket unit %q requires a Socket section", o.Filename)
|
||||
}
|
||||
if o.Config.Mount != nil {
|
||||
return fmt.Errorf("systemd socket unit %q contains invalid section Mount", o.Filename)
|
||||
}
|
||||
if o.Config.Service != nil {
|
||||
return fmt.Errorf("systemd socket unit %q contains invalid section Service", o.Filename)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *SystemdUnitCreateStageOptions) validate() error {
|
||||
fre := regexp.MustCompile(filenameRegex)
|
||||
if !fre.MatchString(o.Filename) {
|
||||
return fmt.Errorf("invalid filename %q for systemd unit: does not conform to schema (%s)", o.Filename, filenameRegex)
|
||||
}
|
||||
|
||||
switch filepath.Ext(o.Filename) {
|
||||
case ".service":
|
||||
return o.validateService()
|
||||
case ".mount":
|
||||
return o.validateMount()
|
||||
case ".socket":
|
||||
return o.validateSocket()
|
||||
default:
|
||||
return fmt.Errorf("invalid filename %q for systemd unit: extension must be one of .service, .mount, or .socket", o.Filename)
|
||||
}
|
||||
}
|
||||
|
||||
func NewSystemdUnitCreateStage(options *SystemdUnitCreateStageOptions) *Stage {
|
||||
if err := options.validate(); err != nil {
|
||||
panic(err)
|
||||
|
|
|
|||
46
vendor/github.com/osbuild/images/pkg/policies/policies.go
generated
vendored
46
vendor/github.com/osbuild/images/pkg/policies/policies.go
generated
vendored
|
|
@ -50,6 +50,7 @@ var CustomDirectoriesPolicies = pathpolicy.NewPathPolicies(map[string]pathpolicy
|
|||
"/sysroot": {Deny: true},
|
||||
"/tmp": {Deny: true},
|
||||
"/usr": {Deny: true},
|
||||
"/usr/local": {},
|
||||
"/var/run": {Deny: true},
|
||||
"/var/tmp": {Deny: true},
|
||||
"/efi": {Deny: true},
|
||||
|
|
@ -57,29 +58,28 @@ var CustomDirectoriesPolicies = pathpolicy.NewPathPolicies(map[string]pathpolicy
|
|||
|
||||
// CustomFilesPolicies is a set of default policies for custom files
|
||||
var CustomFilesPolicies = pathpolicy.NewPathPolicies(map[string]pathpolicy.PathPolicy{
|
||||
"/": {},
|
||||
"/usr/local/bin": {},
|
||||
"/usr/local/sbin": {},
|
||||
"/bin": {Deny: true},
|
||||
"/boot": {Deny: true},
|
||||
"/dev": {Deny: true},
|
||||
"/efi": {Deny: true},
|
||||
"/etc/fstab": {Deny: true},
|
||||
"/etc/group": {Deny: true},
|
||||
"/etc/passwd": {Deny: true},
|
||||
"/etc/shadow": {Deny: true},
|
||||
"/lib": {Deny: true},
|
||||
"/lib64": {Deny: true},
|
||||
"/lost+found": {Deny: true},
|
||||
"/proc": {Deny: true},
|
||||
"/run": {Deny: true},
|
||||
"/sbin": {Deny: true},
|
||||
"/sys": {Deny: true},
|
||||
"/sysroot": {Deny: true},
|
||||
"/tmp": {Deny: true},
|
||||
"/usr": {Deny: true},
|
||||
"/var/run": {Deny: true},
|
||||
"/var/tmp": {Deny: true},
|
||||
"/": {},
|
||||
"/bin": {Deny: true},
|
||||
"/boot": {Deny: true},
|
||||
"/dev": {Deny: true},
|
||||
"/efi": {Deny: true},
|
||||
"/etc/fstab": {Deny: true},
|
||||
"/etc/group": {Deny: true},
|
||||
"/etc/passwd": {Deny: true},
|
||||
"/etc/shadow": {Deny: true},
|
||||
"/lib": {Deny: true},
|
||||
"/lib64": {Deny: true},
|
||||
"/lost+found": {Deny: true},
|
||||
"/proc": {Deny: true},
|
||||
"/run": {Deny: true},
|
||||
"/sbin": {Deny: true},
|
||||
"/sys": {Deny: true},
|
||||
"/sysroot": {Deny: true},
|
||||
"/tmp": {Deny: true},
|
||||
"/usr": {Deny: true},
|
||||
"/usr/local": {},
|
||||
"/var/run": {Deny: true},
|
||||
"/var/tmp": {Deny: true},
|
||||
})
|
||||
|
||||
// MountpointPolicies for ostree
|
||||
|
|
|
|||
38
vendor/github.com/sigstore/fulcio/pkg/certificate/extensions.go
generated
vendored
38
vendor/github.com/sigstore/fulcio/pkg/certificate/extensions.go
generated
vendored
|
|
@ -69,69 +69,69 @@ type Extensions struct {
|
|||
// Deprecated
|
||||
// Triggering event of the Github Workflow. Matches the `event_name` claim of ID
|
||||
// tokens from Github Actions
|
||||
GithubWorkflowTrigger string // OID 1.3.6.1.4.1.57264.1.2
|
||||
GithubWorkflowTrigger string `json:"GithubWorkflowTrigger,omitempty" yaml:"github-workflow-trigger,omitempty"` // OID 1.3.6.1.4.1.57264.1.2
|
||||
|
||||
// Deprecated
|
||||
// SHA of git commit being built in Github Actions. Matches the `sha` claim of ID
|
||||
// tokens from Github Actions
|
||||
GithubWorkflowSHA string // OID 1.3.6.1.4.1.57264.1.3
|
||||
GithubWorkflowSHA string `json:"GithubWorkflowSHA,omitempty" yaml:"github-workflow-sha,omitempty"` // OID 1.3.6.1.4.1.57264.1.3
|
||||
|
||||
// Deprecated
|
||||
// Name of Github Actions Workflow. Matches the `workflow` claim of the ID
|
||||
// tokens from Github Actions
|
||||
GithubWorkflowName string // OID 1.3.6.1.4.1.57264.1.4
|
||||
GithubWorkflowName string `json:"GithubWorkflowName,omitempty" yaml:"github-workflow-name,omitempty"` // OID 1.3.6.1.4.1.57264.1.4
|
||||
|
||||
// Deprecated
|
||||
// Repository of the Github Actions Workflow. Matches the `repository` claim of the ID
|
||||
// tokens from Github Actions
|
||||
GithubWorkflowRepository string // OID 1.3.6.1.4.1.57264.1.5
|
||||
GithubWorkflowRepository string `json:"GithubWorkflowRepository,omitempty" yaml:"github-workflow-repository,omitempty"` // OID 1.3.6.1.4.1.57264.1.5
|
||||
|
||||
// Deprecated
|
||||
// Git Ref of the Github Actions Workflow. Matches the `ref` claim of the ID tokens
|
||||
// from Github Actions
|
||||
GithubWorkflowRef string // 1.3.6.1.4.1.57264.1.6
|
||||
GithubWorkflowRef string `json:"GithubWorkflowRef,omitempty" yaml:"github-workflow-ref,omitempty"` // 1.3.6.1.4.1.57264.1.6
|
||||
|
||||
// Reference to specific build instructions that are responsible for signing.
|
||||
BuildSignerURI string // 1.3.6.1.4.1.57264.1.9
|
||||
BuildSignerURI string `json:"BuildSignerURI,omitempty" yaml:"build-signer-uri,omitempty"` // 1.3.6.1.4.1.57264.1.9
|
||||
|
||||
// Immutable reference to the specific version of the build instructions that is responsible for signing.
|
||||
BuildSignerDigest string // 1.3.6.1.4.1.57264.1.10
|
||||
BuildSignerDigest string `json:"BuildSignerDigest,omitempty" yaml:"build-signer-digest,omitempty"` // 1.3.6.1.4.1.57264.1.10
|
||||
|
||||
// Specifies whether the build took place in platform-hosted cloud infrastructure or customer/self-hosted infrastructure.
|
||||
RunnerEnvironment string // 1.3.6.1.4.1.57264.1.11
|
||||
RunnerEnvironment string `json:"RunnerEnvironment,omitempty" yaml:"runner-environment,omitempty"` // 1.3.6.1.4.1.57264.1.11
|
||||
|
||||
// Source repository URL that the build was based on.
|
||||
SourceRepositoryURI string // 1.3.6.1.4.1.57264.1.12
|
||||
SourceRepositoryURI string `json:"SourceRepositoryURI,omitempty" yaml:"source-repository-uri,omitempty"` // 1.3.6.1.4.1.57264.1.12
|
||||
|
||||
// Immutable reference to a specific version of the source code that the build was based upon.
|
||||
SourceRepositoryDigest string // 1.3.6.1.4.1.57264.1.13
|
||||
SourceRepositoryDigest string `json:"SourceRepositoryDigest,omitempty" yaml:"source-repository-digest,omitempty"` // 1.3.6.1.4.1.57264.1.13
|
||||
|
||||
// Source Repository Ref that the build run was based upon.
|
||||
SourceRepositoryRef string // 1.3.6.1.4.1.57264.1.14
|
||||
SourceRepositoryRef string `json:"SourceRepositoryRef,omitempty" yaml:"source-repository-ref,omitempty"` // 1.3.6.1.4.1.57264.1.14
|
||||
|
||||
// Immutable identifier for the source repository the workflow was based upon.
|
||||
SourceRepositoryIdentifier string // 1.3.6.1.4.1.57264.1.15
|
||||
SourceRepositoryIdentifier string `json:"SourceRepositoryIdentifier,omitempty" yaml:"source-repository-identifier,omitempty"` // 1.3.6.1.4.1.57264.1.15
|
||||
|
||||
// Source repository owner URL of the owner of the source repository that the build was based on.
|
||||
SourceRepositoryOwnerURI string // 1.3.6.1.4.1.57264.1.16
|
||||
SourceRepositoryOwnerURI string `json:"SourceRepositoryOwnerURI,omitempty" yaml:"source-repository-owner-uri,omitempty"` // 1.3.6.1.4.1.57264.1.16
|
||||
|
||||
// Immutable identifier for the owner of the source repository that the workflow was based upon.
|
||||
SourceRepositoryOwnerIdentifier string // 1.3.6.1.4.1.57264.1.17
|
||||
SourceRepositoryOwnerIdentifier string `json:"SourceRepositoryOwnerIdentifier,omitempty" yaml:"source-repository-owner-identifier,omitempty"` // 1.3.6.1.4.1.57264.1.17
|
||||
|
||||
// Build Config URL to the top-level/initiating build instructions.
|
||||
BuildConfigURI string // 1.3.6.1.4.1.57264.1.18
|
||||
BuildConfigURI string `json:"BuildConfigURI,omitempty" yaml:"build-config-uri,omitempty"` // 1.3.6.1.4.1.57264.1.18
|
||||
|
||||
// Immutable reference to the specific version of the top-level/initiating build instructions.
|
||||
BuildConfigDigest string // 1.3.6.1.4.1.57264.1.19
|
||||
BuildConfigDigest string `json:"BuildConfigDigest,omitempty" yaml:"build-config-digest,omitempty"` // 1.3.6.1.4.1.57264.1.19
|
||||
|
||||
// Event or action that initiated the build.
|
||||
BuildTrigger string // 1.3.6.1.4.1.57264.1.20
|
||||
BuildTrigger string `json:"BuildTrigger,omitempty" yaml:"build-trigger,omitempty"` // 1.3.6.1.4.1.57264.1.20
|
||||
|
||||
// Run Invocation URL to uniquely identify the build execution.
|
||||
RunInvocationURI string // 1.3.6.1.4.1.57264.1.21
|
||||
RunInvocationURI string `json:"RunInvocationURI,omitempty" yaml:"run-invocation-uri,omitempty"` // 1.3.6.1.4.1.57264.1.21
|
||||
|
||||
// Source repository visibility at the time of signing the certificate.
|
||||
SourceRepositoryVisibilityAtSigning string // 1.3.6.1.4.1.57264.1.22
|
||||
SourceRepositoryVisibilityAtSigning string `json:"SourceRepositoryVisibilityAtSigning,omitempty" yaml:"source-repository-visibility-at-signing,omitempty"` // 1.3.6.1.4.1.57264.1.22
|
||||
}
|
||||
|
||||
func (e Extensions) Render() ([]pkix.Extension, error) {
|
||||
|
|
|
|||
6
vendor/github.com/sigstore/sigstore/pkg/cryptoutils/publickey.go
generated
vendored
6
vendor/github.com/sigstore/sigstore/pkg/cryptoutils/publickey.go
generated
vendored
|
|
@ -103,15 +103,15 @@ func EqualKeys(first, second crypto.PublicKey) error {
|
|||
switch pub := first.(type) {
|
||||
case *rsa.PublicKey:
|
||||
if !pub.Equal(second) {
|
||||
return fmt.Errorf(genErrMsg(first, second, "rsa"))
|
||||
return errors.New(genErrMsg(first, second, "rsa"))
|
||||
}
|
||||
case *ecdsa.PublicKey:
|
||||
if !pub.Equal(second) {
|
||||
return fmt.Errorf(genErrMsg(first, second, "ecdsa"))
|
||||
return errors.New(genErrMsg(first, second, "ecdsa"))
|
||||
}
|
||||
case ed25519.PublicKey:
|
||||
if !pub.Equal(second) {
|
||||
return fmt.Errorf(genErrMsg(first, second, "ed25519"))
|
||||
return errors.New(genErrMsg(first, second, "ed25519"))
|
||||
}
|
||||
default:
|
||||
return errors.New("unsupported key type")
|
||||
|
|
|
|||
40
vendor/github.com/sylabs/sif/v2/pkg/sif/create.go
generated
vendored
40
vendor/github.com/sylabs/sif/v2/pkg/sif/create.go
generated
vendored
|
|
@ -12,33 +12,47 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
var errAlignmentOverflow = errors.New("integer overflow when calculating alignment")
|
||||
|
||||
// nextAligned finds the next offset that satisfies alignment.
|
||||
func nextAligned(offset int64, alignment int) int64 {
|
||||
func nextAligned(offset int64, alignment int) (int64, error) {
|
||||
align64 := uint64(alignment)
|
||||
offset64 := uint64(offset)
|
||||
|
||||
if align64 != 0 && offset64%align64 != 0 {
|
||||
offset64 = (offset64 & ^(align64 - 1)) + align64
|
||||
if align64 <= 0 || offset64%align64 == 0 {
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
return int64(offset64)
|
||||
offset64 += (align64 - offset64%align64)
|
||||
|
||||
if offset64 > math.MaxInt64 {
|
||||
return 0, errAlignmentOverflow
|
||||
}
|
||||
|
||||
//nolint:gosec // Overflow handled above.
|
||||
return int64(offset64), nil
|
||||
}
|
||||
|
||||
// writeDataObjectAt writes the data object described by di to ws, using time t, recording details
|
||||
// in d. The object is written at the first position that satisfies the alignment requirements
|
||||
// described by di following offsetUnaligned.
|
||||
func writeDataObjectAt(ws io.WriteSeeker, offsetUnaligned int64, di DescriptorInput, t time.Time, d *rawDescriptor) error { //nolint:lll
|
||||
offset, err := ws.Seek(nextAligned(offsetUnaligned, di.opts.alignment), io.SeekStart)
|
||||
offset, err := nextAligned(offsetUnaligned, di.opts.alignment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := ws.Seek(offset, io.SeekStart); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n, err := io.Copy(ws, di.r)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -72,6 +86,7 @@ func (f *FileImage) calculatedDataSize() int64 {
|
|||
var (
|
||||
errInsufficientCapacity = errors.New("insufficient descriptor capacity to add data object(s) to image")
|
||||
errPrimaryPartition = errors.New("image already contains a primary partition")
|
||||
errObjectIDOverflow = errors.New("object ID would overflow")
|
||||
)
|
||||
|
||||
// writeDataObject writes the data object described by di to f, using time t, recording details in
|
||||
|
|
@ -81,6 +96,11 @@ func (f *FileImage) writeDataObject(i int, di DescriptorInput, t time.Time) erro
|
|||
return errInsufficientCapacity
|
||||
}
|
||||
|
||||
// We derive the ID from i, so make sure the ID will not overflow.
|
||||
if int64(i) >= math.MaxUint32 {
|
||||
return errObjectIDOverflow
|
||||
}
|
||||
|
||||
// If this is a primary partition, verify there isn't another primary partition, and update the
|
||||
// architecture in the global header.
|
||||
if p, ok := di.opts.md.(partition); ok && p.Parttype == PartPrimSys {
|
||||
|
|
@ -92,7 +112,7 @@ func (f *FileImage) writeDataObject(i int, di DescriptorInput, t time.Time) erro
|
|||
}
|
||||
|
||||
d := &f.rds[i]
|
||||
d.ID = uint32(i) + 1
|
||||
d.ID = uint32(i) + 1 //nolint:gosec // Overflow handled above.
|
||||
|
||||
f.h.DataSize = f.calculatedDataSize()
|
||||
|
||||
|
|
@ -213,8 +233,16 @@ func OptCreateWithCloseOnUnload(b bool) CreateOpt {
|
|||
}
|
||||
}
|
||||
|
||||
var errDescriptorCapacityNotSupported = errors.New("descriptor capacity not supported")
|
||||
|
||||
// createContainer creates a new SIF container file in rw, according to opts.
|
||||
func createContainer(rw ReadWriter, co createOpts) (*FileImage, error) {
|
||||
// The supported number of descriptors is limited by the unsigned 32-bit ID field in each
|
||||
// rawDescriptor.
|
||||
if co.descriptorCapacity >= math.MaxUint32 {
|
||||
return nil, errDescriptorCapacityNotSupported
|
||||
}
|
||||
|
||||
rds := make([]rawDescriptor, co.descriptorCapacity)
|
||||
rdsSize := int64(binary.Size(rds))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue