From 6ce3dfb93a5d2998fa7768ebd9ba61334b5b7230 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Mon, 11 Mar 2019 21:44:32 +0100 Subject: [PATCH] Bump go-containerregistry to 8c1640add99804503b4126abc718931a4d93c31a (#609) The main reason is to include the fixes from https://github.com/google/go-containerregistry/pull/401. This should fix the build+push to quay.io (with v2 schema enabled) cases. Signed-off-by: Vincent Demeester --- Gopkg.lock | 4 +- Gopkg.toml | 2 +- .../pkg/v1/empty/index.go | 2 +- .../pkg/v1/remote/image.go | 54 ++++++++++++++++++- .../pkg/v1/remote/options.go | 8 +++ .../pkg/v1/remote/write.go | 5 +- 6 files changed, 67 insertions(+), 8 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 7d5486b54..c15fd937e 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -430,7 +430,7 @@ version = "v0.2.0" [[projects]] - digest = "1:a4f41b57b6a09cf498024fd9d2872b99c32bfc1462a8f34ac625e88531d52930" + digest = "1:3edac9d0a5f7e0e636f85bd7d3105df6180af528ab7e6a88f00b1ae6fc0bf947" name = "github.com/google/go-containerregistry" packages = [ "pkg/authn", @@ -450,7 +450,7 @@ "pkg/v1/v1util", ] pruneopts = "NUT" - revision = "678f6c51f585140f8d0c07f6f7e193f7a4c8e457" + revision = "8c1640add99804503b4126abc718931a4d93c31a" [[projects]] digest = "1:f4f203acd8b11b8747bdcd91696a01dbc95ccb9e2ca2db6abf81c3a4f5e950ce" diff --git a/Gopkg.toml b/Gopkg.toml index 2ab371521..e39d19a01 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -37,7 +37,7 @@ required = [ [[constraint]] name = "github.com/google/go-containerregistry" - revision = "678f6c51f585140f8d0c07f6f7e193f7a4c8e457" + revision = "8c1640add99804503b4126abc718931a4d93c31a" [[override]] name = "k8s.io/apimachinery" diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/empty/index.go b/vendor/github.com/google/go-containerregistry/pkg/v1/empty/index.go index 83dc58ab7..a03d758fd 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/empty/index.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/empty/index.go @@ -18,7 +18,7 @@ import ( "encoding/json" "errors" - "github.com/google/go-containerregistry/pkg/v1" + v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/partial" "github.com/google/go-containerregistry/pkg/v1/types" ) diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/image.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/image.go index 37e25ad94..1be0ad2ea 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/image.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/image.go @@ -33,6 +33,11 @@ import ( "github.com/google/go-containerregistry/pkg/v1/v1util" ) +var defaultPlatform = v1.Platform{ + Architecture: "amd64", + OS: "linux", +} + // remoteImage accesses an image from a remote registry type remoteImage struct { fetcher @@ -41,6 +46,7 @@ type remoteImage struct { configLock sync.Mutex // Protects config config []byte mediaType types.MediaType + platform v1.Platform } // ImageOption is a functional option for Image. @@ -53,6 +59,7 @@ type imageOpener struct { transport http.RoundTripper ref name.Reference client *http.Client + platform v1.Platform } func (i *imageOpener) Open() (v1.Image, error) { @@ -65,6 +72,7 @@ func (i *imageOpener) Open() (v1.Image, error) { Ref: i.ref, Client: &http.Client{Transport: tr}, }, + platform: i.platform, } imgCore, err := partial.CompressedToImage(ri) if err != nil { @@ -85,6 +93,7 @@ func Image(ref name.Reference, options ...ImageOption) (v1.Image, error) { auth: authn.Anonymous, transport: http.DefaultTransport, ref: ref, + platform: defaultPlatform, } for _, option := range options { @@ -183,16 +192,26 @@ func (r *remoteImage) RawManifest() ([]byte, error) { return r.manifest, nil } - // TODO(jonjohnsonjr): Accept manifest list and image index? acceptable := []types.MediaType{ types.DockerManifestSchema2, types.OCIManifestSchema1, + // We'll resolve these to an image based on the platform. + types.DockerManifestList, + types.OCIImageIndex, } manifest, desc, err := r.fetchManifest(acceptable) if err != nil { return nil, err } + // We want an image but the registry has an index, resolve it to an image. + for desc.MediaType == types.DockerManifestList || desc.MediaType == types.OCIImageIndex { + manifest, desc, err = r.matchImage(manifest) + if err != nil { + return nil, err + } + } + r.mediaType = desc.MediaType r.manifest = manifest return r.manifest, nil @@ -283,3 +302,36 @@ func (r *remoteImage) LayerByDigest(h v1.Hash) (partial.CompressedLayer, error) digest: h, }, nil } + +// This naively matches the first manifest with matching Architecture and OS. +// +// We should probably use this instead: +// github.com/containerd/containerd/platforms +// +// But first we'd need to migrate to: +// github.com/opencontainers/image-spec/specs-go/v1 +func (r *remoteImage) matchImage(rawIndex []byte) ([]byte, *v1.Descriptor, error) { + index, err := v1.ParseIndexManifest(bytes.NewReader(rawIndex)) + if err != nil { + return nil, nil, err + } + for _, childDesc := range index.Manifests { + // If platform is missing from child descriptor, assume it's amd64/linux. + p := defaultPlatform + if childDesc.Platform != nil { + p = *childDesc.Platform + } + if r.platform.Architecture == p.Architecture && r.platform.OS == p.OS { + childRef, err := name.ParseReference(fmt.Sprintf("%s@%s", r.Ref.Context(), childDesc.Digest), name.StrictValidation) + if err != nil { + return nil, nil, err + } + r.fetcher = fetcher{ + Client: r.Client, + Ref: childRef, + } + return r.fetchManifest([]types.MediaType{childDesc.MediaType}) + } + } + return nil, nil, fmt.Errorf("no matching image for %s/%s, index: %s", r.platform.Architecture, r.platform.OS, string(rawIndex)) +} diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/options.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/options.go index a6e9584ee..335e3fe5b 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/options.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/options.go @@ -19,6 +19,7 @@ import ( "net/http" "github.com/google/go-containerregistry/pkg/authn" + v1 "github.com/google/go-containerregistry/pkg/v1" ) // WithTransport is a functional option for overriding the default transport @@ -54,3 +55,10 @@ func WithAuthFromKeychain(keys authn.Keychain) ImageOption { return nil } } + +func WithPlatform(p v1.Platform) ImageOption { + return func(i *imageOpener) error { + i.platform = p + return nil + } +} diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go index 6e2c38a34..66f148155 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go @@ -200,10 +200,9 @@ func (w *writer) checkExistingManifest(h v1.Hash, mt types.MediaType) (bool, err func (w *writer) initiateUpload(from, mount string) (location string, mounted bool, err error) { u := w.url(fmt.Sprintf("/v2/%s/blobs/uploads/", w.ref.Context().RepositoryStr())) uv := url.Values{} - if mount != "" { + if mount != "" && from != "" { + // Quay will fail if we specify a "mount" without a "from". uv["mount"] = []string{mount} - } - if from != "" { uv["from"] = []string{from} } u.RawQuery = uv.Encode()