update c/common

Update containers common to the latest HEAD.  Some bug fixes in libimage
forced us to have a clearer separation between ordinary images and
manifest lists.  Hence, when looking up manifest lists without recursing
into any of their instances, we need to use `LookupManifestList()`.

Also account for some other changes in c/common (e.g., the changed order
in the security labels).

Further vendor the latest HEAD from Buildah which is required to get the
bud tests to pass.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
Valentin Rothberg
2021-05-18 10:05:03 +02:00
parent 8bc39f4a90
commit 898a8ad285
186 changed files with 2720 additions and 1771 deletions

View File

@ -84,7 +84,9 @@ func (i *Image) ID() string {
}
// Digest is a digest value that we can use to locate the image, if one was
// specified at creation-time.
// specified at creation-time. Typically it is the digest of one among
// possibly many digests that we have stored for the image, so many
// applications are better off using the entire list returned by Digests().
func (i *Image) Digest() digest.Digest {
return i.storageImage.Digest
}
@ -708,17 +710,43 @@ func (i *Image) HasDifferentDigest(ctx context.Context, remoteRef types.ImageRef
return false, err
}
rawManifest, _, err := remoteImg.Manifest(ctx)
rawManifest, rawManifestMIMEType, err := remoteImg.Manifest(ctx)
if err != nil {
return false, err
}
remoteDigest, err := manifest.Digest(rawManifest)
if err != nil {
return false, err
// If the remote ref's manifest is a list, try to zero in on the image
// in the list that we would eventually try to pull.
var remoteDigest digest.Digest
if manifest.MIMETypeIsMultiImage(rawManifestMIMEType) {
list, err := manifest.ListFromBlob(rawManifest, rawManifestMIMEType)
if err != nil {
return false, err
}
remoteDigest, err = list.ChooseInstance(sys)
if err != nil {
return false, err
}
} else {
remoteDigest, err = manifest.Digest(rawManifest)
if err != nil {
return false, err
}
}
return i.Digest().String() != remoteDigest.String(), nil
// Check if we already have that image's manifest in this image. A
// single image can have multiple manifests that describe the same
// config blob and layers, so treat any match as a successful match.
for _, digest := range append(i.Digests(), i.Digest()) {
if digest.Validate() != nil {
continue
}
if digest.String() == remoteDigest.String() {
return false, nil
}
}
// No matching digest found in the local image.
return true, nil
}
// driverData gets the driver data from the store on a layer

View File

@ -19,6 +19,10 @@ import (
// NOTE: the abstractions and APIs here are a first step to further merge
// `libimage/manifests` into `libimage`.
// ErrNotAManifestList indicates that an image was found in the local
// containers storage but it is not a manifest list as requested.
var ErrNotAManifestList = errors.New("image is not a manifest list")
// ManifestList represents a manifest list (Docker) or an image index (OCI) in
// the local containers storage.
type ManifestList struct {
@ -73,7 +77,11 @@ func (r *Runtime) LookupManifestList(name string) (*ManifestList, error) {
}
func (r *Runtime) lookupManifestList(name string) (*Image, manifests.List, error) {
image, _, err := r.LookupImage(name, &LookupImageOptions{IgnorePlatform: true})
lookupOptions := &LookupImageOptions{
IgnorePlatform: true,
lookupManifest: true,
}
image, _, err := r.LookupImage(name, lookupOptions)
if err != nil {
return nil, nil, err
}

View File

@ -162,6 +162,14 @@ func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference,
storageName = imageName
}
case storageTransport.Transport.Name():
storageName = ref.StringWithinTransport()
named := ref.DockerReference()
if named == nil {
return nil, errors.Errorf("could not get an image name for storage reference %q", ref)
}
imageName = named.String()
default:
storageName = toLocalImageName(ref.StringWithinTransport())
imageName = storageName
@ -170,7 +178,7 @@ func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference,
// Create a storage reference.
destRef, err := storageTransport.Transport.ParseStoreReference(r.store, storageName)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "parsing %q", storageName)
}
_, err = c.copy(ctx, ref, destRef)

View File

@ -29,8 +29,10 @@ func (r *Runtime) Push(ctx context.Context, source, destination string, options
options = &PushOptions{}
}
// Look up the local image.
image, resolvedSource, err := r.LookupImage(source, nil)
// Look up the local image. Note that we need to ignore the platform
// and push what the user specified (containers/podman/issues/10344).
lookupOptions := &LookupImageOptions{IgnorePlatform: true}
image, resolvedSource, err := r.LookupImage(source, lookupOptions)
if err != nil {
return nil, err
}

View File

@ -147,6 +147,10 @@ type LookupImageOptions struct {
// the current platform will be performed. This can be helpful when
// the platform does not matter, for instance, for image removal.
IgnorePlatform bool
// If set, do not look for items/instances in the manifest list that
// match the current platform but return the manifest list as is.
lookupManifest bool
}
// Lookup Image looks up `name` in the local container storage matching the
@ -244,30 +248,52 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo
}
image := r.storageToImage(img, ref)
if options.IgnorePlatform {
logrus.Debugf("Found image %q as %q in local containers storage", name, candidate)
return image, nil
}
logrus.Debugf("Found image %q as %q in local containers storage", name, candidate)
// If we referenced a manifest list, we need to check whether we can
// find a matching instance in the local containers storage.
isManifestList, err := image.IsManifestList(context.Background())
if err != nil {
if errors.Cause(err) == os.ErrNotExist {
// We must be tolerant toward corrupted images.
// See containers/podman commit fd9dd7065d44.
logrus.Warnf("error determining if an image is a manifest list: %v, ignoring the error", err)
return image, nil
}
return nil, err
}
if options.lookupManifest {
if isManifestList {
return image, nil
}
return nil, errors.Wrapf(ErrNotAManifestList, candidate)
}
if isManifestList {
logrus.Debugf("Candidate %q is a manifest list, looking up matching instance", candidate)
manifestList, err := image.ToManifestList()
if err != nil {
return nil, err
}
image, err = manifestList.LookupInstance(context.Background(), "", "", "")
if err != nil {
return nil, err
}
ref, err = storageTransport.Transport.ParseStoreReference(r.store, "@"+image.ID())
instance, err := manifestList.LookupInstance(context.Background(), "", "", "")
if err != nil {
// NOTE: If we are not looking for a specific platform
// and already found the manifest list, then return it
// instead of the error.
if options.IgnorePlatform {
return image, nil
}
return nil, errors.Wrap(storage.ErrImageUnknown, err.Error())
}
ref, err = storageTransport.Transport.ParseStoreReference(r.store, "@"+instance.ID())
if err != nil {
return nil, err
}
image = instance
}
if options.IgnorePlatform {
return image, nil
}
matches, err := imageReferenceMatchesContext(context.Background(), ref, &r.systemContext)
@ -550,7 +576,7 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem
return nil, rmErrors
}
case len(options.Filters) > 0:
default:
filteredImages, err := r.ListImages(ctx, nil, &ListImagesOptions{Filters: options.Filters})
if err != nil {
appendError(err)

View File

@ -57,9 +57,13 @@ func (r *Runtime) Save(ctx context.Context, names []string, format, path string,
// Dispatch the save operations.
switch format {
case "oci-archive", "oci-dir", "docker-dir":
if len(names) > 1 {
return errors.Errorf("%q does not support saving multiple images (%v)", format, names)
}
return r.saveSingleImage(ctx, names[0], format, path, options)
case "docker-archive":
options.ManifestMIMEType = manifest.DockerV2Schema2MediaType
return r.saveDockerArchive(ctx, names, path, options)
}
@ -134,6 +138,18 @@ func (r *Runtime) saveDockerArchive(ctx context.Context, names []string, path st
tags []reference.NamedTagged
}
additionalTags := []reference.NamedTagged{}
for _, tag := range options.AdditionalTags {
named, err := NormalizeName(tag)
if err == nil {
tagged, withTag := named.(reference.NamedTagged)
if !withTag {
return errors.Errorf("invalid additional tag %q: normalized to untagged %q", tag, named.String())
}
additionalTags = append(additionalTags, tagged)
}
}
orderedIDs := []string{} // to preserve the relative order
localImages := make(map[string]*localImage) // to assemble tags
visitedNames := make(map[string]bool) // filters duplicate names
@ -153,6 +169,7 @@ func (r *Runtime) saveDockerArchive(ctx context.Context, names []string, path st
local, exists := localImages[image.ID()]
if !exists {
local = &localImage{image: image}
local.tags = additionalTags
orderedIDs = append(orderedIDs, image.ID())
}
// Add the tag if the locally resolved name is properly tagged