mirror of
https://github.com/GoogleContainerTools/kaniko
synced 2026-10-19 04:18:57 +02:00
Upgrade docker (#2440)
* somehow now the only thing that doesnt work is devices.Device Signed-off-by: Joe Kimmel <jkimmel@vmware.com> * this gets rid of all the compiler errors in the vendored code Signed-off-by: Joe Kimmel <jkimmel@vmware.com> * fixed some things but a bunch of tests and maybe some compiler steps are still failing Signed-off-by: Joe Kimmel <jkimmel@vmware.com> * all the things i figured out how to fix so far Signed-off-by: Joe Kimmel <jkimmel@vmware.com> * guess i had to redo go mods after rebasing again Signed-off-by: Joe Kimmel <jkimmel@vmware.com> * update docker constants to be SHOUTY CASE now Signed-off-by: Joe Kimmel <jkimmel@vmware.com> * include DestPath in resolveEnv Signed-off-by: Joe Kimmel <jkimmel@vmware.com> * fix one mistake in Docker lib upgrade and some typos/deprecations in the file Signed-off-by: Joe Kimmel <jkimmel@vmware.com> * last changes (hopefully) to update to new docker libs Signed-off-by: Joe Kimmel <jkimmel@vmware.com> --------- Signed-off-by: Joe Kimmel <jkimmel@vmware.com>
This commit is contained in:
+15
@@ -38,6 +38,21 @@ type ConfigFile struct {
|
||||
Config Config `json:"config"`
|
||||
OSVersion string `json:"os.version,omitempty"`
|
||||
Variant string `json:"variant,omitempty"`
|
||||
OSFeatures []string `json:"os.features,omitempty"`
|
||||
}
|
||||
|
||||
// Platform attempts to generates a Platform from the ConfigFile fields.
|
||||
func (cf *ConfigFile) Platform() *Platform {
|
||||
if cf.OS == "" && cf.Architecture == "" && cf.OSVersion == "" && cf.Variant == "" && len(cf.OSFeatures) == 0 {
|
||||
return nil
|
||||
}
|
||||
return &Platform{
|
||||
OS: cf.OS,
|
||||
Architecture: cf.Architecture,
|
||||
OSVersion: cf.OSVersion,
|
||||
Variant: cf.Variant,
|
||||
OSFeatures: cf.OSFeatures,
|
||||
}
|
||||
}
|
||||
|
||||
// History is one entry of a list recording how this container image was built.
|
||||
|
||||
+1
@@ -59,5 +59,6 @@ func (i emptyIndex) ImageIndex(v1.Hash) (v1.ImageIndex, error) {
|
||||
func base() *v1.IndexManifest {
|
||||
return &v1.IndexManifest{
|
||||
SchemaVersion: 2,
|
||||
MediaType: types.OCIImageIndex,
|
||||
}
|
||||
}
|
||||
|
||||
+41
@@ -85,6 +85,47 @@ func (p Platform) Equals(o Platform) bool {
|
||||
stringSliceEqualIgnoreOrder(p.Features, o.Features)
|
||||
}
|
||||
|
||||
// Satisfies returns true if this Platform "satisfies" the given spec Platform.
|
||||
//
|
||||
// Note that this is different from Equals and that Satisfies is not reflexive.
|
||||
//
|
||||
// The given spec represents "requirements" such that any missing values in the
|
||||
// spec are not compared.
|
||||
//
|
||||
// For OSFeatures and Features, Satisfies will return true if this Platform's
|
||||
// fields contain a superset of the values in the spec's fields (order ignored).
|
||||
func (p Platform) Satisfies(spec Platform) bool {
|
||||
return satisfies(spec.OS, p.OS) &&
|
||||
satisfies(spec.Architecture, p.Architecture) &&
|
||||
satisfies(spec.Variant, p.Variant) &&
|
||||
satisfies(spec.OSVersion, p.OSVersion) &&
|
||||
satisfiesList(spec.OSFeatures, p.OSFeatures) &&
|
||||
satisfiesList(spec.Features, p.Features)
|
||||
}
|
||||
|
||||
func satisfies(want, have string) bool {
|
||||
return want == "" || want == have
|
||||
}
|
||||
|
||||
func satisfiesList(want, have []string) bool {
|
||||
if len(want) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
set := map[string]struct{}{}
|
||||
for _, h := range have {
|
||||
set[h] = struct{}{}
|
||||
}
|
||||
|
||||
for _, w := range want {
|
||||
if _, ok := set[w]; !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// stringSliceEqual compares 2 string slices and returns if their contents are identical.
|
||||
func stringSliceEqual(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ func Layer(byteSize int64, mt types.MediaType) (v1.Layer, error) {
|
||||
if err := tw.WriteHeader(&tar.Header{
|
||||
Name: fileName,
|
||||
Size: byteSize,
|
||||
Typeflag: tar.TypeRegA,
|
||||
Typeflag: tar.TypeReg,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+46
-16
@@ -245,7 +245,32 @@ func fallbackTag(d name.Digest) name.Tag {
|
||||
}
|
||||
|
||||
func (f *fetcher) fetchReferrers(ctx context.Context, filter map[string]string, d name.Digest) (*v1.IndexManifest, error) {
|
||||
// Assume the registry doesn't support the Referrers API endpoint, so we'll use the fallback tag scheme.
|
||||
// Check the Referrers API endpoint first.
|
||||
u := f.url("referrers", d.DigestStr())
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Accept", string(types.OCIImageIndex))
|
||||
|
||||
resp, err := f.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if err := transport.CheckError(resp, http.StatusOK, http.StatusNotFound, http.StatusBadRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
var im v1.IndexManifest
|
||||
if err := json.NewDecoder(resp.Body).Decode(&im); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return filterReferrersResponse(filter, &im), nil
|
||||
}
|
||||
|
||||
// The registry doesn't support the Referrers API endpoint, so we'll use the fallback tag scheme.
|
||||
b, _, err := f.fetchManifest(fallbackTag(d), []types.MediaType{types.OCIImageIndex})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -261,21 +286,7 @@ func (f *fetcher) fetchReferrers(ctx context.Context, filter map[string]string,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If filter applied, filter out by artifactType and add annotation
|
||||
// See https://github.com/opencontainers/distribution-spec/blob/main/spec.md#listing-referrers
|
||||
if filter != nil {
|
||||
if v, ok := filter["artifactType"]; ok {
|
||||
tmp := []v1.Descriptor{}
|
||||
for _, desc := range im.Manifests {
|
||||
if desc.ArtifactType == v {
|
||||
tmp = append(tmp, desc)
|
||||
}
|
||||
}
|
||||
im.Manifests = tmp
|
||||
}
|
||||
}
|
||||
|
||||
return &im, nil
|
||||
return filterReferrersResponse(filter, &im), nil
|
||||
}
|
||||
|
||||
func (f *fetcher) fetchManifest(ref name.Reference, acceptable []types.MediaType) ([]byte, *v1.Descriptor, error) {
|
||||
@@ -479,3 +490,22 @@ func (f *fetcher) blobExists(h v1.Hash) (bool, error) {
|
||||
|
||||
return resp.StatusCode == http.StatusOK, nil
|
||||
}
|
||||
|
||||
// If filter applied, filter out by artifactType.
|
||||
// See https://github.com/opencontainers/distribution-spec/blob/main/spec.md#listing-referrers
|
||||
func filterReferrersResponse(filter map[string]string, origIndex *v1.IndexManifest) *v1.IndexManifest {
|
||||
newIndex := origIndex
|
||||
if filter == nil {
|
||||
return newIndex
|
||||
}
|
||||
if v, ok := filter["artifactType"]; ok {
|
||||
tmp := []v1.Descriptor{}
|
||||
for _, desc := range newIndex.Manifests {
|
||||
if desc.ArtifactType == v {
|
||||
tmp = append(tmp, desc)
|
||||
}
|
||||
}
|
||||
newIndex.Manifests = tmp
|
||||
}
|
||||
return newIndex
|
||||
}
|
||||
|
||||
+26
-5
@@ -580,13 +580,11 @@ func unpackTaggable(t Taggable) ([]byte, *v1.Descriptor, error) {
|
||||
}
|
||||
|
||||
// commitSubjectReferrers is responsible for updating the fallback tag manifest to track descriptors referring to a subject for registries that don't yet support the Referrers API.
|
||||
// TODO: this method only uses the fallback tag for now
|
||||
// TODO: use conditional requests to avoid race conditions
|
||||
func (w *writer) commitSubjectReferrers(ctx context.Context, sub name.Digest, add v1.Descriptor) error {
|
||||
// The registry doesn't support Referrers API, we need to update the manifest tagged with the fallback tag.
|
||||
// Make the request to GET the current manifest.
|
||||
t := fallbackTag(sub)
|
||||
u := w.url(fmt.Sprintf("/v2/%s/manifests/%s", w.repo.RepositoryStr(), t.Identifier()))
|
||||
// Check if the registry supports Referrers API.
|
||||
// TODO: This should be done once per registry, not once per subject.
|
||||
u := w.url(fmt.Sprintf("/v2/%s/referrers/%s", w.repo.RepositoryStr(), sub.DigestStr()))
|
||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -598,6 +596,29 @@ func (w *writer) commitSubjectReferrers(ctx context.Context, sub name.Digest, ad
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if err := transport.CheckError(resp, http.StatusOK, http.StatusNotFound, http.StatusBadRequest); err != nil {
|
||||
return err
|
||||
}
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
// The registry supports Referrers API. The registry is responsible for updating the referrers list.
|
||||
return nil
|
||||
}
|
||||
|
||||
// The registry doesn't support Referrers API, we need to update the manifest tagged with the fallback tag.
|
||||
// Make the request to GET the current manifest.
|
||||
t := fallbackTag(sub)
|
||||
u = w.url(fmt.Sprintf("/v2/%s/manifests/%s", w.repo.RepositoryStr(), t.Identifier()))
|
||||
req, err = http.NewRequest(http.MethodGet, u.String(), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Accept", string(types.OCIImageIndex))
|
||||
resp, err = w.client.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var im v1.IndexManifest
|
||||
if err := transport.CheckError(resp, http.StatusOK, http.StatusNotFound); err != nil {
|
||||
return err
|
||||
|
||||
+15
-17
@@ -69,7 +69,7 @@ func Write(ref name.Reference, img v1.Image, w io.Writer, opts ...WriteOption) e
|
||||
return MultiRefWrite(map[name.Reference]v1.Image{ref: img}, w, opts...)
|
||||
}
|
||||
|
||||
// MultiWrite writes the contents of each image to the provided reader, in the compressed format.
|
||||
// MultiWrite writes the contents of each image to the provided writer, in the compressed format.
|
||||
// The contents are written in the following format:
|
||||
// One manifest.json file at the top level containing information about several images.
|
||||
// One file for each layer, named after the layer's SHA.
|
||||
@@ -82,7 +82,7 @@ func MultiWrite(tagToImage map[name.Tag]v1.Image, w io.Writer, opts ...WriteOpti
|
||||
return MultiRefWrite(refToImage, w, opts...)
|
||||
}
|
||||
|
||||
// MultiRefWrite writes the contents of each image to the provided reader, in the compressed format.
|
||||
// MultiRefWrite writes the contents of each image to the provided writer, in the compressed format.
|
||||
// The contents are written in the following format:
|
||||
// One manifest.json file at the top level containing information about several images.
|
||||
// One file for each layer, named after the layer's SHA.
|
||||
@@ -98,12 +98,13 @@ func MultiRefWrite(refToImage map[name.Reference]v1.Image, w io.Writer, opts ...
|
||||
}
|
||||
}
|
||||
|
||||
size, mBytes, err := getSizeAndManifest(refToImage)
|
||||
imageToTags := dedupRefToImage(refToImage)
|
||||
size, mBytes, err := getSizeAndManifest(imageToTags)
|
||||
if err != nil {
|
||||
return sendUpdateReturn(o, err)
|
||||
}
|
||||
|
||||
return writeImagesToTar(refToImage, mBytes, size, w, o)
|
||||
return writeImagesToTar(imageToTags, mBytes, size, w, o)
|
||||
}
|
||||
|
||||
// sendUpdateReturn return the passed in error message, also sending on update channel, if it exists
|
||||
@@ -125,11 +126,10 @@ func sendProgressWriterReturn(pw *progressWriter, err error) error {
|
||||
}
|
||||
|
||||
// writeImagesToTar writes the images to the tarball
|
||||
func writeImagesToTar(refToImage map[name.Reference]v1.Image, m []byte, size int64, w io.Writer, o *writeOptions) (err error) {
|
||||
func writeImagesToTar(imageToTags map[v1.Image][]string, m []byte, size int64, w io.Writer, o *writeOptions) (err error) {
|
||||
if w == nil {
|
||||
return sendUpdateReturn(o, errors.New("must pass valid writer"))
|
||||
}
|
||||
imageToTags := dedupRefToImage(refToImage)
|
||||
|
||||
tw := w
|
||||
var pw *progressWriter
|
||||
@@ -219,9 +219,7 @@ func writeImagesToTar(refToImage map[name.Reference]v1.Image, m []byte, size int
|
||||
}
|
||||
|
||||
// calculateManifest calculates the manifest and optionally the size of the tar file
|
||||
func calculateManifest(refToImage map[name.Reference]v1.Image) (m Manifest, err error) {
|
||||
imageToTags := dedupRefToImage(refToImage)
|
||||
|
||||
func calculateManifest(imageToTags map[v1.Image][]string) (m Manifest, err error) {
|
||||
if len(imageToTags) == 0 {
|
||||
return nil, errors.New("set of images is empty")
|
||||
}
|
||||
@@ -290,12 +288,13 @@ func calculateManifest(refToImage map[name.Reference]v1.Image) (m Manifest, err
|
||||
|
||||
// CalculateSize calculates the expected complete size of the output tar file
|
||||
func CalculateSize(refToImage map[name.Reference]v1.Image) (size int64, err error) {
|
||||
size, _, err = getSizeAndManifest(refToImage)
|
||||
imageToTags := dedupRefToImage(refToImage)
|
||||
size, _, err = getSizeAndManifest(imageToTags)
|
||||
return size, err
|
||||
}
|
||||
|
||||
func getSizeAndManifest(refToImage map[name.Reference]v1.Image) (int64, []byte, error) {
|
||||
m, err := calculateManifest(refToImage)
|
||||
func getSizeAndManifest(imageToTags map[v1.Image][]string) (int64, []byte, error) {
|
||||
m, err := calculateManifest(imageToTags)
|
||||
if err != nil {
|
||||
return 0, nil, fmt.Errorf("unable to calculate manifest: %w", err)
|
||||
}
|
||||
@@ -304,7 +303,7 @@ func getSizeAndManifest(refToImage map[name.Reference]v1.Image) (int64, []byte,
|
||||
return 0, nil, fmt.Errorf("could not marshall manifest to bytes: %w", err)
|
||||
}
|
||||
|
||||
size, err := calculateTarballSize(refToImage, mBytes)
|
||||
size, err := calculateTarballSize(imageToTags, mBytes)
|
||||
if err != nil {
|
||||
return 0, nil, fmt.Errorf("error calculating tarball size: %w", err)
|
||||
}
|
||||
@@ -312,9 +311,7 @@ func getSizeAndManifest(refToImage map[name.Reference]v1.Image) (int64, []byte,
|
||||
}
|
||||
|
||||
// calculateTarballSize calculates the size of the tar file
|
||||
func calculateTarballSize(refToImage map[name.Reference]v1.Image, mBytes []byte) (size int64, err error) {
|
||||
imageToTags := dedupRefToImage(refToImage)
|
||||
|
||||
func calculateTarballSize(imageToTags map[v1.Image][]string, mBytes []byte) (size int64, err error) {
|
||||
seenLayerDigests := make(map[string]struct{})
|
||||
for img, name := range imageToTags {
|
||||
manifest, err := img.Manifest()
|
||||
@@ -386,7 +383,8 @@ func writeTarEntry(tf *tar.Writer, path string, r io.Reader, size int64) error {
|
||||
// ComputeManifest get the manifest.json that will be written to the tarball
|
||||
// for multiple references
|
||||
func ComputeManifest(refToImage map[name.Reference]v1.Image) (Manifest, error) {
|
||||
return calculateManifest(refToImage)
|
||||
imageToTags := dedupRefToImage(refToImage)
|
||||
return calculateManifest(imageToTags)
|
||||
}
|
||||
|
||||
// WriteOption a function option to pass to Write()
|
||||
|
||||
+15
@@ -99,6 +99,11 @@ func (in *ConfigFile) DeepCopyInto(out *ConfigFile) {
|
||||
}
|
||||
in.RootFS.DeepCopyInto(&out.RootFS)
|
||||
in.Config.DeepCopyInto(&out.Config)
|
||||
if in.OSFeatures != nil {
|
||||
in, out := &in.OSFeatures, &out.OSFeatures
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -222,6 +227,11 @@ func (in *IndexManifest) DeepCopyInto(out *IndexManifest) {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Subject != nil {
|
||||
in, out := &in.Subject, &out.Subject
|
||||
*out = new(Descriptor)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -253,6 +263,11 @@ func (in *Manifest) DeepCopyInto(out *Manifest) {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Subject != nil {
|
||||
in, out := &in.Subject, &out.Subject
|
||||
*out = new(Descriptor)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user