diff --git a/Gopkg.lock b/Gopkg.lock index 47e3f96625..410e2aae1b 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -431,7 +431,7 @@ [[projects]] branch = "master" - digest = "1:edf64d541c12aaf4f279642ea9939f035dcc9fc2edf649aba295e9cbca2c28d4" + digest = "1:764d0a9bb2c987d9333c5b0a256bc94791db50c0b5be2fa10f2247b1dcbd7a04" name = "github.com/google/go-containerregistry" packages = [ "pkg/authn", @@ -450,7 +450,7 @@ "pkg/v1/v1util", ] pruneopts = "NUT" - revision = "03167950e20ac82689f50828811e69cdd9e02af2" + revision = "24bbadfcffb5e05b1578cb2bd5438992ada3b546" [[projects]] digest = "1:f4f203acd8b11b8747bdcd91696a01dbc95ccb9e2ca2db6abf81c3a4f5e950ce" diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/partial/compressed.go b/vendor/github.com/google/go-containerregistry/pkg/v1/partial/compressed.go index e6e4f4d42f..6c3998e524 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/partial/compressed.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/partial/compressed.go @@ -125,6 +125,11 @@ func (i *compressedImageExtender) Layers() ([]v1.Layer, error) { // LayerByDigest implements v1.Image func (i *compressedImageExtender) LayerByDigest(h v1.Hash) (v1.Layer, error) { + if cfgName, err := i.ConfigName(); err != nil { + return nil, err + } else if cfgName == h { + return ConfigLayer(i) + } cl, err := i.CompressedImageCore.LayerByDigest(h) if err != nil { return nil, err diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/partial/uncompressed.go b/vendor/github.com/google/go-containerregistry/pkg/v1/partial/uncompressed.go index 7afa187b87..f7055dcad2 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/partial/uncompressed.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/partial/uncompressed.go @@ -37,8 +37,12 @@ type UncompressedLayer interface { // uncompressedLayerExtender implements v1.Image using the uncompressed base properties. type uncompressedLayerExtender struct { UncompressedLayer - // TODO(mattmoor): Memoize size/hash so that the methods aren't twice as + // Memoize size/hash so that the methods aren't twice as // expensive as doing this manually. + hash v1.Hash + size int64 + hashSizeError error + once sync.Once } // Compressed implements v1.Layer @@ -52,29 +56,31 @@ func (ule *uncompressedLayerExtender) Compressed() (io.ReadCloser, error) { // Digest implements v1.Layer func (ule *uncompressedLayerExtender) Digest() (v1.Hash, error) { - r, err := ule.Compressed() - if err != nil { - return v1.Hash{}, err - } - defer r.Close() - h, _, err := v1.SHA256(r) - return h, err + ule.calcSizeHash() + return ule.hash, ule.hashSizeError } // Size implements v1.Layer func (ule *uncompressedLayerExtender) Size() (int64, error) { - r, err := ule.Compressed() - if err != nil { - return -1, err - } - defer r.Close() - _, i, err := v1.SHA256(r) - return i, err + ule.calcSizeHash() + return ule.size, ule.hashSizeError +} + +func (ule *uncompressedLayerExtender) calcSizeHash() { + ule.once.Do(func() { + var r io.ReadCloser + r, ule.hashSizeError = ule.Compressed() + if ule.hashSizeError != nil { + return + } + defer r.Close() + ule.hash, ule.size, ule.hashSizeError = v1.SHA256(r) + }) } // UncompressedToLayer fills in the missing methods from an UncompressedLayer so that it implements v1.Layer func UncompressedToLayer(ul UncompressedLayer) (v1.Layer, error) { - return &uncompressedLayerExtender{ul}, nil + return &uncompressedLayerExtender{UncompressedLayer: ul}, nil } // UncompressedImageCore represents the bare minimum interface a natively diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/bearer.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/bearer.go index 7dd49ae6f8..a451213904 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/bearer.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/bearer.go @@ -46,22 +46,37 @@ var _ http.RoundTripper = (*bearerTransport)(nil) // RoundTrip implements http.RoundTripper func (bt *bearerTransport) RoundTrip(in *http.Request) (*http.Response, error) { - hdr, err := bt.bearer.Authorization() + sendRequest := func() (*http.Response, error) { + hdr, err := bt.bearer.Authorization() + if err != nil { + return nil, err + } + + // http.Client handles redirects at a layer above the http.RoundTripper + // abstraction, so to avoid forwarding Authorization headers to places + // we are redirected, only set it when the authorization header matches + // the registry with which we are interacting. + if in.Host == bt.registry.RegistryStr() { + in.Header.Set("Authorization", hdr) + } + in.Header.Set("User-Agent", transportName) + return bt.inner.RoundTrip(in) + } + + res, err := sendRequest() if err != nil { return nil, err } - // http.Client handles redirects at a layer above the http.RoundTripper - // abstraction, so to avoid forwarding Authorization headers to places - // we are redirected, only set it when the authorization header matches - // the registry with which we are interacting. - if in.Host == bt.registry.RegistryStr() { - in.Header.Set("Authorization", hdr) + // Perform a token refresh() and retry the request in case the token has expired + if res.StatusCode == http.StatusUnauthorized { + if err = bt.refresh(); err != nil { + return nil, err + } + return sendRequest() } - in.Header.Set("User-Agent", transportName) - // TODO(mattmoor): On 401s perform a single refresh() and retry. - return bt.inner.RoundTrip(in) + return res, err } func (bt *bearerTransport) refresh() error {