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

View File

@ -6,6 +6,7 @@ package capabilities
// changed significantly to fit the needs of libpod.
import (
"sort"
"strings"
"sync"
@ -48,6 +49,7 @@ func init() {
}
capsList = append(capsList, cap)
capabilityList = append(capabilityList, getCapName(cap))
sort.Strings(capabilityList)
}
}
@ -88,6 +90,7 @@ func BoundingSet() ([]string, error) {
r = append(r, getCapName(c))
}
boundingSetRet = r
sort.Strings(boundingSetRet)
boundingSetErr = err
})
return boundingSetRet, boundingSetErr
@ -116,6 +119,7 @@ func NormalizeCapabilities(caps []string) ([]string, error) {
}
normalized[i] = c
}
sort.Strings(normalized)
return normalized, nil
}
@ -157,18 +161,25 @@ func MergeCapabilities(base, adds, drops []string) ([]string, error) {
}
if stringInSlice(All, capDrop) {
if stringInSlice(All, capAdd) {
return nil, errors.New("adding all caps and removing all caps not allowed")
}
// "Drop" all capabilities; return what's in capAdd instead
sort.Strings(capAdd)
return capAdd, nil
}
if stringInSlice(All, capAdd) {
// "Add" all capabilities;
return BoundingSet()
}
for _, add := range capAdd {
if stringInSlice(add, capDrop) {
return nil, errors.Errorf("capability %q cannot be dropped and added", add)
base, err = BoundingSet()
if err != nil {
return nil, err
}
capAdd = []string{}
} else {
for _, add := range capAdd {
if stringInSlice(add, capDrop) {
return nil, errors.Errorf("capability %q cannot be dropped and added", add)
}
}
}
@ -193,5 +204,6 @@ func MergeCapabilities(base, adds, drops []string) ([]string, error) {
}
caps = append(caps, cap)
}
sort.Strings(caps)
return caps, nil
}

View File

@ -526,11 +526,11 @@ func systemConfigs() ([]string, error) {
if _, err := os.Stat(OverrideContainersConfig); err == nil {
configs = append(configs, OverrideContainersConfig)
}
if unshare.IsRootless() {
path, err := rootlessConfigPath()
if err != nil {
return nil, err
}
path, err := ifRootlessConfigPath()
if err != nil {
return nil, err
}
if path != "" {
if _, err := os.Stat(path); err == nil {
configs = append(configs, path)
}

View File

@ -4,9 +4,14 @@ import (
"os"
)
// podman remote clients on darwin cannot use unshare.isRootless() to determine the configuration file locations.
func customConfigFile() (string, error) {
if path, found := os.LookupEnv("CONTAINERS_CONF"); found {
return path, nil
}
return rootlessConfigPath()
}
func ifRootlessConfigPath() (string, error) {
return rootlessConfigPath()
}

View File

@ -24,3 +24,14 @@ func customConfigFile() (string, error) {
}
return OverrideContainersConfig, nil
}
func ifRootlessConfigPath() (string, error) {
if unshare.IsRootless() {
path, err := rootlessConfigPath()
if err != nil {
return "", err
}
return path, nil
}
return "", nil
}

View File

@ -2,9 +2,14 @@ package config
import "os"
// podman remote clients on windows cannot use unshare.isRootless() to determine the configuration file locations.
func customConfigFile() (string, error) {
if path, found := os.LookupEnv("CONTAINERS_CONF"); found {
return path, nil
}
return os.Getenv("APPDATA") + "\\containers\\containers.conf", nil
}
func ifRootlessConfigPath() (string, error) {
return os.Getenv("APPDATA") + "\\containers\\containers.conf", nil
}

View File

@ -157,7 +157,7 @@ default_sysctls = [
# Logging driver for the container. Available options: k8s-file and journald.
#
# log_driver = "journald"
# log_driver = "k8s-file"
# Maximum size allowed for the container log file. Negative numbers indicate
# that no size limit is imposed. If positive, it must be >= 8192 to match or

View File

@ -102,7 +102,7 @@ const (
// SystemdCgroupsManager represents systemd native cgroup manager
SystemdCgroupsManager = "systemd"
// DefaultLogDriver is the default type of log files
DefaultLogDriver = "journald"
DefaultLogDriver = "k8s-file"
// DefaultLogSizeMax is the default value for the maximum log size
// allowed for a container. Negative values mean that no limit is imposed.
DefaultLogSizeMax = -1

View File

@ -1,4 +1,4 @@
package version
// Version is the version of the build.
const Version = "0.38.1-dev"
const Version = "0.38.4-dev"