mirror of
https://github.com/GoogleContainerTools/kaniko
synced 2026-10-19 15:38:24 +02:00
Update go-containerregistry.
This commit is contained in:
+1
-1
@@ -76,7 +76,7 @@ func (h *helper) Authorization() (string, error) {
|
||||
|
||||
// If we see this specific message, it means the domain wasn't found
|
||||
// and we should fall back on anonymous auth.
|
||||
output := out.String()
|
||||
output := strings.TrimSpace(out.String())
|
||||
if output == magicNotFoundMessage {
|
||||
return Anonymous.Authorization()
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// Copyright 2018 Google LLC All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/google/go-containerregistry/pkg/v1/types"
|
||||
)
|
||||
|
||||
type ImageIndex interface {
|
||||
// MediaType of this image's manifest.
|
||||
MediaType() (types.MediaType, error)
|
||||
|
||||
// Digest returns the sha256 of this index's manifest.
|
||||
Digest() (Hash, error)
|
||||
|
||||
// IndexManifest returns this image index's manifest object.
|
||||
IndexManifest() (*IndexManifest, error)
|
||||
|
||||
// RawIndexManifest returns the serialized bytes of IndexManifest().
|
||||
RawIndexManifest() ([]byte, error)
|
||||
}
|
||||
+18
@@ -30,6 +30,14 @@ type Manifest struct {
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
// IndexManifest represents an OCI image index in a structured way.
|
||||
type IndexManifest struct {
|
||||
SchemaVersion int64 `json:"schemaVersion"`
|
||||
MediaType types.MediaType `json:"mediaType,omitempty"`
|
||||
Manifests []Descriptor `json:"manifests"`
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
// Descriptor holds a reference from the manifest to one of its constituent elements.
|
||||
type Descriptor struct {
|
||||
MediaType types.MediaType `json:"mediaType"`
|
||||
@@ -37,6 +45,7 @@ type Descriptor struct {
|
||||
Digest Hash `json:"digest"`
|
||||
URLs []string `json:"urls,omitempty"`
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
Platform *Platform `json:"platform,omitempty"`
|
||||
}
|
||||
|
||||
// ParseManifest parses the io.Reader's contents into a Manifest.
|
||||
@@ -47,3 +56,12 @@ func ParseManifest(r io.Reader) (*Manifest, error) {
|
||||
}
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
// ParseIndexManifest parses the io.Reader's contents into an IndexManifest.
|
||||
func ParseIndexManifest(r io.Reader) (*IndexManifest, error) {
|
||||
im := IndexManifest{}
|
||||
if err := json.NewDecoder(r).Decode(&im); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &im, nil
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// Copyright 2018 Google LLC All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package v1
|
||||
|
||||
// Platform represents the target os/arch for an image.
|
||||
type Platform struct {
|
||||
Architecture string `json:"architecture"`
|
||||
OS string `json:"os"`
|
||||
OSVersion string `json:"os.version,omitempty"`
|
||||
OSFeatures []string `json:"os.features,omitempty"`
|
||||
Variant string `json:"variant,omitempty"`
|
||||
}
|
||||
+9
-8
@@ -144,14 +144,15 @@ func (r *remoteImage) RawManifest() ([]byte, error) {
|
||||
if digest.String() != dgst.DigestStr() {
|
||||
return nil, fmt.Errorf("manifest digest: %q does not match requested digest: %q for %q", digest, dgst.DigestStr(), r.ref)
|
||||
}
|
||||
} else if checksum := resp.Header.Get("Docker-Content-Digest"); checksum != "" && checksum != digest.String() {
|
||||
err := fmt.Errorf("manifest digest: %q does not match Docker-Content-Digest: %q for %q", digest, checksum, r.ref)
|
||||
if r.ref.Context().RegistryStr() == name.DefaultRegistry {
|
||||
// TODO(docker/distribution#2395): Remove this check.
|
||||
} else {
|
||||
// When pulling by tag, we can only validate that the digest matches what the registry told us it should be.
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// Do nothing for tags; I give up.
|
||||
//
|
||||
// We'd like to validate that the "Docker-Content-Digest" header matches what is returned by the registry,
|
||||
// but so many registries implement this incorrectly that it's not worth checking.
|
||||
//
|
||||
// For reference:
|
||||
// https://github.com/docker/distribution/issues/2395
|
||||
// https://github.com/GoogleContainerTools/kaniko/issues/298
|
||||
}
|
||||
|
||||
r.manifest = manifest
|
||||
|
||||
+30
-4
@@ -120,6 +120,26 @@ func (w *writer) nextLocation(resp *http.Response) (string, error) {
|
||||
return resp.Request.URL.ResolveReference(u).String(), nil
|
||||
}
|
||||
|
||||
// checkExisting checks if a blob exists already in the repository by making a
|
||||
// HEAD request to the blob store API. GCR performs an existence check on the
|
||||
// initiation if "mount" is specified, even if no "from" sources are specified.
|
||||
// However, this is not broadly applicable to all registries, e.g. ECR.
|
||||
func (w *writer) checkExisting(h v1.Hash) (bool, error) {
|
||||
u := w.url(fmt.Sprintf("/v2/%s/blobs/%s", w.ref.Context().RepositoryStr(), h.String()))
|
||||
|
||||
resp, err := w.client.Head(u.String())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if err := CheckError(resp, http.StatusOK, http.StatusNotFound); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return resp.StatusCode == http.StatusOK, nil
|
||||
}
|
||||
|
||||
// initiateUpload initiates the blob upload, which starts with a POST that can
|
||||
// optionally include the hash of the layer and a list of repositories from
|
||||
// which that layer might be read. On failure, an error is returned.
|
||||
@@ -135,10 +155,7 @@ func (w *writer) initiateUpload(h v1.Hash) (location string, mounted bool, err e
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
// We currently avoid HEAD because it's semi-redundant with the mount that is part
|
||||
// of initiating the blob upload. GCR will perform an existence check on the initiation
|
||||
// if "mount" is specified, even if no "from" sources are specified. If this turns out
|
||||
// to not be broadly applicable then we should replace mounts without "from"s with a HEAD.
|
||||
|
||||
if ml, ok := l.(*MountableLayer); ok {
|
||||
if w.ref.Context().RegistryStr() == ml.Reference.Context().RegistryStr() {
|
||||
uv["from"] = []string{ml.Reference.Context().RepositoryStr()}
|
||||
@@ -231,6 +248,15 @@ func (w *writer) commitBlob(h v1.Hash, location string) (err error) {
|
||||
|
||||
// uploadOne performs a complete upload of a single layer.
|
||||
func (w *writer) uploadOne(h v1.Hash) error {
|
||||
existing, err := w.checkExisting(h)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if existing {
|
||||
log.Printf("existing blob: %v", h)
|
||||
return nil
|
||||
}
|
||||
|
||||
location, mounted, err := w.initiateUpload(h)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+86
-4
@@ -26,6 +26,11 @@ func (in *Config) DeepCopyInto(out *Config) {
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Healthcheck != nil {
|
||||
in, out := &in.Healthcheck, &out.Healthcheck
|
||||
*out = new(HealthConfig)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Entrypoint != nil {
|
||||
in, out := &in.Entrypoint, &out.Entrypoint
|
||||
*out = make([]string, len(*in))
|
||||
@@ -51,15 +56,15 @@ func (in *Config) DeepCopyInto(out *Config) {
|
||||
if in.Volumes != nil {
|
||||
in, out := &in.Volumes, &out.Volumes
|
||||
*out = make(map[string]struct{}, len(*in))
|
||||
for key := range *in {
|
||||
(*out)[key] = struct{}{}
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.ExposedPorts != nil {
|
||||
in, out := &in.ExposedPorts, &out.ExposedPorts
|
||||
*out = make(map[string]struct{}, len(*in))
|
||||
for key := range *in {
|
||||
(*out)[key] = struct{}{}
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Shell != nil {
|
||||
@@ -123,6 +128,11 @@ func (in *Descriptor) DeepCopyInto(out *Descriptor) {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Platform != nil {
|
||||
in, out := &in.Platform, &out.Platform
|
||||
*out = new(Platform)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -152,6 +162,27 @@ func (in *Hash) DeepCopy() *Hash {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HealthConfig) DeepCopyInto(out *HealthConfig) {
|
||||
*out = *in
|
||||
if in.Test != nil {
|
||||
in, out := &in.Test, &out.Test
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthConfig.
|
||||
func (in *HealthConfig) DeepCopy() *HealthConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HealthConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *History) DeepCopyInto(out *History) {
|
||||
*out = *in
|
||||
@@ -169,6 +200,36 @@ func (in *History) DeepCopy() *History {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *IndexManifest) DeepCopyInto(out *IndexManifest) {
|
||||
*out = *in
|
||||
if in.Manifests != nil {
|
||||
in, out := &in.Manifests, &out.Manifests
|
||||
*out = make([]Descriptor, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Annotations != nil {
|
||||
in, out := &in.Annotations, &out.Annotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IndexManifest.
|
||||
func (in *IndexManifest) DeepCopy() *IndexManifest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(IndexManifest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Manifest) DeepCopyInto(out *Manifest) {
|
||||
*out = *in
|
||||
@@ -200,6 +261,27 @@ func (in *Manifest) DeepCopy() *Manifest {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Platform) DeepCopyInto(out *Platform) {
|
||||
*out = *in
|
||||
if in.OSFeatures != nil {
|
||||
in, out := &in.OSFeatures, &out.OSFeatures
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Platform.
|
||||
func (in *Platform) DeepCopy() *Platform {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Platform)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RootFS) DeepCopyInto(out *RootFS) {
|
||||
*out = *in
|
||||
|
||||
Reference in New Issue
Block a user