1
0
mirror of https://github.com/ko-build/ko.git synced 2025-11-06 09:19:12 +02:00

bump go-containerregistry dep (#404)

This commit is contained in:
Jason Hall
2021-07-30 14:11:26 -04:00
committed by GitHub
parent 8c7b9cbb8b
commit 24e371ae56
13 changed files with 107 additions and 27 deletions

2
go.mod
View File

@@ -11,7 +11,7 @@ require (
github.com/go-training/helloworld v0.0.0-20200225145412-ba5f4379d78b
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-cmp v0.5.6
github.com/google/go-containerregistry v0.5.2-0.20210720200529-2f6fbf77f249
github.com/google/go-containerregistry v0.6.0
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect
github.com/klauspost/compress v1.13.1 // indirect
github.com/mattmoor/dep-notify v0.0.0-20190205035814-a45dec370a17

2
go.sum
View File

@@ -389,6 +389,8 @@ github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-containerregistry v0.5.2-0.20210720200529-2f6fbf77f249 h1:vWUL43oVb6y5SS/wXSYirEZZTonXoKn+ac/hUh/QB+U=
github.com/google/go-containerregistry v0.5.2-0.20210720200529-2f6fbf77f249/go.mod h1:euCCtNbZ6tKqi1E72vwDj2xZcN5ttKpZLfa/wSo5iLw=
github.com/google/go-containerregistry v0.6.0 h1:niQ+8XD//kKgArIFwDVBXsWVWbde16LPdHMyNwSC8h4=
github.com/google/go-containerregistry v0.6.0/go.mod h1:euCCtNbZ6tKqi1E72vwDj2xZcN5ttKpZLfa/wSo5iLw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=

View File

@@ -17,7 +17,9 @@
package verify
import (
"bytes"
"encoding/hex"
"errors"
"fmt"
"hash"
"io"
@@ -81,3 +83,25 @@ func ReadCloser(r io.ReadCloser, size int64, h v1.Hash) (io.ReadCloser, error) {
CloseFunc: r.Close,
}, nil
}
// Descriptor verifies that the embedded Data field matches the Size and Digest
// fields of the given v1.Descriptor, returning an error if the Data field is
// missing or if it contains incorrect data.
func Descriptor(d v1.Descriptor) error {
if d.Data == nil {
return errors.New("error verifying descriptor; Data == nil")
}
h, sz, err := v1.SHA256(bytes.NewReader(d.Data))
if err != nil {
return err
}
if h != d.Digest {
return fmt.Errorf("error verifying Digest; got %q, want %q", h, d.Digest)
}
if sz != d.Size {
return fmt.Errorf("error verifying Size; got %d, want %d", sz, d.Size)
}
return nil
}

View File

@@ -43,6 +43,7 @@ type Descriptor struct {
MediaType types.MediaType `json:"mediaType"`
Size int64 `json:"size"`
Digest Hash `json:"digest"`
Data []byte `json:"data,omitempty"`
URLs []string `json:"urls,omitempty"`
Annotations map[string]string `json:"annotations,omitempty"`
Platform *Platform `json:"platform,omitempty"`

View File

@@ -130,6 +130,11 @@ func (i *image) compute() error {
manifest.Config.Digest = d
manifest.Config.Size = sz
// If Data was set in the base image, we need to update it in the mutated image.
if m.Config.Data != nil {
manifest.Config.Data = rcfg
}
// With OCI media types, this should not be set, see discussion:
// https://github.com/opencontainers/image-spec/pull/795
if i.mediaType != nil {

View File

@@ -51,6 +51,9 @@ func computeDescriptor(ia IndexAddendum) (*v1.Descriptor, error) {
if len(ia.Descriptor.Annotations) != 0 {
desc.Annotations = ia.Descriptor.Annotations
}
if ia.Descriptor.Data != nil {
desc.Data = ia.Descriptor.Data
}
return desc, nil
}

View File

@@ -91,7 +91,9 @@ func Catalog(ctx context.Context, target name.Registry, options ...Option) ([]st
Scheme: target.Scheme(),
Host: target.RegistryStr(),
Path: "/v2/_catalog",
RawQuery: "n=10000",
// ECR returns an error if n > 1000:
// https://github.com/google/go-containerregistry/issues/1091
RawQuery: "n=1000",
}
client := http.Client{Transport: tr}

View File

@@ -15,6 +15,7 @@
package remote
import (
"bytes"
"io"
"io/ioutil"
"net/http"
@@ -100,6 +101,14 @@ func (r *remoteImage) RawConfigFile() ([]byte, error) {
return nil, err
}
if m.Config.Data != nil {
if err := verify.Descriptor(m.Config); err != nil {
return nil, err
}
r.config = m.Config.Data
return r.config, nil
}
body, err := r.fetchBlob(r.context, m.Config.Size, m.Config.Digest)
if err != nil {
return nil, err
@@ -143,6 +152,10 @@ func (rl *remoteImageLayer) Compressed() (io.ReadCloser, error) {
return nil, err
}
if d.Data != nil {
return verify.ReadCloser(ioutil.NopCloser(bytes.NewReader(d.Data)), d.Size, d.Digest)
}
// We don't want to log binary layers -- this can break terminals.
ctx := redact.NewContext(rl.ri.context, "omitting binary blobs from logs")

View File

@@ -19,6 +19,7 @@ import (
"fmt"
"sync"
"github.com/google/go-containerregistry/internal/verify"
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/partial"
@@ -198,10 +199,21 @@ func (r *remoteIndex) childByHash(h v1.Hash) (*Descriptor, error) {
// Convert one of this index's child's v1.Descriptor into a remote.Descriptor, with the given platform option.
func (r *remoteIndex) childDescriptor(child v1.Descriptor, platform v1.Platform) (*Descriptor, error) {
ref := r.Ref.Context().Digest(child.Digest.String())
manifest, _, err := r.fetchManifest(ref, []types.MediaType{child.MediaType})
var (
manifest []byte
err error
)
if child.Data != nil {
if err := verify.Descriptor(child); err != nil {
return nil, err
}
manifest = child.Data
} else {
manifest, _, err = r.fetchManifest(ref, []types.MediaType{child.MediaType})
if err != nil {
return nil, err
}
}
return &Descriptor{
fetcher: fetcher{
Ref: ref,

View File

@@ -31,14 +31,16 @@ type tags struct {
Tags []string `json:"tags"`
}
// List wraps ListWithContext using the background context.
func List(repo name.Repository, options ...Option) ([]string, error) {
return ListWithContext(context.Background(), repo, options...)
// ListWithContext calls List with the given context.
//
// Deprecated: Use List and WithContext. This will be removed in a future release.
func ListWithContext(ctx context.Context, repo name.Repository, options ...Option) ([]string, error) {
return List(repo, append(options, WithContext(ctx))...)
}
// ListWithContext calls /tags/list for the given repository, returning the list of tags
// List calls /tags/list for the given repository, returning the list of tags
// in the "tags" property.
func ListWithContext(ctx context.Context, repo name.Repository, options ...Option) ([]string, error) {
func List(repo name.Repository, options ...Option) ([]string, error) {
o, err := makeOptions(repo, options...)
if err != nil {
return nil, err
@@ -58,13 +60,6 @@ func ListWithContext(ctx context.Context, repo name.Repository, options ...Optio
RawQuery: "n=1000",
}
// This is lazy, but I want to make sure List(..., WithContext(ctx)) works
// without calling makeOptions() twice (which can have side effects).
// This means ListWithContext(ctx, ..., WithContext(ctx2)) prefers ctx2.
if o.context != context.Background() {
ctx = o.context
}
client := http.Client{Transport: tr}
tagList := []string{}
parsed := tags{}
@@ -72,16 +67,15 @@ func ListWithContext(ctx context.Context, repo name.Repository, options ...Optio
// get responses until there is no next page
for {
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-o.context.Done():
return nil, o.context.Err()
default:
}
req, err := http.NewRequest("GET", uri.String(), nil)
req, err := http.NewRequestWithContext(o.context, "GET", uri.String(), nil)
if err != nil {
return nil, err
}
req = req.WithContext(ctx)
resp, err := client.Do(req)
if err != nil {

View File

@@ -108,8 +108,8 @@ func ping(ctx context.Context, reg name.Registry, t http.RoundTripper) (*pingRes
}, nil
case http.StatusUnauthorized:
if challenges := authchallenge.ResponseChallenges(resp); len(challenges) != 0 {
// If we hit more than one, I'm not even sure what to do.
wac := challenges[0]
// If we hit more than one, let's try to find one that we know how to handle.
wac := pickFromMultipleChallenges(challenges)
return &pingResp{
challenge: challenge(wac.Scheme).Canonical(),
parameters: wac.Parameters,
@@ -127,3 +127,22 @@ func ping(ctx context.Context, reg name.Registry, t http.RoundTripper) (*pingRes
}
return nil, errors.New(strings.Join(errs, "; "))
}
func pickFromMultipleChallenges(challenges []authchallenge.Challenge) authchallenge.Challenge {
// It might happen there are multiple www-authenticate headers, e.g. `Negotiate` and `Basic`.
// Picking simply the first one could result eventually in `unrecognized challenge` error,
// that's why we're looping through the challenges in search for one that can be handled.
allowedSchemes := []string{"basic", "bearer"}
for _, wac := range challenges {
currentScheme := strings.ToLower(wac.Scheme)
for _, allowed := range allowedSchemes {
if allowed == currentScheme {
return wac
}
}
}
return challenges[0]
}

View File

@@ -115,6 +115,11 @@ func (in *ConfigFile) DeepCopy() *ConfigFile {
func (in *Descriptor) DeepCopyInto(out *Descriptor) {
*out = *in
out.Digest = in.Digest
if in.Data != nil {
in, out := &in.Data, &out.Data
*out = make([]byte, len(*in))
copy(*out, *in)
}
if in.URLs != nil {
in, out := &in.URLs, &out.URLs
*out = make([]string, len(*in))

2
vendor/modules.txt vendored
View File

@@ -110,7 +110,7 @@ github.com/google/go-cmp/cmp/internal/diff
github.com/google/go-cmp/cmp/internal/flags
github.com/google/go-cmp/cmp/internal/function
github.com/google/go-cmp/cmp/internal/value
# github.com/google/go-containerregistry v0.5.2-0.20210720200529-2f6fbf77f249
# github.com/google/go-containerregistry v0.6.0
## explicit
github.com/google/go-containerregistry/cmd/crane/cmd
github.com/google/go-containerregistry/internal/and