From fb4a0c572ed1264ebb12218e8905c4845cb159c5 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Thu, 27 May 2021 16:13:54 +0200 Subject: support tag@digest notation Vendor in the latest HEAd of containers/common to implicitly support the tag@digest notation for images. To remain compatible with Docker, the tag will be stripped off the image reference and is entirely ignored. Fixes: #6721 Signed-off-by: Valentin Rothberg --- .../containers/common/libimage/normalize.go | 51 ++++++++++++++++++++++ .../github.com/containers/common/libimage/pull.go | 23 +++++++++- .../containers/common/libimage/runtime.go | 9 ++++ .../containers/common/pkg/config/default.go | 2 +- .../containers/common/pkg/config/nosystemd.go | 10 ++++- .../containers/common/pkg/config/systemd.go | 40 ++++++++++++++++- .../containers/common/version/version.go | 2 +- vendor/modules.txt | 2 +- 8 files changed, 133 insertions(+), 6 deletions(-) (limited to 'vendor') diff --git a/vendor/github.com/containers/common/libimage/normalize.go b/vendor/github.com/containers/common/libimage/normalize.go index 03d2456de..bfea807c8 100644 --- a/vendor/github.com/containers/common/libimage/normalize.go +++ b/vendor/github.com/containers/common/libimage/normalize.go @@ -5,6 +5,7 @@ import ( "github.com/containers/image/v5/docker/reference" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) // NormalizeName normalizes the provided name according to the conventions by @@ -40,6 +41,11 @@ func NormalizeName(name string) (reference.Named, error) { } if _, hasTag := named.(reference.NamedTagged); hasTag { + // Strip off the tag of a tagged and digested reference. + named, err = normalizeTaggedDigestedNamed(named) + if err != nil { + return nil, err + } return named, nil } if _, hasDigest := named.(reference.Digested); hasDigest { @@ -90,3 +96,48 @@ func ToNameTagPairs(repoTags []reference.Named) ([]NameTagPair, error) { } return pairs, nil } + +// normalizeTaggedDigestedString strips the tag off the specified string iff it +// is tagged and digested. Note that the tag is entirely ignored to match +// Docker behavior. +func normalizeTaggedDigestedString(s string) (string, error) { + // Note that the input string is not expected to be parseable, so we + // return it verbatim in error cases. + ref, err := reference.Parse(s) + if err != nil { + return "", err + } + named, ok := ref.(reference.Named) + if !ok { + return s, nil + } + named, err = normalizeTaggedDigestedNamed(named) + if err != nil { + return "", err + } + return named.String(), nil +} + +// normalizeTaggedDigestedNamed strips the tag off the specified named +// reference iff it is tagged and digested. Note that the tag is entirely +// ignored to match Docker behavior. +func normalizeTaggedDigestedNamed(named reference.Named) (reference.Named, error) { + _, isTagged := named.(reference.NamedTagged) + if !isTagged { + return named, nil + } + digested, isDigested := named.(reference.Digested) + if !isDigested { + return named, nil + } + + // Now strip off the tag. + newNamed := reference.TrimNamed(named) + // And re-add the digest. + newNamed, err := reference.WithDigest(newNamed, digested.Digest()) + if err != nil { + return named, err + } + logrus.Debugf("Stripped off tag from tagged and digested reference %q", named.String()) + return newNamed, nil +} diff --git a/vendor/github.com/containers/common/libimage/pull.go b/vendor/github.com/containers/common/libimage/pull.go index 5fa888251..acf5c818f 100644 --- a/vendor/github.com/containers/common/libimage/pull.go +++ b/vendor/github.com/containers/common/libimage/pull.go @@ -52,6 +52,7 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP options = &PullOptions{} } + var possiblyUnqualifiedName string // used for short-name resolution ref, err := alltransports.ParseImageName(name) if err != nil { // If the image clearly refers to a local one, we can look it up directly. @@ -67,6 +68,15 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP return []*Image{local}, err } + // Docker compat: strip off the tag iff name is tagged and digested + // (e.g., fedora:latest@sha256...). In that case, the tag is stripped + // off and entirely ignored. The digest is the sole source of truth. + normalizedName, normalizeError := normalizeTaggedDigestedString(name) + if normalizeError != nil { + return nil, normalizeError + } + name = normalizedName + // If the input does not include a transport assume it refers // to a registry. dockerRef, dockerErr := alltransports.ParseImageName("docker://" + name) @@ -74,6 +84,17 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP return nil, err } ref = dockerRef + possiblyUnqualifiedName = name + } else if ref.Transport().Name() == registryTransport.Transport.Name() { + // Normalize the input if we're referring to the docker + // transport directly. That makes sure that a `docker://fedora` + // will resolve directly to `docker.io/library/fedora:latest` + // and not be subject to short-name resolution. + named := ref.DockerReference() + if named == nil { + return nil, errors.New("internal error: unexpected nil reference") + } + possiblyUnqualifiedName = named.String() } if options.AllTags && ref.Transport().Name() != registryTransport.Transport.Name() { @@ -94,7 +115,7 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP // DOCKER REGISTRY case registryTransport.Transport.Name(): - pulledImages, pullError = r.copyFromRegistry(ctx, ref, strings.TrimPrefix(name, "docker://"), pullPolicy, options) + pulledImages, pullError = r.copyFromRegistry(ctx, ref, possiblyUnqualifiedName, pullPolicy, options) // DOCKER ARCHIVE case dockerArchiveTransport.Transport.Name(): diff --git a/vendor/github.com/containers/common/libimage/runtime.go b/vendor/github.com/containers/common/libimage/runtime.go index aa798d008..bbf1c2a61 100644 --- a/vendor/github.com/containers/common/libimage/runtime.go +++ b/vendor/github.com/containers/common/libimage/runtime.go @@ -180,6 +180,15 @@ func (r *Runtime) LookupImage(name string, options *LookupImageOptions) (*Image, } logrus.Debugf("Found image %q in local containers storage (%s)", name, storageRef.StringWithinTransport()) return r.storageToImage(img, storageRef), "", nil + } else { + // Docker compat: strip off the tag iff name is tagged and digested + // (e.g., fedora:latest@sha256...). In that case, the tag is stripped + // off and entirely ignored. The digest is the sole source of truth. + normalizedName, err := normalizeTaggedDigestedString(name) + if err != nil { + return nil, "", err + } + name = normalizedName } originalName := name diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go index 2b660d1ab..d5a7d5b84 100644 --- a/vendor/github.com/containers/common/pkg/config/default.go +++ b/vendor/github.com/containers/common/pkg/config/default.go @@ -195,7 +195,7 @@ func DefaultConfig() (*Config, error) { Init: false, InitPath: "", IPCNS: "private", - LogDriver: DefaultLogDriver, + LogDriver: defaultLogDriver(), LogSizeMax: DefaultLogSizeMax, NetNS: netns, NoHosts: false, diff --git a/vendor/github.com/containers/common/pkg/config/nosystemd.go b/vendor/github.com/containers/common/pkg/config/nosystemd.go index 5b82b1389..6e39a6ccd 100644 --- a/vendor/github.com/containers/common/pkg/config/nosystemd.go +++ b/vendor/github.com/containers/common/pkg/config/nosystemd.go @@ -3,9 +3,17 @@ package config func defaultCgroupManager() string { - return "cgroupfs" + return CgroupfsCgroupsManager } func defaultEventsLogger() string { return "file" } + +func defaultLogDriver() string { + return DefaultLogDriver +} + +func useSystemd() bool { + return false +} diff --git a/vendor/github.com/containers/common/pkg/config/systemd.go b/vendor/github.com/containers/common/pkg/config/systemd.go index 02e5c4ac2..ed014126b 100644 --- a/vendor/github.com/containers/common/pkg/config/systemd.go +++ b/vendor/github.com/containers/common/pkg/config/systemd.go @@ -3,11 +3,23 @@ package config import ( + "io/ioutil" + "strings" + "sync" + "github.com/containers/common/pkg/cgroupv2" "github.com/containers/storage/pkg/unshare" ) +var ( + systemdOnce sync.Once + usesSystemd bool +) + func defaultCgroupManager() string { + if !useSystemd() { + return CgroupfsCgroupsManager + } enabled, err := cgroupv2.Enabled() if err == nil && !enabled && unshare.IsRootless() { return CgroupfsCgroupsManager @@ -15,6 +27,32 @@ func defaultCgroupManager() string { return SystemdCgroupsManager } + func defaultEventsLogger() string { - return "journald" + if useSystemd() { + return "journald" + } + return "file" +} + +func defaultLogDriver() string { + // If we decide to change the default for logdriver, it should be done here. + if useSystemd() { + return DefaultLogDriver + } + + return DefaultLogDriver + +} + +func useSystemd() bool { + systemdOnce.Do(func() { + dat, err := ioutil.ReadFile("/proc/1/comm") + if err == nil { + val := strings.TrimSuffix(string(dat), "\n") + usesSystemd = (val == "systemd") + } + return + }) + return usesSystemd } diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go index 54661f433..ff3bf9a32 100644 --- a/vendor/github.com/containers/common/version/version.go +++ b/vendor/github.com/containers/common/version/version.go @@ -1,4 +1,4 @@ package version // Version is the version of the build. -const Version = "0.39.0" +const Version = "0.39.1-dev" diff --git a/vendor/modules.txt b/vendor/modules.txt index 879bb2759..c6a275a09 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -91,7 +91,7 @@ github.com/containers/buildah/pkg/overlay github.com/containers/buildah/pkg/parse github.com/containers/buildah/pkg/rusage github.com/containers/buildah/util -# github.com/containers/common v0.39.0 +# github.com/containers/common v0.39.1-0.20210527140106-e5800a20386a github.com/containers/common/libimage github.com/containers/common/libimage/manifests github.com/containers/common/pkg/apparmor -- cgit v1.2.3-54-g00ecf