aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/containers/common/libimage/pull.go2
-rw-r--r--vendor/github.com/containers/common/libimage/search.go18
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go3
-rw-r--r--vendor/github.com/containers/common/pkg/config/containers.conf6
-rw-r--r--vendor/github.com/containers/common/pkg/config/nosystemd.go4
-rw-r--r--vendor/github.com/containers/common/pkg/config/systemd.go20
-rw-r--r--vendor/github.com/containers/common/pkg/manifests/manifests.go2
-rw-r--r--vendor/github.com/containers/image/v5/copy/copy.go101
-rw-r--r--vendor/github.com/containers/image/v5/copy/manifest.go6
-rw-r--r--vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go59
-rw-r--r--vendor/github.com/containers/image/v5/types/types.go5
-rw-r--r--vendor/github.com/containers/image/v5/version/version.go4
-rw-r--r--vendor/github.com/containers/storage/.cirrus.yml4
-rw-r--r--vendor/github.com/containers/storage/Vagrantfile25
-rw-r--r--vendor/github.com/containers/storage/go.mod1
-rw-r--r--vendor/github.com/containers/storage/go.sum2
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/archive.go7
-rw-r--r--vendor/github.com/containers/storage/pkg/chunked/storage_linux.go327
-rw-r--r--vendor/github.com/containers/storage/types/options.go4
-rw-r--r--vendor/github.com/jinzhu/copier/copier.go13
-rw-r--r--vendor/github.com/jinzhu/copier/go.mod2
-rw-r--r--vendor/github.com/mitchellh/mapstructure/CHANGELOG.md4
-rw-r--r--vendor/github.com/mitchellh/mapstructure/mapstructure.go8
-rw-r--r--vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go3
-rw-r--r--vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go3
-rw-r--r--vendor/github.com/opencontainers/image-spec/specs-go/version.go2
26 files changed, 471 insertions, 164 deletions
diff --git a/vendor/github.com/containers/common/libimage/pull.go b/vendor/github.com/containers/common/libimage/pull.go
index 1d1bc201b..59221d935 100644
--- a/vendor/github.com/containers/common/libimage/pull.go
+++ b/vendor/github.com/containers/common/libimage/pull.go
@@ -454,7 +454,7 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str
// NOTE that this is will even override --pull={false,never}. This is
// very likely a bug but a consistent one in Podman/Buildah and should
// be addressed at a later point.
- if pullPolicy != config.PullPolicyAlways {
+ if pullPolicy != config.PullPolicyAlways && pullPolicy != config.PullPolicyNever {
switch {
// User input clearly refer to a local image.
case strings.HasPrefix(imageName, "localhost/"):
diff --git a/vendor/github.com/containers/common/libimage/search.go b/vendor/github.com/containers/common/libimage/search.go
index ece81531a..33a4776ce 100644
--- a/vendor/github.com/containers/common/libimage/search.go
+++ b/vendor/github.com/containers/common/libimage/search.go
@@ -58,6 +58,10 @@ type SearchOptions struct {
InsecureSkipTLSVerify types.OptionalBool
// ListTags returns the search result with available tags
ListTags bool
+ // Registries to search if the specified term does not include a
+ // registry. If set, the unqualified-search registries in
+ // containers-registries.conf(5) are ignored.
+ Registries []string
}
// SearchFilter allows filtering images while searching.
@@ -105,6 +109,10 @@ func ParseSearchFilter(filter []string) (*SearchFilter, error) {
return sFilter, nil
}
+// Search searches term. If term includes a registry, only this registry will
+// be used for searching. Otherwise, the unqualified-search registries in
+// containers-registries.conf(5) or the ones specified in the options will be
+// used.
func (r *Runtime) Search(ctx context.Context, term string, options *SearchOptions) ([]SearchResult, error) {
if options == nil {
options = &SearchOptions{}
@@ -117,10 +125,14 @@ func (r *Runtime) Search(ctx context.Context, term string, options *SearchOption
// that we cannot use the reference parser from the containers/image
// library as the search term may container arbitrary input such as
// wildcards. See bugzilla.redhat.com/show_bug.cgi?id=1846629.
- if spl := strings.SplitN(term, "/", 2); len(spl) > 1 {
- searchRegistries = append(searchRegistries, spl[0])
+ spl := strings.SplitN(term, "/", 2)
+ switch {
+ case len(spl) > 1:
+ searchRegistries = []string{spl[0]}
term = spl[1]
- } else {
+ case len(options.Registries) > 0:
+ searchRegistries = options.Registries
+ default:
regs, err := sysregistriesv2.UnqualifiedSearchRegistries(r.systemContextCopy())
if err != nil {
return nil, err
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
index 7ce0e5022..29c505e9c 100644
--- a/vendor/github.com/containers/common/pkg/config/config.go
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -420,6 +420,9 @@ type EngineConfig struct {
// ChownCopiedFiles tells the container engine whether to chown files copied
// into a container to the container's primary uid/gid.
ChownCopiedFiles bool `toml:"chown_copied_files,omitempty"`
+
+ // CompressionFormat is the compression format used to compress image layers.
+ CompressionFormat string `toml:"compression_format,omitempty"`
}
// SetOptions contains a subset of options in a Config. It's used to indicate if
diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf
index 8e305b57e..84b49b7e4 100644
--- a/vendor/github.com/containers/common/pkg/config/containers.conf
+++ b/vendor/github.com/containers/common/pkg/config/containers.conf
@@ -294,6 +294,12 @@ default_sysctls = [
#
#active_service = production
+# The compression format to use when pushing an image.
+# Valid options are: `gzip`, `zstd` and `zstd:chunked`.
+#
+#compression_format = "gzip"
+
+
# Cgroup management implementation used for the runtime.
# Valid options "systemd" or "cgroupfs"
#
diff --git a/vendor/github.com/containers/common/pkg/config/nosystemd.go b/vendor/github.com/containers/common/pkg/config/nosystemd.go
index 2a3b6fb35..f64b2dfc6 100644
--- a/vendor/github.com/containers/common/pkg/config/nosystemd.go
+++ b/vendor/github.com/containers/common/pkg/config/nosystemd.go
@@ -22,3 +22,7 @@ func defaultLogDriver() string {
func useSystemd() bool {
return false
}
+
+func useJournald() 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 fab3ea437..186e8b343 100644
--- a/vendor/github.com/containers/common/pkg/config/systemd.go
+++ b/vendor/github.com/containers/common/pkg/config/systemd.go
@@ -4,12 +4,12 @@ package config
import (
"io/ioutil"
+ "path/filepath"
"strings"
"sync"
"github.com/containers/common/pkg/cgroupv2"
"github.com/containers/storage/pkg/unshare"
- "github.com/coreos/go-systemd/v22/sdjournal"
)
var (
@@ -67,12 +67,20 @@ func useJournald() bool {
if !useSystemd() {
return
}
- journal, err := sdjournal.NewJournal()
- if err != nil {
- return
+ for _, root := range []string{"/run/log/journal", "/var/log/journal"} {
+ dirs, err := ioutil.ReadDir(root)
+ if err != nil {
+ continue
+ }
+ for _, d := range dirs {
+ if d.IsDir() {
+ if _, err := ioutil.ReadDir(filepath.Join(root, d.Name())); err == nil {
+ usesJournald = true
+ return
+ }
+ }
+ }
}
- journal.Close()
- usesJournald = true
return
})
return usesJournald
diff --git a/vendor/github.com/containers/common/pkg/manifests/manifests.go b/vendor/github.com/containers/common/pkg/manifests/manifests.go
index ea9495ee7..5c2836893 100644
--- a/vendor/github.com/containers/common/pkg/manifests/manifests.go
+++ b/vendor/github.com/containers/common/pkg/manifests/manifests.go
@@ -74,6 +74,7 @@ func Create() List {
},
oci: v1.Index{
Versioned: imgspec.Versioned{SchemaVersion: 2},
+ MediaType: v1.MediaTypeImageIndex,
},
}
}
@@ -373,6 +374,7 @@ func FromBlob(manifestBytes []byte) (List, error) {
},
oci: v1.Index{
Versioned: imgspec.Versioned{SchemaVersion: 2},
+ MediaType: v1.MediaTypeImageIndex,
},
}
switch manifestType {
diff --git a/vendor/github.com/containers/image/v5/copy/copy.go b/vendor/github.com/containers/image/v5/copy/copy.go
index e1649ba8e..317f8922a 100644
--- a/vendor/github.com/containers/image/v5/copy/copy.go
+++ b/vendor/github.com/containers/image/v5/copy/copy.go
@@ -80,13 +80,13 @@ type copier struct {
// imageCopier tracks state specific to a single image (possibly an item of a manifest list)
type imageCopier struct {
- c *copier
- manifestUpdates *types.ManifestUpdateOptions
- src types.Image
- diffIDsAreNeeded bool
- canModifyManifest bool
- canSubstituteBlobs bool
- ociEncryptLayers *[]int
+ c *copier
+ manifestUpdates *types.ManifestUpdateOptions
+ src types.Image
+ diffIDsAreNeeded bool
+ cannotModifyManifestReason string // The reason the manifest cannot be modified, or an empty string if it can
+ canSubstituteBlobs bool
+ ociEncryptLayers *[]int
}
const (
@@ -129,10 +129,14 @@ type Options struct {
DestinationCtx *types.SystemContext
ProgressInterval time.Duration // time to wait between reports to signal the progress channel
Progress chan types.ProgressProperties // Reported to when ProgressInterval has arrived for a single artifact+offset.
+
+ // Preserve digests, and fail if we cannot.
+ PreserveDigests bool
// manifest MIME type of image set by user. "" is default and means use the autodetection to the the manifest MIME type
ForceManifestMIMEType string
ImageListSelection ImageListSelection // set to either CopySystemImage (the default), CopyAllImages, or CopySpecificImages to control which instances we copy when the source reference is a list; ignored if the source reference is not a list
Instances []digest.Digest // if ImageListSelection is CopySpecificImages, copy only these instances and the list itself
+
// If OciEncryptConfig is non-nil, it indicates that an image should be encrypted.
// The encryption options is derived from the construction of EncryptConfig object.
// Note: During initial encryption process of a layer, the resultant digest is not known
@@ -410,7 +414,36 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur
return nil, errors.Wrapf(err, "Can not copy signatures to %s", transports.ImageName(c.dest.Reference()))
}
}
- canModifyManifestList := (len(sigs) == 0)
+
+ // If the destination is a digested reference, make a note of that, determine what digest value we're
+ // expecting, and check that the source manifest matches it.
+ destIsDigestedReference := false
+ if named := c.dest.Reference().DockerReference(); named != nil {
+ if digested, ok := named.(reference.Digested); ok {
+ destIsDigestedReference = true
+ matches, err := manifest.MatchesDigest(manifestList, digested.Digest())
+ if err != nil {
+ return nil, errors.Wrapf(err, "computing digest of source image's manifest")
+ }
+ if !matches {
+ return nil, errors.New("Digest of source image's manifest would not match destination reference")
+ }
+ }
+ }
+
+ // Determine if we're allowed to modify the manifest list.
+ // If we can, set to the empty string. If we can't, set to the reason why.
+ // Compare, and perhaps keep in sync with, the version in copyOneImage.
+ cannotModifyManifestListReason := ""
+ if len(sigs) > 0 {
+ cannotModifyManifestListReason = "Would invalidate signatures"
+ }
+ if destIsDigestedReference {
+ cannotModifyManifestListReason = "Destination specifies a digest"
+ }
+ if options.PreserveDigests {
+ cannotModifyManifestListReason = "Instructed to preserve digests"
+ }
// Determine if we'll need to convert the manifest list to a different format.
forceListMIMEType := options.ForceManifestMIMEType
@@ -425,8 +458,8 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur
return nil, errors.Wrapf(err, "determining manifest list type to write to destination")
}
if selectedListType != originalList.MIMEType() {
- if !canModifyManifestList {
- return nil, errors.Errorf("manifest list must be converted to type %q to be written to destination, but that would invalidate signatures", selectedListType)
+ if cannotModifyManifestListReason != "" {
+ return nil, errors.Errorf("Manifest list must be converted to type %q to be written to destination, but we cannot modify it: %q", selectedListType, cannotModifyManifestListReason)
}
}
@@ -510,8 +543,8 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur
// If we can't just use the original value, but we have to change it, flag an error.
if !bytes.Equal(attemptedManifestList, originalManifestList) {
- if !canModifyManifestList {
- return nil, errors.Errorf(" manifest list must be converted to type %q to be written to destination, but that would invalidate signatures", thisListType)
+ if cannotModifyManifestListReason != "" {
+ return nil, errors.Errorf("Manifest list must be converted to type %q to be written to destination, but we cannot modify it: %q", thisListType, cannotModifyManifestListReason)
}
logrus.Debugf("Manifest list has been updated")
} else {
@@ -629,13 +662,27 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli
}
}
+ // Determine if we're allowed to modify the manifest.
+ // If we can, set to the empty string. If we can't, set to the reason why.
+ // Compare, and perhaps keep in sync with, the version in copyMultipleImages.
+ cannotModifyManifestReason := ""
+ if len(sigs) > 0 {
+ cannotModifyManifestReason = "Would invalidate signatures"
+ }
+ if destIsDigestedReference {
+ cannotModifyManifestReason = "Destination specifies a digest"
+ }
+ if options.PreserveDigests {
+ cannotModifyManifestReason = "Instructed to preserve digests"
+ }
+
ic := imageCopier{
c: c,
manifestUpdates: &types.ManifestUpdateOptions{InformationOnly: types.ManifestUpdateInformation{Destination: c.dest}},
src: src,
// diffIDsAreNeeded is computed later
- canModifyManifest: len(sigs) == 0 && !destIsDigestedReference,
- ociEncryptLayers: options.OciEncryptLayers,
+ cannotModifyManifestReason: cannotModifyManifestReason,
+ ociEncryptLayers: options.OciEncryptLayers,
}
// Ensure _this_ copy sees exactly the intended data when either processing a signed image or signing it.
// This may be too conservative, but for now, better safe than sorry, _especially_ on the SignBy path:
@@ -643,7 +690,7 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli
// We do intend the RecordDigestUncompressedPair calls to only work with reliable data, but at least there’s a risk
// that the compressed version coming from a third party may be designed to attack some other decompressor implementation,
// and we would reuse and sign it.
- ic.canSubstituteBlobs = ic.canModifyManifest && options.SignBy == ""
+ ic.canSubstituteBlobs = ic.cannotModifyManifestReason == "" && options.SignBy == ""
if err := ic.updateEmbeddedDockerReference(); err != nil {
return nil, "", "", err
@@ -710,10 +757,10 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli
}
// If the original MIME type is acceptable, determineManifestConversion always uses it as preferredManifestMIMEType.
// So if we are here, we will definitely be trying to convert the manifest.
- // With !ic.canModifyManifest, that would just be a string of repeated failures for the same reason,
+ // With ic.cannotModifyManifestReason != "", that would just be a string of repeated failures for the same reason,
// so let’s bail out early and with a better error message.
- if !ic.canModifyManifest {
- return nil, "", "", errors.Wrap(err, "Writing manifest failed (and converting it is not possible, image is signed or the destination specifies a digest)")
+ if ic.cannotModifyManifestReason != "" {
+ return nil, "", "", errors.Wrapf(err, "Writing manifest failed and we cannot try conversions: %q", cannotModifyManifestReason)
}
// errs is a list of errors when trying various manifest types. Also serves as an "upload succeeded" flag when set to nil.
@@ -813,9 +860,9 @@ func (ic *imageCopier) updateEmbeddedDockerReference() error {
return nil // No reference embedded in the manifest, or it matches destRef already.
}
- if !ic.canModifyManifest {
- return errors.Errorf("Copying a schema1 image with an embedded Docker reference to %s (Docker reference %s) would change the manifest, which is not possible (image is signed or the destination specifies a digest)",
- transports.ImageName(ic.c.dest.Reference()), destRef.String())
+ if ic.cannotModifyManifestReason != "" {
+ return errors.Errorf("Copying a schema1 image with an embedded Docker reference to %s (Docker reference %s) would change the manifest, which we cannot do: %q",
+ transports.ImageName(ic.c.dest.Reference()), destRef.String(), ic.cannotModifyManifestReason)
}
ic.manifestUpdates.EmbeddedDockerReference = destRef
return nil
@@ -833,7 +880,7 @@ func isTTY(w io.Writer) bool {
return false
}
-// copyLayers copies layers from ic.src/ic.c.rawSource to dest, using and updating ic.manifestUpdates if necessary and ic.canModifyManifest.
+// copyLayers copies layers from ic.src/ic.c.rawSource to dest, using and updating ic.manifestUpdates if necessary and ic.cannotModifyManifestReason == "".
func (ic *imageCopier) copyLayers(ctx context.Context) error {
srcInfos := ic.src.LayerInfos()
numLayers := len(srcInfos)
@@ -844,8 +891,8 @@ func (ic *imageCopier) copyLayers(ctx context.Context) error {
srcInfosUpdated := false
// If we only need to check authorization, no updates required.
if updatedSrcInfos != nil && !reflect.DeepEqual(srcInfos, updatedSrcInfos) {
- if !ic.canModifyManifest {
- return errors.Errorf("Copying this image requires changing layer representation, which is not possible (image is signed or the destination specifies a digest)")
+ if ic.cannotModifyManifestReason != "" {
+ return errors.Errorf("Copying this image would require changing layer representation, which we cannot do: %q", ic.cannotModifyManifestReason)
}
srcInfos = updatedSrcInfos
srcInfosUpdated = true
@@ -975,8 +1022,8 @@ func layerDigestsDiffer(a, b []types.BlobInfo) bool {
func (ic *imageCopier) copyUpdatedConfigAndManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, digest.Digest, error) {
pendingImage := ic.src
if !ic.noPendingManifestUpdates() {
- if !ic.canModifyManifest {
- return nil, "", errors.Errorf("Internal error: copy needs an updated manifest but that was known to be forbidden")
+ if ic.cannotModifyManifestReason != "" {
+ return nil, "", errors.Errorf("Internal error: copy needs an updated manifest but that was known to be forbidden: %q", ic.cannotModifyManifestReason)
}
if !ic.diffIDsAreNeeded && ic.src.UpdatedImageNeedsLayerDiffIDs(*ic.manifestUpdates) {
// We have set ic.diffIDsAreNeeded based on the preferred MIME type returned by determineManifestConversion.
@@ -1359,7 +1406,7 @@ func (ic *imageCopier) copyLayerFromStream(ctx context.Context, srcStream io.Rea
}
}
- blobInfo, err := ic.c.copyBlobFromStream(ctx, srcStream, srcInfo, getDiffIDRecorder, ic.canModifyManifest, false, toEncrypt, bar, layerIndex, emptyLayer) // Sets err to nil on success
+ blobInfo, err := ic.c.copyBlobFromStream(ctx, srcStream, srcInfo, getDiffIDRecorder, ic.cannotModifyManifestReason == "", false, toEncrypt, bar, layerIndex, emptyLayer) // Sets err to nil on success
return blobInfo, diffIDChan, err
// We need the defer … pipeWriter.CloseWithError() to happen HERE so that the caller can block on reading from diffIDChan
}
diff --git a/vendor/github.com/containers/image/v5/copy/manifest.go b/vendor/github.com/containers/image/v5/copy/manifest.go
index b97edbf08..86ec8863a 100644
--- a/vendor/github.com/containers/image/v5/copy/manifest.go
+++ b/vendor/github.com/containers/image/v5/copy/manifest.go
@@ -79,10 +79,10 @@ func (ic *imageCopier) determineManifestConversion(ctx context.Context, destSupp
if _, ok := supportedByDest[srcType]; ok {
prioritizedTypes.append(srcType)
}
- if !ic.canModifyManifest {
- // We could also drop the !ic.canModifyManifest check and have the caller
+ if ic.cannotModifyManifestReason != "" {
+ // We could also drop this check and have the caller
// make the choice; it is already doing that to an extent, to improve error
- // messages. But it is nice to hide the “if !ic.canModifyManifest, do no conversion”
+ // messages. But it is nice to hide the “if we can't modify, do no conversion”
// special case in here; the caller can then worry (or not) only about a good UI.
logrus.Debugf("We can't modify the manifest, hoping for the best...")
return srcType, []string{}, nil // Take our chances - FIXME? Or should we fail without trying?
diff --git a/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go b/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go
index fb0a15b99..46c10ff63 100644
--- a/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go
+++ b/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go
@@ -118,6 +118,7 @@ type Resolved struct {
}
func (r *Resolved) addCandidate(named reference.Named) {
+ named = reference.TagNameOnly(named) // Make sure to add ":latest" if needed
r.PullCandidates = append(r.PullCandidates, PullCandidate{named, false, r})
}
@@ -138,6 +139,8 @@ const (
rationaleUSR
// Resolved value has been selected by the user (via the prompt).
rationaleUserSelection
+ // Resolved value has been enforced to use Docker Hub (via SystemContext).
+ rationaleEnforcedDockerHub
)
// Description returns a human-readable description about the resolution
@@ -152,6 +155,8 @@ func (r *Resolved) Description() string {
return fmt.Sprintf("Resolved %q as an alias (%s)", r.userInput, r.originDescription)
case rationaleUSR:
return fmt.Sprintf("Resolving %q using unqualified-search registries (%s)", r.userInput, r.originDescription)
+ case rationaleEnforcedDockerHub:
+ return fmt.Sprintf("Resolving %q to docker.io (%s)", r.userInput, r.originDescription)
case rationaleUserSelection, rationaleNone:
fallthrough
default:
@@ -265,8 +270,20 @@ func Resolve(ctx *types.SystemContext, name string) (*Resolved, error) {
return nil, err
}
if !isShort { // no short name
- named := reference.TagNameOnly(shortRef) // Make sure to add ":latest" if needed
+ resolved.addCandidate(shortRef)
+ return resolved, nil
+ }
+
+ // Resolve to docker.io only if enforced by the caller (e.g., Podman's
+ // Docker-compatible REST API).
+ if ctx != nil && ctx.PodmanOnlyShortNamesIgnoreRegistriesConfAndForceDockerHub {
+ named, err := reference.ParseNormalizedNamed(name)
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot normalize input: %q", name)
+ }
resolved.addCandidate(named)
+ resolved.rationale = rationaleEnforcedDockerHub
+ resolved.originDescription = "enforced by caller"
return resolved, nil
}
@@ -295,9 +312,6 @@ func Resolve(ctx *types.SystemContext, name string) (*Resolved, error) {
return nil, err
}
}
- // Make sure to add ":latest" if needed
- namedAlias = reference.TagNameOnly(namedAlias)
-
resolved.addCandidate(namedAlias)
resolved.rationale = rationaleAlias
resolved.originDescription = aliasOriginDescription
@@ -325,9 +339,6 @@ func Resolve(ctx *types.SystemContext, name string) (*Resolved, error) {
if err != nil {
return nil, errors.Wrapf(err, "creating reference with unqualified-search registry %q", reg)
}
- // Make sure to add ":latest" if needed
- named = reference.TagNameOnly(named)
-
resolved.addCandidate(named)
}
@@ -412,6 +423,23 @@ func ResolveLocally(ctx *types.SystemContext, name string) ([]reference.Named, e
var candidates []reference.Named
+ // Complete the candidates with the specified registries.
+ completeCandidates := func(registries []string) ([]reference.Named, error) {
+ for _, reg := range registries {
+ named, err := reference.ParseNormalizedNamed(fmt.Sprintf("%s/%s", reg, name))
+ if err != nil {
+ return nil, errors.Wrapf(err, "creating reference with unqualified-search registry %q", reg)
+ }
+ named = reference.TagNameOnly(named) // Make sure to add ":latest" if needed
+ candidates = append(candidates, named)
+ }
+ return candidates, nil
+ }
+
+ if ctx != nil && ctx.PodmanOnlyShortNamesIgnoreRegistriesConfAndForceDockerHub {
+ return completeCandidates([]string{"docker.io"})
+ }
+
// Strip off the tag to normalize the short name for looking it up in
// the config files.
isTagged, isDigested, shortNameRepo, tag, digest := splitUserInput(shortRef)
@@ -434,9 +462,7 @@ func ResolveLocally(ctx *types.SystemContext, name string) ([]reference.Named, e
return nil, err
}
}
- // Make sure to add ":latest" if needed
- namedAlias = reference.TagNameOnly(namedAlias)
-
+ namedAlias = reference.TagNameOnly(namedAlias) // Make sure to add ":latest" if needed
candidates = append(candidates, namedAlias)
}
@@ -447,16 +473,5 @@ func ResolveLocally(ctx *types.SystemContext, name string) ([]reference.Named, e
}
// Note that "localhost" has precedence over the unqualified-search registries.
- for _, reg := range append([]string{"localhost"}, unqualifiedSearchRegistries...) {
- named, err := reference.ParseNormalizedNamed(fmt.Sprintf("%s/%s", reg, name))
- if err != nil {
- return nil, errors.Wrapf(err, "creating reference with unqualified-search registry %q", reg)
- }
- // Make sure to add ":latest" if needed
- named = reference.TagNameOnly(named)
-
- candidates = append(candidates, named)
- }
-
- return candidates, nil
+ return completeCandidates(append([]string{"localhost"}, unqualifiedSearchRegistries...))
}
diff --git a/vendor/github.com/containers/image/v5/types/types.go b/vendor/github.com/containers/image/v5/types/types.go
index c98a6c6fd..dcff8caf7 100644
--- a/vendor/github.com/containers/image/v5/types/types.go
+++ b/vendor/github.com/containers/image/v5/types/types.go
@@ -561,6 +561,11 @@ type SystemContext struct {
UserShortNameAliasConfPath string
// If set, short-name resolution in pkg/shortnames must follow the specified mode
ShortNameMode *ShortNameMode
+ // If set, short names will resolve in pkg/shortnames to docker.io only, and unqualified-search registries and
+ // short-name aliases in registries.conf are ignored. Note that this field is only intended to help enforce
+ // resolving to Docker Hub in the Docker-compatible REST API of Podman; it should never be used outside this
+ // specific context.
+ PodmanOnlyShortNamesIgnoreRegistriesConfAndForceDockerHub bool
// If not "", overrides the default path for the authentication file, but only new format files
AuthFilePath string
// if not "", overrides the default path for the authentication file, but with the legacy format;
diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go
index ffb2a4ce2..17639f0d4 100644
--- a/vendor/github.com/containers/image/v5/version/version.go
+++ b/vendor/github.com/containers/image/v5/version/version.go
@@ -8,10 +8,10 @@ const (
// VersionMinor is for functionality in a backwards-compatible manner
VersionMinor = 17
// VersionPatch is for backwards-compatible bug fixes
- VersionPatch = 0
+ VersionPatch = 1
// VersionDev indicates development branch. Releases will be empty string.
- VersionDev = ""
+ VersionDev = "-dev"
)
// Version is the specification version that the package types support.
diff --git a/vendor/github.com/containers/storage/.cirrus.yml b/vendor/github.com/containers/storage/.cirrus.yml
index d080d790c..726acc3ae 100644
--- a/vendor/github.com/containers/storage/.cirrus.yml
+++ b/vendor/github.com/containers/storage/.cirrus.yml
@@ -17,8 +17,8 @@ env:
####
#### Cache-image names to test with (double-quotes around names are critical)
###
- FEDORA_NAME: "fedora-34"
- PRIOR_FEDORA_NAME: "fedora-33"
+ FEDORA_NAME: "fedora-35"
+ PRIOR_FEDORA_NAME: "fedora-34"
UBUNTU_NAME: "ubuntu-2104"
# GCE project where images live
diff --git a/vendor/github.com/containers/storage/Vagrantfile b/vendor/github.com/containers/storage/Vagrantfile
deleted file mode 100644
index c82c1f81b..000000000
--- a/vendor/github.com/containers/storage/Vagrantfile
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- mode: ruby -*-
-# vi: set ft=ruby :
-#
-# The fedora/28-cloud-base and debian/jessie64 boxes are also available for
-# the "virtualbox" provider. Set the VAGRANT_PROVIDER environment variable to
-# "virtualbox" to use them instead.
-#
-Vagrant.configure("2") do |config|
- config.vm.define "fedora" do |c|
- c.vm.box = "fedora/28-cloud-base"
- c.vm.synced_folder ".", "/vagrant", type: "rsync",
- rsync__exclude: "bundles", rsync__args: ["-vadz", "--delete"]
- c.vm.provision "shell", inline: <<-SHELL
- sudo /vagrant/vagrant/provision.sh
- SHELL
- end
- config.vm.define "debian" do |c|
- c.vm.box = "debian/jessie64"
- c.vm.synced_folder ".", "/vagrant", type: "rsync",
- rsync__exclude: "bundles", rsync__args: ["-vadz", "--delete"]
- c.vm.provision "shell", inline: <<-SHELL
- sudo /vagrant/vagrant/provision.sh
- SHELL
- end
-end
diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod
index 04d5adac4..57b634f17 100644
--- a/vendor/github.com/containers/storage/go.mod
+++ b/vendor/github.com/containers/storage/go.mod
@@ -7,6 +7,7 @@ require (
github.com/Microsoft/go-winio v0.5.1
github.com/Microsoft/hcsshim v0.9.1
github.com/containerd/stargz-snapshotter/estargz v0.10.1
+ github.com/cyphar/filepath-securejoin v0.2.3
github.com/docker/go-units v0.4.0
github.com/google/go-intervals v0.0.2
github.com/hashicorp/go-multierror v1.1.1
diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum
index 35328e287..94d46b21a 100644
--- a/vendor/github.com/containers/storage/go.sum
+++ b/vendor/github.com/containers/storage/go.sum
@@ -218,6 +218,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
+github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
+github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
diff --git a/vendor/github.com/containers/storage/pkg/archive/archive.go b/vendor/github.com/containers/storage/pkg/archive/archive.go
index 76544ff28..e7c4cfcf1 100644
--- a/vendor/github.com/containers/storage/pkg/archive/archive.go
+++ b/vendor/github.com/containers/storage/pkg/archive/archive.go
@@ -77,6 +77,10 @@ const (
containersOverrideXattr = "user.containers.override_stat"
)
+var xattrsToIgnore = map[string]interface{}{
+ "security.selinux": true,
+}
+
// Archiver allows the reuse of most utility functions of this package with a
// pluggable Untar function. To facilitate the passing of specific id mappings
// for untar, an archiver can be created with maps which will then be passed to
@@ -743,6 +747,9 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L
var errs []string
for key, value := range hdr.Xattrs {
+ if _, found := xattrsToIgnore[key]; found {
+ continue
+ }
if err := system.Lsetxattr(path, key, []byte(value), 0); err != nil {
if errors.Is(err, syscall.ENOTSUP) || (inUserns && errors.Is(err, syscall.EPERM)) {
// We ignore errors here because not all graphdrivers support
diff --git a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
index d18ab299b..52d21d689 100644
--- a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
+++ b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
@@ -13,6 +13,7 @@ import (
"reflect"
"sort"
"strings"
+ "sync/atomic"
"syscall"
"time"
@@ -25,6 +26,7 @@ import (
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/system"
"github.com/containers/storage/types"
+ securejoin "github.com/cyphar/filepath-securejoin"
"github.com/klauspost/compress/zstd"
"github.com/klauspost/pgzip"
digest "github.com/opencontainers/go-digest"
@@ -57,6 +59,10 @@ type chunkedDiffer struct {
gzipReader *pgzip.Reader
}
+var xattrsToIgnore = map[string]interface{}{
+ "security.selinux": true,
+}
+
func timeToTimespec(time time.Time) (ts unix.Timespec) {
if time.IsZero() {
// Return UTIME_OMIT special value
@@ -89,7 +95,7 @@ func copyFileContent(srcFd int, destFile string, dirfd int, mode os.FileMode, us
src := fmt.Sprintf("/proc/self/fd/%d", srcFd)
st, err := os.Stat(src)
if err != nil {
- return nil, -1, err
+ return nil, -1, fmt.Errorf("copy file content for %q: %w", destFile, err)
}
copyWithFileRange, copyWithFileClone := true, true
@@ -111,15 +117,15 @@ func copyFileContent(srcFd int, destFile string, dirfd int, mode os.FileMode, us
// If the destination file already exists, we shouldn't blow it away
dstFile, err := openFileUnderRoot(destFile, dirfd, newFileFlags, mode)
if err != nil {
- return nil, -1, err
+ return nil, -1, fmt.Errorf("open file %q under rootfs for copy: %w", destFile, err)
}
err = driversCopy.CopyRegularToFile(src, dstFile, st, &copyWithFileRange, &copyWithFileClone)
if err != nil {
dstFile.Close()
- return nil, -1, err
+ return nil, -1, fmt.Errorf("copy to file %q under rootfs: %w", destFile, err)
}
- return dstFile, st.Size(), err
+ return dstFile, st.Size(), nil
}
func prepareOtherLayersCache(layersMetadata map[string][]internal.FileMetadata) map[string]map[string][]*internal.FileMetadata {
@@ -153,7 +159,7 @@ func getLayersCache(store storage.Store) (map[string][]internal.FileMetadata, ma
defer manifestReader.Close()
manifest, err := ioutil.ReadAll(manifestReader)
if err != nil {
- return nil, nil, err
+ return nil, nil, fmt.Errorf("open manifest file for layer %q: %w", r.ID, err)
}
var toc internal.TOC
if err := json.Unmarshal(manifest, &toc); err != nil {
@@ -162,7 +168,7 @@ func getLayersCache(store storage.Store) (map[string][]internal.FileMetadata, ma
layersMetadata[r.ID] = toc.Entries
target, err := store.DifferTarget(r.ID)
if err != nil {
- return nil, nil, err
+ return nil, nil, fmt.Errorf("get checkout directory layer %q: %w", r.ID, err)
}
layersTarget[r.ID] = target
}
@@ -184,7 +190,7 @@ func GetDiffer(ctx context.Context, store storage.Store, blobSize int64, annotat
func makeZstdChunkedDiffer(ctx context.Context, store storage.Store, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (*chunkedDiffer, error) {
manifest, tocOffset, err := readZstdChunkedManifest(iss, blobSize, annotations)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("read zstd:chunked manifest: %w", err)
}
layersMetadata, layersTarget, err := getLayersCache(store)
if err != nil {
@@ -204,7 +210,7 @@ func makeZstdChunkedDiffer(ctx context.Context, store storage.Store, blobSize in
func makeEstargzChunkedDiffer(ctx context.Context, store storage.Store, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (*chunkedDiffer, error) {
manifest, tocOffset, err := readEstargzChunkedManifest(iss, blobSize, annotations)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("read zstd:chunked manifest: %w", err)
}
layersMetadata, layersTarget, err := getLayersCache(store)
if err != nil {
@@ -230,21 +236,21 @@ func makeEstargzChunkedDiffer(ctx context.Context, store storage.Store, blobSize
func copyFileFromOtherLayer(file *internal.FileMetadata, source string, otherFile *internal.FileMetadata, dirfd int, useHardLinks bool) (bool, *os.File, int64, error) {
srcDirfd, err := unix.Open(source, unix.O_RDONLY, 0)
if err != nil {
- return false, nil, 0, err
+ return false, nil, 0, fmt.Errorf("open source file %q: %w", source, err)
}
defer unix.Close(srcDirfd)
srcFile, err := openFileUnderRoot(otherFile.Name, srcDirfd, unix.O_RDONLY, 0)
if err != nil {
- return false, nil, 0, err
+ return false, nil, 0, fmt.Errorf("open source file %q under target rootfs: %w", otherFile.Name, err)
}
defer srcFile.Close()
dstFile, written, err := copyFileContent(int(srcFile.Fd()), file.Name, dirfd, 0, useHardLinks)
if err != nil {
- return false, nil, 0, err
+ return false, nil, 0, fmt.Errorf("copy content to %q: %w", file.Name, err)
}
- return true, dstFile, written, err
+ return true, dstFile, written, nil
}
// canDedupMetadataWithHardLink says whether it is possible to deduplicate file with otherFile.
@@ -280,10 +286,6 @@ func canDedupFileWithHardLink(file *internal.FileMetadata, fd int, s os.FileInfo
return false
}
- xattrsToIgnore := map[string]interface{}{
- "security.selinux": true,
- }
-
xattrs := make(map[string]string)
for _, x := range listXattrs {
v, err := system.Lgetxattr(path, x)
@@ -510,7 +512,7 @@ type missingChunk struct {
}
// setFileAttrs sets the file attributes for file given metadata
-func setFileAttrs(file *os.File, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
+func setFileAttrs(dirfd int, file *os.File, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions, usePath bool) error {
if file == nil || file.Fd() < 0 {
return errors.Errorf("invalid file")
}
@@ -520,54 +522,237 @@ func setFileAttrs(file *os.File, mode os.FileMode, metadata *internal.FileMetada
if err != nil {
return err
}
+
+ // If it is a symlink, force to use the path
if t == tar.TypeSymlink {
- return nil
+ usePath = true
+ }
+
+ baseName := ""
+ if usePath {
+ dirName := filepath.Dir(metadata.Name)
+ if dirName != "" {
+ parentFd, err := openFileUnderRoot(dirName, dirfd, unix.O_PATH|unix.O_DIRECTORY, 0)
+ if err != nil {
+ return err
+ }
+ defer parentFd.Close()
+
+ dirfd = int(parentFd.Fd())
+ }
+ baseName = filepath.Base(metadata.Name)
+ }
+
+ doChown := func() error {
+ if usePath {
+ return unix.Fchownat(dirfd, baseName, metadata.UID, metadata.GID, unix.AT_SYMLINK_NOFOLLOW)
+ }
+ return unix.Fchown(fd, metadata.UID, metadata.GID)
+ }
+
+ doSetXattr := func(k string, v []byte) error {
+ return unix.Fsetxattr(fd, k, v, 0)
+ }
+
+ doUtimes := func() error {
+ ts := []unix.Timespec{timeToTimespec(metadata.AccessTime), timeToTimespec(metadata.ModTime)}
+ if usePath {
+ return unix.UtimesNanoAt(dirfd, baseName, ts, unix.AT_SYMLINK_NOFOLLOW)
+ }
+ return unix.UtimesNanoAt(unix.AT_FDCWD, fmt.Sprintf("/proc/self/fd/%d", fd), ts, 0)
+ }
+
+ doChmod := func() error {
+ if usePath {
+ return unix.Fchmodat(dirfd, baseName, uint32(mode), unix.AT_SYMLINK_NOFOLLOW)
+ }
+ return unix.Fchmod(fd, uint32(mode))
}
- if err := unix.Fchown(fd, metadata.UID, metadata.GID); err != nil {
+ if err := doChown(); err != nil {
if !options.IgnoreChownErrors {
- return err
+ return fmt.Errorf("chown %q to %d:%d: %w", metadata.Name, metadata.UID, metadata.GID, err)
}
}
+ canIgnore := func(err error) bool {
+ return err == nil || errors.Is(err, unix.ENOSYS) || errors.Is(err, unix.ENOTSUP)
+ }
+
for k, v := range metadata.Xattrs {
+ if _, found := xattrsToIgnore[k]; found {
+ continue
+ }
data, err := base64.StdEncoding.DecodeString(v)
if err != nil {
- return err
+ return fmt.Errorf("decode xattr %q: %w", v, err)
}
- if err := unix.Fsetxattr(fd, k, data, 0); err != nil {
- return err
+ if err := doSetXattr(k, data); !canIgnore(err) {
+ return fmt.Errorf("set xattr %s=%q for %q: %w", k, data, metadata.Name, err)
}
}
- ts := []unix.Timespec{timeToTimespec(metadata.AccessTime), timeToTimespec(metadata.ModTime)}
- if err := unix.UtimesNanoAt(fd, "", ts, 0); err != nil && errors.Is(err, unix.ENOSYS) {
- return err
+ if err := doUtimes(); !canIgnore(err) {
+ return fmt.Errorf("set utimes for %q: %w", metadata.Name, err)
}
- if err := unix.Fchmod(fd, uint32(mode)); err != nil {
- return err
+ if err := doChmod(); !canIgnore(err) {
+ return fmt.Errorf("chmod %q: %w", metadata.Name, err)
}
return nil
}
+func openFileUnderRootFallback(dirfd int, name string, flags uint64, mode os.FileMode) (int, error) {
+ root := fmt.Sprintf("/proc/self/fd/%d", dirfd)
+
+ targetRoot, err := os.Readlink(root)
+ if err != nil {
+ return -1, err
+ }
+
+ hasNoFollow := (flags & unix.O_NOFOLLOW) != 0
+
+ fd := -1
+ // If O_NOFOLLOW is specified in the flags, then resolve only the parent directory and use the
+ // last component as the path to openat().
+ if hasNoFollow {
+ dirName := filepath.Dir(name)
+ if dirName != "" {
+ newRoot, err := securejoin.SecureJoin(root, filepath.Dir(name))
+ if err != nil {
+ return -1, err
+ }
+ root = newRoot
+ }
+
+ parentDirfd, err := unix.Open(root, unix.O_PATH, 0)
+ if err != nil {
+ return -1, err
+ }
+ defer unix.Close(parentDirfd)
+
+ fd, err = unix.Openat(parentDirfd, filepath.Base(name), int(flags), uint32(mode))
+ if err != nil {
+ return -1, err
+ }
+ } else {
+ newPath, err := securejoin.SecureJoin(root, name)
+ if err != nil {
+ return -1, err
+ }
+ fd, err = unix.Openat(dirfd, newPath, int(flags), uint32(mode))
+ if err != nil {
+ return -1, err
+ }
+ }
+
+ target, err := os.Readlink(fmt.Sprintf("/proc/self/fd/%d", fd))
+ if err != nil {
+ unix.Close(fd)
+ return -1, err
+ }
+
+ // Add an additional check to make sure the opened fd is inside the rootfs
+ if !strings.HasPrefix(target, targetRoot) {
+ unix.Close(fd)
+ return -1, fmt.Errorf("error while resolving %q. It resolves outside the root directory", name)
+ }
+
+ return fd, err
+}
+
+func openFileUnderRootOpenat2(dirfd int, name string, flags uint64, mode os.FileMode) (int, error) {
+ how := unix.OpenHow{
+ Flags: flags,
+ Mode: uint64(mode & 07777),
+ Resolve: unix.RESOLVE_IN_ROOT,
+ }
+ return unix.Openat2(dirfd, name, &how)
+}
+
+// skipOpenat2 is set when openat2 is not supported by the underlying kernel and avoid
+// using it again.
+var skipOpenat2 int32
+
+// openFileUnderRootRaw tries to open a file using openat2 and if it is not supported fallbacks to a
+// userspace lookup.
+func openFileUnderRootRaw(dirfd int, name string, flags uint64, mode os.FileMode) (int, error) {
+ var fd int
+ var err error
+ if atomic.LoadInt32(&skipOpenat2) > 0 {
+ fd, err = openFileUnderRootFallback(dirfd, name, flags, mode)
+ } else {
+ fd, err = openFileUnderRootOpenat2(dirfd, name, flags, mode)
+ // If the function failed with ENOSYS, switch off the support for openat2
+ // and fallback to using safejoin.
+ if err != nil && errors.Is(err, unix.ENOSYS) {
+ atomic.StoreInt32(&skipOpenat2, 1)
+ fd, err = openFileUnderRootFallback(dirfd, name, flags, mode)
+ }
+ }
+ return fd, err
+}
+
// openFileUnderRoot safely opens a file under the specified root directory using openat2
// name is the path to open relative to dirfd.
// dirfd is an open file descriptor to the target checkout directory.
-// flags are the flags top pass to the open syscall.
+// flags are the flags to pass to the open syscall.
// mode specifies the mode to use for newly created files.
func openFileUnderRoot(name string, dirfd int, flags uint64, mode os.FileMode) (*os.File, error) {
- how := unix.OpenHow{
- Flags: flags,
- Mode: uint64(mode & 07777),
- Resolve: unix.RESOLVE_IN_ROOT,
+ fd, err := openFileUnderRootRaw(dirfd, name, flags, mode)
+ if err == nil {
+ return os.NewFile(uintptr(fd), name), nil
+ }
+
+ hasCreate := (flags & unix.O_CREAT) != 0
+ if errors.Is(err, unix.ENOENT) && hasCreate {
+ parent := filepath.Dir(name)
+ if parent != "" {
+ newDirfd, err2 := openOrCreateDirUnderRoot(parent, dirfd, 0)
+ if err2 == nil {
+ defer newDirfd.Close()
+ fd, err := openFileUnderRootRaw(dirfd, name, flags, mode)
+ if err == nil {
+ return os.NewFile(uintptr(fd), name), nil
+ }
+ }
+ }
}
+ return nil, fmt.Errorf("open %q under the rootfs: %w", name, err)
+}
- fd, err := unix.Openat2(dirfd, name, &how)
- if err != nil {
- return nil, err
+// openOrCreateDirUnderRoot safely opens a directory or create it if it is missing.
+// name is the path to open relative to dirfd.
+// dirfd is an open file descriptor to the target checkout directory.
+// mode specifies the mode to use for newly created files.
+func openOrCreateDirUnderRoot(name string, dirfd int, mode os.FileMode) (*os.File, error) {
+ fd, err := openFileUnderRootRaw(dirfd, name, unix.O_DIRECTORY|unix.O_RDONLY, mode)
+ if err == nil {
+ return os.NewFile(uintptr(fd), name), nil
+ }
+
+ if errors.Is(err, unix.ENOENT) {
+ parent := filepath.Dir(name)
+ if parent != "" {
+ pDir, err2 := openOrCreateDirUnderRoot(parent, dirfd, mode)
+ if err2 != nil {
+ return nil, err
+ }
+ defer pDir.Close()
+
+ baseName := filepath.Base(name)
+
+ if err2 := unix.Mkdirat(int(pDir.Fd()), baseName, 0755); err2 != nil {
+ return nil, err
+ }
+
+ fd, err = openFileUnderRootRaw(int(pDir.Fd()), baseName, unix.O_DIRECTORY|unix.O_RDONLY, mode)
+ if err == nil {
+ return os.NewFile(uintptr(fd), name), nil
+ }
+ }
}
- return os.NewFile(uintptr(fd), name), nil
+ return nil, err
}
func (c *chunkedDiffer) createFileFromCompressedStream(dest string, dirfd int, reader io.Reader, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) (err error) {
@@ -631,7 +816,7 @@ func (c *chunkedDiffer) createFileFromCompressedStream(dest string, dirfd int, r
if digester.Digest() != manifestChecksum {
return fmt.Errorf("checksum mismatch for %q", dest)
}
- return setFileAttrs(file, mode, metadata, options)
+ return setFileAttrs(dirfd, file, mode, metadata, options, false)
}
func (c *chunkedDiffer) storeMissingFiles(streams chan io.ReadCloser, errs chan error, dest string, dirfd int, missingChunks []missingChunk, options *archive.TarOptions) error {
@@ -755,13 +940,13 @@ func (c *chunkedDiffer) retrieveMissingFiles(dest string, dirfd int, missingChun
return nil
}
-func safeMkdir(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
- parent := filepath.Dir(metadata.Name)
- base := filepath.Base(metadata.Name)
+func safeMkdir(dirfd int, mode os.FileMode, name string, metadata *internal.FileMetadata, options *archive.TarOptions) error {
+ parent := filepath.Dir(name)
+ base := filepath.Base(name)
parentFd := dirfd
if parent != "." {
- parentFile, err := openFileUnderRoot(parent, dirfd, unix.O_DIRECTORY|unix.O_PATH|unix.O_RDONLY, 0)
+ parentFile, err := openOrCreateDirUnderRoot(parent, dirfd, 0)
if err != nil {
return err
}
@@ -771,21 +956,21 @@ func safeMkdir(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, opt
if err := unix.Mkdirat(parentFd, base, uint32(mode)); err != nil {
if !os.IsExist(err) {
- return err
+ return fmt.Errorf("mkdir %q: %w", name, err)
}
}
- file, err := openFileUnderRoot(metadata.Name, dirfd, unix.O_RDONLY, 0)
+ file, err := openFileUnderRoot(name, dirfd, unix.O_DIRECTORY|unix.O_RDONLY, 0)
if err != nil {
return err
}
defer file.Close()
- return setFileAttrs(file, mode, metadata, options)
+ return setFileAttrs(dirfd, file, mode, metadata, options, false)
}
func safeLink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
- sourceFile, err := openFileUnderRoot(metadata.Linkname, dirfd, unix.O_RDONLY, 0)
+ sourceFile, err := openFileUnderRoot(metadata.Linkname, dirfd, unix.O_PATH|unix.O_RDONLY|unix.O_NOFOLLOW, 0)
if err != nil {
return err
}
@@ -794,7 +979,7 @@ func safeLink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, opti
destDir, destBase := filepath.Dir(metadata.Name), filepath.Base(metadata.Name)
destDirFd := dirfd
if destDir != "." {
- f, err := openFileUnderRoot(destDir, dirfd, unix.O_RDONLY, 0)
+ f, err := openOrCreateDirUnderRoot(destDir, dirfd, 0)
if err != nil {
return err
}
@@ -804,23 +989,33 @@ func safeLink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, opti
err = doHardLink(int(sourceFile.Fd()), destDirFd, destBase)
if err != nil {
- return err
+ return fmt.Errorf("create hardlink %q pointing to %q: %w", metadata.Name, metadata.Linkname, err)
}
- newFile, err := openFileUnderRoot(metadata.Name, dirfd, unix.O_WRONLY, 0)
+ newFile, err := openFileUnderRoot(metadata.Name, dirfd, unix.O_WRONLY|unix.O_NOFOLLOW, 0)
if err != nil {
+ // If the target is a symlink, open the file with O_PATH.
+ if errors.Is(err, unix.ELOOP) {
+ newFile, err := openFileUnderRoot(metadata.Name, dirfd, unix.O_PATH|unix.O_NOFOLLOW, 0)
+ if err != nil {
+ return err
+ }
+ defer newFile.Close()
+
+ return setFileAttrs(dirfd, newFile, mode, metadata, options, true)
+ }
return err
}
defer newFile.Close()
- return setFileAttrs(newFile, mode, metadata, options)
+ return setFileAttrs(dirfd, newFile, mode, metadata, options, false)
}
func safeSymlink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
destDir, destBase := filepath.Dir(metadata.Name), filepath.Base(metadata.Name)
destDirFd := dirfd
if destDir != "." {
- f, err := openFileUnderRoot(destDir, dirfd, unix.O_RDONLY, 0)
+ f, err := openOrCreateDirUnderRoot(destDir, dirfd, 0)
if err != nil {
return err
}
@@ -828,7 +1023,10 @@ func safeSymlink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, o
destDirFd = int(f.Fd())
}
- return unix.Symlinkat(metadata.Linkname, destDirFd, destBase)
+ if err := unix.Symlinkat(metadata.Linkname, destDirFd, destBase); err != nil {
+ return fmt.Errorf("create symlink %q pointing to %q: %w", metadata.Name, metadata.Linkname, err)
+ }
+ return nil
}
type whiteoutHandler struct {
@@ -837,13 +1035,16 @@ type whiteoutHandler struct {
}
func (d whiteoutHandler) Setxattr(path, name string, value []byte) error {
- file, err := openFileUnderRoot(path, d.Dirfd, unix.O_RDONLY, 0)
+ file, err := openOrCreateDirUnderRoot(path, d.Dirfd, 0)
if err != nil {
return err
}
defer file.Close()
- return unix.Fsetxattr(int(file.Fd()), name, value, 0)
+ if err := unix.Fsetxattr(int(file.Fd()), name, value, 0); err != nil {
+ return fmt.Errorf("set xattr %s=%q for %q: %w", name, value, path, err)
+ }
+ return nil
}
func (d whiteoutHandler) Mknod(path string, mode uint32, dev int) error {
@@ -852,7 +1053,7 @@ func (d whiteoutHandler) Mknod(path string, mode uint32, dev int) error {
dirfd := d.Dirfd
if dir != "" {
- dir, err := openFileUnderRoot(dir, d.Dirfd, unix.O_RDONLY, 0)
+ dir, err := openOrCreateDirUnderRoot(dir, d.Dirfd, 0)
if err != nil {
return err
}
@@ -861,12 +1062,16 @@ func (d whiteoutHandler) Mknod(path string, mode uint32, dev int) error {
dirfd = int(dir.Fd())
}
- return unix.Mknodat(dirfd, base, mode, dev)
+ if err := unix.Mknodat(dirfd, base, mode, dev); err != nil {
+ return fmt.Errorf("mknod %q: %w", path, err)
+ }
+
+ return nil
}
func checkChownErr(err error, name string, uid, gid int) error {
if errors.Is(err, syscall.EINVAL) {
- return errors.Wrapf(err, "potentially insufficient UIDs or GIDs available in user namespace (requested %d:%d for %s): Check /etc/subuid and /etc/subgid if configured locally", uid, gid, name)
+ return fmt.Errorf("potentially insufficient UIDs or GIDs available in user namespace (requested %d:%d for %s): Check /etc/subuid and /etc/subgid if configured locally: %w", uid, gid, name, err)
}
return err
}
@@ -961,7 +1166,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
dirfd, err := unix.Open(dest, unix.O_RDONLY|unix.O_PATH, 0)
if err != nil {
- return output, err
+ return output, fmt.Errorf("cannot open %q: %w", dest, err)
}
defer unix.Close(dirfd)
@@ -1021,7 +1226,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
return err
}
defer file.Close()
- if err := setFileAttrs(file, mode, &r, options); err != nil {
+ if err := setFileAttrs(dirfd, file, mode, &r, options, false); err != nil {
return err
}
return nil
@@ -1033,7 +1238,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
}
case tar.TypeDir:
- if err := safeMkdir(dirfd, mode, &r, options); err != nil {
+ if err := safeMkdir(dirfd, mode, r.Name, &r, options); err != nil {
return output, err
}
continue
@@ -1070,7 +1275,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
finalizeFile := func(dstFile *os.File) error {
if dstFile != nil {
defer dstFile.Close()
- if err := setFileAttrs(dstFile, mode, &r, options); err != nil {
+ if err := setFileAttrs(dirfd, dstFile, mode, &r, options, false); err != nil {
return err
}
}
diff --git a/vendor/github.com/containers/storage/types/options.go b/vendor/github.com/containers/storage/types/options.go
index 8a3858d9f..fe4274efd 100644
--- a/vendor/github.com/containers/storage/types/options.go
+++ b/vendor/github.com/containers/storage/types/options.go
@@ -42,6 +42,10 @@ func init() {
defaultStoreOptions.GraphDriverName = ""
if _, err := os.Stat(defaultOverrideConfigFile); err == nil {
+ // The DefaultConfigFile(rootless) function returns the path
+ // of the used storage.conf file, by returning defaultConfigFile
+ // If override exists containers/storage uses it by default.
+ defaultConfigFile = defaultOverrideConfigFile
ReloadConfigurationFileIfNeeded(defaultOverrideConfigFile, &defaultStoreOptions)
} else {
if !os.IsNotExist(err) {
diff --git a/vendor/github.com/jinzhu/copier/copier.go b/vendor/github.com/jinzhu/copier/copier.go
index 412ff5497..6d21da869 100644
--- a/vendor/github.com/jinzhu/copier/copier.go
+++ b/vendor/github.com/jinzhu/copier/copier.go
@@ -348,10 +348,15 @@ func deepFields(reflectType reflect.Type) []reflect.StructField {
for i := 0; i < reflectType.NumField(); i++ {
v := reflectType.Field(i)
- if v.Anonymous {
- fields = append(fields, deepFields(v.Type)...)
- } else {
- fields = append(fields, v)
+ // PkgPath is the package path that qualifies a lower case (unexported)
+ // field name. It is empty for upper case (exported) field names.
+ // See https://golang.org/ref/spec#Uniqueness_of_identifiers
+ if v.PkgPath == "" {
+ if v.Anonymous {
+ fields = append(fields, deepFields(v.Type)...)
+ } else {
+ fields = append(fields, v)
+ }
}
}
diff --git a/vendor/github.com/jinzhu/copier/go.mod b/vendor/github.com/jinzhu/copier/go.mod
index 531422dcb..309801e9b 100644
--- a/vendor/github.com/jinzhu/copier/go.mod
+++ b/vendor/github.com/jinzhu/copier/go.mod
@@ -1,3 +1,3 @@
module github.com/jinzhu/copier
-go 1.15
+go 1.13
diff --git a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
index 9fe803a5e..38a099162 100644
--- a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
+++ b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.4.3
+
+* Fix cases where `json.Number` didn't decode properly [GH-261]
+
## 1.4.2
* Custom name matchers to support any sort of casing, formatting, etc. for
diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go
index dcee0f2d6..6b81b0067 100644
--- a/vendor/github.com/mitchellh/mapstructure/mapstructure.go
+++ b/vendor/github.com/mitchellh/mapstructure/mapstructure.go
@@ -684,16 +684,12 @@ func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) e
}
case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
jn := data.(json.Number)
- i, err := jn.Int64()
+ i, err := strconv.ParseUint(string(jn), 0, 64)
if err != nil {
return fmt.Errorf(
"error decoding json.Number into %s: %s", name, err)
}
- if i < 0 && !d.config.WeaklyTypedInput {
- return fmt.Errorf("cannot parse '%s', %d overflows uint",
- name, i)
- }
- val.SetUint(uint64(i))
+ val.SetUint(i)
default:
return fmt.Errorf(
"'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go
index 4e6c4b236..82da6c6a8 100644
--- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go
+++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go
@@ -21,6 +21,9 @@ import "github.com/opencontainers/image-spec/specs-go"
type Index struct {
specs.Versioned
+ // MediaType specificies the type of this document data structure e.g. `application/vnd.oci.image.index.v1+json`
+ MediaType string `json:"mediaType,omitempty"`
+
// Manifests references platform specific manifests.
Manifests []Descriptor `json:"manifests"`
diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go
index 7ff32c40b..d72d15ce4 100644
--- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go
+++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go
@@ -20,6 +20,9 @@ import "github.com/opencontainers/image-spec/specs-go"
type Manifest struct {
specs.Versioned
+ // MediaType specificies the type of this document data structure e.g. `application/vnd.oci.image.manifest.v1+json`
+ MediaType string `json:"mediaType,omitempty"`
+
// Config references a configuration object for a container, by digest.
// The referenced configuration object is a JSON blob that the runtime uses to set up the container.
Config Descriptor `json:"config"`
diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/version.go b/vendor/github.com/opencontainers/image-spec/specs-go/version.go
index 58f1095ab..31f99cf64 100644
--- a/vendor/github.com/opencontainers/image-spec/specs-go/version.go
+++ b/vendor/github.com/opencontainers/image-spec/specs-go/version.go
@@ -22,7 +22,7 @@ const (
// VersionMinor is for functionality in a backwards-compatible manner
VersionMinor = 0
// VersionPatch is for backwards-compatible bug fixes
- VersionPatch = 1
+ VersionPatch = 2
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = "-dev"