summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValentin Rothberg <rothberg@redhat.com>2021-06-21 10:51:51 +0200
committerValentin Rothberg <rothberg@redhat.com>2021-06-23 15:42:13 +0200
commit5fc622f945de46db85c8cc0284f935bac1929e3a (patch)
tree9fe97bbaaafbe3f3804a422a4a53edaefde636b3
parentd3afc6b3b6d6ba1d900b74d24affb132f38622d3 (diff)
downloadpodman-5fc622f945de46db85c8cc0284f935bac1929e3a.tar.gz
podman-5fc622f945de46db85c8cc0284f935bac1929e3a.tar.bz2
podman-5fc622f945de46db85c8cc0284f935bac1929e3a.zip
create: support images with invalid platform
Much to my regret, there is a number of images in the wild with invalid platforms breaking the platform checks in libimage that want to make sure that a local image is matching the expected platform. Imagine a `podman run --arch=arm64 fedora` with a local amd64 fedora image. We really shouldn't use the local one in this case and pull down the arm64 one. The strict platform checks in libimage in combination with invalid platforms in images surfaced in Podman being able to pull an image but failing to look it up in subsequent presence checks. A `podman run` would hence pull such an image but fail to create the container. Support images with invalid platforms by vendoring the latest HEAD from containers/common. Also remove the partially implemented pull-policy logic from Podman and let libimage handle that entirely. However, whenever --arch, --os or --platform are specified, the pull policy will be forced to "newer". This way, we pessimistically assume that the local image has an invalid platform and we reach out to the registry. If there's a newer image (i.e., one with a different digest), we'll pull it down. Please note that most of the logic has either already been implemented in libimage or been moved down which allows for removing some clutter from Podman. [NO TESTS NEEDED] since c/common has new tests. Podman can rely on the existing tests. Fixes: #10648 Fixes: #10682 Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
-rw-r--r--cmd/podman/containers/create.go58
-rw-r--r--go.mod2
-rw-r--r--go.sum5
-rw-r--r--pkg/api/handlers/libpod/images_pull.go24
-rw-r--r--pkg/api/server/register_images.go4
-rw-r--r--pkg/bindings/images/pull.go10
-rw-r--r--pkg/bindings/images/types.go3
-rw-r--r--pkg/bindings/images/types_pull_options.go16
-rw-r--r--pkg/domain/infra/tunnel/images.go2
-rw-r--r--pkg/errorhandling/errorhandling.go9
-rw-r--r--pkg/specgen/generate/container.go3
-rw-r--r--pkg/specgen/generate/container_create.go3
-rw-r--r--test/system/255-auto-update.bats2
-rw-r--r--vendor/github.com/containers/common/libimage/image.go18
-rw-r--r--vendor/github.com/containers/common/libimage/pull.go48
-rw-r--r--vendor/github.com/containers/common/libimage/runtime.go56
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go2
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/default_linux.go42
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/seccomp.json50
-rw-r--r--vendor/github.com/containers/common/version/version.go2
-rw-r--r--vendor/modules.txt2
21 files changed, 196 insertions, 165 deletions
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 68a17abd0..2144a6e10 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -8,7 +8,6 @@ import (
"strings"
"github.com/containers/common/pkg/config"
- storageTransport "github.com/containers/image/v5/storage"
"github.com/containers/image/v5/transports/alltransports"
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
@@ -16,9 +15,7 @@ import (
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util"
- "github.com/containers/storage"
"github.com/pkg/errors"
- "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@@ -236,30 +233,12 @@ func createInit(c *cobra.Command) error {
return nil
}
-// TODO: we should let the backend take care of the pull policy (which it
-// does!). The code below is at risk of causing regression and code divergence.
func pullImage(imageName string) (string, error) {
pullPolicy, err := config.ValidatePullPolicy(cliVals.Pull)
if err != nil {
return "", err
}
- // Check if the image is missing and hence if we need to pull it.
- imageMissing := true
- imageRef, err := alltransports.ParseImageName(imageName)
- switch {
- case err != nil:
- // Assume we specified a local image without the explicit storage transport.
- fallthrough
-
- case imageRef.Transport().Name() == storageTransport.Transport.Name():
- br, err := registry.ImageEngine().Exists(registry.GetContext(), imageName)
- if err != nil {
- return "", err
- }
- imageMissing = !br.Value
- }
-
if cliVals.Platform != "" || cliVals.Arch != "" || cliVals.OS != "" {
if cliVals.Platform != "" {
if cliVals.Arch != "" || cliVals.OS != "" {
@@ -271,31 +250,28 @@ func pullImage(imageName string) (string, error) {
cliVals.Arch = split[1]
}
}
+ }
- if pullPolicy != config.PullPolicyAlways {
- logrus.Info("--platform --arch and --os causes the pull policy to be \"always\"")
- pullPolicy = config.PullPolicyAlways
- }
+ pullReport, pullErr := registry.ImageEngine().Pull(registry.GetContext(), imageName, entities.ImagePullOptions{
+ Authfile: cliVals.Authfile,
+ Quiet: cliVals.Quiet,
+ Arch: cliVals.Arch,
+ OS: cliVals.OS,
+ Variant: cliVals.Variant,
+ SignaturePolicy: cliVals.SignaturePolicy,
+ PullPolicy: pullPolicy,
+ })
+ if pullErr != nil {
+ return "", pullErr
}
- if imageMissing || pullPolicy == config.PullPolicyAlways {
- if pullPolicy == config.PullPolicyNever {
- return "", errors.Wrap(storage.ErrImageUnknown, imageName)
- }
- pullReport, pullErr := registry.ImageEngine().Pull(registry.GetContext(), imageName, entities.ImagePullOptions{
- Authfile: cliVals.Authfile,
- Quiet: cliVals.Quiet,
- Arch: cliVals.Arch,
- OS: cliVals.OS,
- Variant: cliVals.Variant,
- SignaturePolicy: cliVals.SignaturePolicy,
- PullPolicy: pullPolicy,
- })
- if pullErr != nil {
- return "", pullErr
- }
+ // Return the input name such that the image resolves to correct
+ // repo/tag in the backend (see #8082). Unless we're referring to
+ // the image via a transport.
+ if _, err := alltransports.ParseImageName(imageName); err == nil {
imageName = pullReport.Images[0]
}
+
return imageName, nil
}
diff --git a/go.mod b/go.mod
index 46a72c567..e8ebb88fe 100644
--- a/go.mod
+++ b/go.mod
@@ -12,7 +12,7 @@ require (
github.com/containernetworking/cni v0.8.1
github.com/containernetworking/plugins v0.9.1
github.com/containers/buildah v1.21.1
- github.com/containers/common v0.40.1-0.20210617134614-c6578d76fb0d
+ github.com/containers/common v0.40.2-0.20210623133759-d13a31743aec
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.13.2
github.com/containers/ocicrypt v1.1.1
diff --git a/go.sum b/go.sum
index 33dab408c..e2a83a95f 100644
--- a/go.sum
+++ b/go.sum
@@ -221,12 +221,11 @@ github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRD
github.com/containers/buildah v1.21.1 h1:e9LmTCUKUBLg72v5DnIOT/wc8ffkfB7LbpQBywLZo20=
github.com/containers/buildah v1.21.1/go.mod h1:yPdlpVd93T+i91yGxrJbW1YOWrqN64j5ZhHOZmHUejs=
github.com/containers/common v0.38.4/go.mod h1:egfpX/Y3+19Dz4Wa1eRZDdgzoEOeneieF9CQppKzLBg=
-github.com/containers/common v0.40.1-0.20210617134614-c6578d76fb0d h1:PaS/t2XcyxEDOr685T+3HPMyMqN99UPcj6I92nqIDH8=
-github.com/containers/common v0.40.1-0.20210617134614-c6578d76fb0d/go.mod h1:+zxauZzkurY5tbQGDxrCV6rF694RX1olXyYRVJHrzWo=
+github.com/containers/common v0.40.2-0.20210623133759-d13a31743aec h1:ZcteA2klZSZAZgVonwJAqezF6hdO9SMKUy49ZHXZd38=
+github.com/containers/common v0.40.2-0.20210623133759-d13a31743aec/go.mod h1:J23CfuhN1fAg85q5HxS6SKYhKbGqmqieKQqoHaQbEI8=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.12.0/go.mod h1:VasTuHmOw+uD0oHCfApQcMO2+36SfyncoSahU7513Xs=
-github.com/containers/image/v5 v5.13.2-0.20210617132750-db0df5e0cf5e/go.mod h1:GkWursKDlDcUIT7L7vZf70tADvZCk/Ga0wgS0MuF0ag=
github.com/containers/image/v5 v5.13.2 h1:AgYunV/9d2fRkrmo23wH2MkqeHolFd6oQCkK+1PpuFA=
github.com/containers/image/v5 v5.13.2/go.mod h1:GkWursKDlDcUIT7L7vZf70tADvZCk/Ga0wgS0MuF0ag=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go
index e88b53a4b..04b415638 100644
--- a/pkg/api/handlers/libpod/images_pull.go
+++ b/pkg/api/handlers/libpod/images_pull.go
@@ -26,14 +26,16 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- Reference string `schema:"reference"`
- OS string `schema:"OS"`
- Arch string `schema:"Arch"`
- Variant string `schema:"Variant"`
- TLSVerify bool `schema:"tlsVerify"`
- AllTags bool `schema:"allTags"`
+ Reference string `schema:"reference"`
+ OS string `schema:"OS"`
+ Arch string `schema:"Arch"`
+ Variant string `schema:"Variant"`
+ TLSVerify bool `schema:"tlsVerify"`
+ AllTags bool `schema:"allTags"`
+ PullPolicy string `schema:"policy"`
}{
- TLSVerify: true,
+ TLSVerify: true,
+ PullPolicy: "always",
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
@@ -83,12 +85,18 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
pullOptions.Writer = writer
+ pullPolicy, err := config.ParsePullPolicy(query.PullPolicy)
+ if err != nil {
+ utils.Error(w, "failed to parse pull policy", http.StatusBadRequest, err)
+ return
+ }
+
var pulledImages []*libimage.Image
var pullError error
runCtx, cancel := context.WithCancel(r.Context())
go func() {
defer cancel()
- pulledImages, pullError = runtime.LibimageRuntime().Pull(runCtx, query.Reference, config.PullPolicyAlways, pullOptions)
+ pulledImages, pullError = runtime.LibimageRuntime().Pull(runCtx, query.Reference, pullPolicy, pullOptions)
}()
flush := func() {
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index d075cd098..3410c53cd 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -974,6 +974,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// description: Pull image for the specified variant.
// type: string
// - in: query
+ // name: policy
+ // description: Pull policy, "always" (default), "missing", "newer", "never".
+ // type: string
+ // - in: query
// name: tlsVerify
// description: Require TLS verification.
// type: boolean
diff --git a/pkg/bindings/images/pull.go b/pkg/bindings/images/pull.go
index 9780c3bff..7dfe9560c 100644
--- a/pkg/bindings/images/pull.go
+++ b/pkg/bindings/images/pull.go
@@ -13,7 +13,7 @@ import (
"github.com/containers/podman/v3/pkg/auth"
"github.com/containers/podman/v3/pkg/bindings"
"github.com/containers/podman/v3/pkg/domain/entities"
- "github.com/hashicorp/go-multierror"
+ "github.com/containers/podman/v3/pkg/errorhandling"
"github.com/pkg/errors"
)
@@ -65,7 +65,7 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string,
dec := json.NewDecoder(response.Body)
var images []string
- var mErr error
+ var pullErrors []error
for {
var report entities.ImagePullReport
if err := dec.Decode(&report); err != nil {
@@ -77,7 +77,7 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string,
select {
case <-response.Request.Context().Done():
- return images, mErr
+ break
default:
// non-blocking select
}
@@ -86,7 +86,7 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string,
case report.Stream != "":
fmt.Fprint(stderr, report.Stream)
case report.Error != "":
- mErr = multierror.Append(mErr, errors.New(report.Error))
+ pullErrors = append(pullErrors, errors.New(report.Error))
case len(report.Images) > 0:
images = report.Images
case report.ID != "":
@@ -94,5 +94,5 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string,
return images, errors.Errorf("failed to parse pull results stream, unexpected input: %v", report)
}
}
- return images, mErr
+ return images, errorhandling.JoinErrors(pullErrors)
}
diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go
index 1f3e46729..0aa75a81e 100644
--- a/pkg/bindings/images/types.go
+++ b/pkg/bindings/images/types.go
@@ -147,6 +147,9 @@ type PullOptions struct {
// OS will overwrite the local operating system (OS) for image
// pulls.
OS *string
+ // Policy is the pull policy. Supported values are "missing", "never",
+ // "newer", "always". An empty string defaults to "always".
+ Policy *string
// Password for authenticating against the registry.
Password *string
// Quiet can be specified to suppress pull progress when pulling. Ignored
diff --git a/pkg/bindings/images/types_pull_options.go b/pkg/bindings/images/types_pull_options.go
index 0611c4447..8fcf499eb 100644
--- a/pkg/bindings/images/types_pull_options.go
+++ b/pkg/bindings/images/types_pull_options.go
@@ -84,6 +84,22 @@ func (o *PullOptions) GetOS() string {
return *o.OS
}
+// WithPolicy
+func (o *PullOptions) WithPolicy(value string) *PullOptions {
+ v := &value
+ o.Policy = v
+ return o
+}
+
+// GetPolicy
+func (o *PullOptions) GetPolicy() string {
+ var policy string
+ if o.Policy == nil {
+ return policy
+ }
+ return *o.Policy
+}
+
// WithPassword
func (o *PullOptions) WithPassword(value string) *PullOptions {
v := &value
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 3fd9a755d..42027a2dc 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -107,7 +107,7 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, opts entities.
options := new(images.PullOptions)
options.WithAllTags(opts.AllTags).WithAuthfile(opts.Authfile).WithArch(opts.Arch).WithOS(opts.OS)
options.WithVariant(opts.Variant).WithPassword(opts.Password)
- options.WithQuiet(opts.Quiet).WithUsername(opts.Username)
+ options.WithQuiet(opts.Quiet).WithUsername(opts.Username).WithPolicy(opts.PullPolicy.String())
if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
if s == types.OptionalBoolTrue {
options.WithSkipTLSVerify(true)
diff --git a/pkg/errorhandling/errorhandling.go b/pkg/errorhandling/errorhandling.go
index 9b1740006..6adbc9f34 100644
--- a/pkg/errorhandling/errorhandling.go
+++ b/pkg/errorhandling/errorhandling.go
@@ -15,6 +15,12 @@ func JoinErrors(errs []error) error {
return nil
}
+ // If there's just one error, return it. This prevents the "%d errors
+ // occurred:" header plus list from the multierror package.
+ if len(errs) == 1 {
+ return errs[0]
+ }
+
// `multierror` appends new lines which we need to remove to prevent
// blank lines when printing the error.
var multiE *multierror.Error
@@ -24,9 +30,6 @@ func JoinErrors(errs []error) error {
if finalErr == nil {
return finalErr
}
- if len(multiE.WrappedErrors()) == 1 && logrus.IsLevelEnabled(logrus.TraceLevel) {
- return multiE.WrappedErrors()[0]
- }
return errors.New(strings.TrimSpace(finalErr.Error()))
}
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index d00e51e82..e7276892d 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -24,7 +24,8 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
var inspectData *libimage.ImageData
var err error
if s.Image != "" {
- newImage, _, err = r.LibimageRuntime().LookupImage(s.Image, nil)
+ lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true}
+ newImage, _, err = r.LibimageRuntime().LookupImage(s.Image, lookupOptions)
if err != nil {
return nil, err
}
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index a0f5cc7e6..087ff59df 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -92,7 +92,8 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
options = append(options, libpod.WithRootFS(s.Rootfs))
} else {
var resolvedImageName string
- newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, nil)
+ lookupOptions := &libimage.LookupImageOptions{IgnorePlatform: true}
+ newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, lookupOptions)
if err != nil {
return nil, err
}
diff --git a/test/system/255-auto-update.bats b/test/system/255-auto-update.bats
index 9bfb44791..3713243d5 100644
--- a/test/system/255-auto-update.bats
+++ b/test/system/255-auto-update.bats
@@ -194,7 +194,7 @@ function _confirm_update() {
run_podman 125 auto-update
update_log=$output
is "$update_log" ".*invalid auto-update policy.*" "invalid policy setup"
- is "$update_log" ".*1 error occurred.*" "invalid policy setup"
+ is "$update_log" ".*Error: invalid auto-update policy.*" "invalid policy setup"
local n_updated=$(grep -c 'Trying to pull' <<<"$update_log")
is "$n_updated" "2" "Number of images updated from registry."
diff --git a/vendor/github.com/containers/common/libimage/image.go b/vendor/github.com/containers/common/libimage/image.go
index 3bcdbabec..f1272f507 100644
--- a/vendor/github.com/containers/common/libimage/image.go
+++ b/vendor/github.com/containers/common/libimage/image.go
@@ -61,6 +61,24 @@ func (i *Image) reload() error {
return nil
}
+// isCorrupted returns an error if the image may be corrupted.
+func (i *Image) isCorrupted(name string) error {
+ // If it's a manifest list, we're good for now.
+ if _, err := i.getManifestList(); err == nil {
+ return nil
+ }
+
+ ref, err := i.StorageReference()
+ if err != nil {
+ return err
+ }
+
+ if _, err := ref.NewImage(context.Background(), nil); err != nil {
+ return errors.Errorf("Image %s exists in local storage but may be corrupted: %v", name, err)
+ }
+ return nil
+}
+
// Names returns associated names with the image which may be a mix of tags and
// digests.
func (i *Image) Names() []string {
diff --git a/vendor/github.com/containers/common/libimage/pull.go b/vendor/github.com/containers/common/libimage/pull.go
index 0271f0051..0a5e49fd2 100644
--- a/vendor/github.com/containers/common/libimage/pull.go
+++ b/vendor/github.com/containers/common/libimage/pull.go
@@ -105,6 +105,20 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP
r.writeEvent(&Event{ID: "", Name: name, Time: time.Now(), Type: EventTypeImagePull})
}
+ // Some callers may set the platform via the system context at creation
+ // time of the runtime. We need this information to decide whether we
+ // need to enforce pulling from a registry (see
+ // containers/podman/issues/10682).
+ if options.Architecture == "" {
+ options.Architecture = r.systemContext.ArchitectureChoice
+ }
+ if options.OS == "" {
+ options.OS = r.systemContext.OSChoice
+ }
+ if options.Variant == "" {
+ options.Variant = r.systemContext.VariantChoice
+ }
+
var (
pulledImages []string
pullError error
@@ -333,7 +347,7 @@ func (r *Runtime) copyFromRegistry(ctx context.Context, ref types.ImageReference
// from a registry. On successful pull it returns the used fully-qualified
// name that can later be used to look up the image in the local containers
// storage.
-func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName string, pullPolicy config.PullPolicy, options *PullOptions) ([]string, error) {
+func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName string, pullPolicy config.PullPolicy, options *PullOptions) ([]string, error) { //nolint:gocyclo
// Sanity check.
if err := pullPolicy.Validate(); err != nil {
return nil, err
@@ -349,11 +363,41 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str
// resolved name for pulling. Assume we're doing a `pull foo`.
// If there's already a local image "localhost/foo", then we should
// attempt pulling that instead of doing the full short-name dance.
- localImage, resolvedImageName, err = r.LookupImage(imageName, nil)
+ lookupOptions := &LookupImageOptions{
+ // NOTE: we must ignore the platform of a local image when
+ // doing lookups. Some images set an incorrect or even invalid
+ // platform (see containers/podman/issues/10682). Doing the
+ // lookup while ignoring the platform checks prevents
+ // redundantly downloading the same image.
+ IgnorePlatform: true,
+ }
+ localImage, resolvedImageName, err = r.LookupImage(imageName, lookupOptions)
if err != nil && errors.Cause(err) != storage.ErrImageUnknown {
logrus.Errorf("Looking up %s in local storage: %v", imageName, err)
}
+ // If the local image is corrupted, we need to repull it.
+ if localImage != nil {
+ if err := localImage.isCorrupted(imageName); err != nil {
+ logrus.Error(err)
+ localImage = nil
+ }
+ }
+
+ // Unless the pull policy is "always", we must pessimistically assume
+ // that the local image has an invalid architecture (see
+ // containers/podman/issues/10682). Hence, whenever the user requests
+ // a custom platform, set the pull policy to "always" to make sure
+ // we're pulling down the image.
+ //
+ // 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 && len(options.Architecture)+len(options.OS)+len(options.Variant) > 0 {
+ logrus.Debugf("Enforcing pull policy to %q to support custom platform (arch: %q, os: %q, variant: %q)", "always", options.Architecture, options.OS, options.Variant)
+ pullPolicy = config.PullPolicyAlways
+ }
+
if pullPolicy == config.PullPolicyNever {
if localImage != nil {
logrus.Debugf("Pull policy %q but no local image has been found for %s", pullPolicy, imageName)
diff --git a/vendor/github.com/containers/common/libimage/runtime.go b/vendor/github.com/containers/common/libimage/runtime.go
index efa182544..3cbd3dcf4 100644
--- a/vendor/github.com/containers/common/libimage/runtime.go
+++ b/vendor/github.com/containers/common/libimage/runtime.go
@@ -144,9 +144,8 @@ func (r *Runtime) Exists(name string) (bool, error) {
if image == nil {
return false, nil
}
- // Inspect the image to make sure if it's corrupted or not.
- if _, err := image.Inspect(context.Background(), false); err != nil {
- logrus.Errorf("Image %s exists in local storage but may be corrupted: %v", name, err)
+ if err := image.isCorrupted(name); err != nil {
+ logrus.Error(err)
return false, nil
}
return true, nil
@@ -159,6 +158,13 @@ type LookupImageOptions struct {
// the platform does not matter, for instance, for image removal.
IgnorePlatform bool
+ // Lookup an image matching the specified architecture.
+ Architecture string
+ // Lookup an image matching the specified OS.
+ OS string
+ // Lookup an image matching the specified variant.
+ Variant string
+
// 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
@@ -210,6 +216,25 @@ func (r *Runtime) LookupImage(name string, options *LookupImageOptions) (*Image,
name = strings.TrimPrefix(name, "sha256:")
}
+ // Set the platform for matching local images.
+ if !options.IgnorePlatform {
+ if options.Architecture == "" {
+ options.Architecture = r.systemContext.ArchitectureChoice
+ }
+ if options.Architecture == "" {
+ options.Architecture = runtime.GOARCH
+ }
+ if options.OS == "" {
+ options.OS = r.systemContext.OSChoice
+ }
+ if options.OS == "" {
+ options.OS = runtime.GOOS
+ }
+ if options.Variant == "" {
+ options.Variant = r.systemContext.VariantChoice
+ }
+ }
+
// First, check if we have an exact match in the storage. Maybe an ID
// or a fully-qualified image name.
img, err := r.lookupImageInLocalStorage(name, name, options)
@@ -295,7 +320,7 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo
if err != nil {
return nil, err
}
- instance, err := manifestList.LookupInstance(context.Background(), "", "", "")
+ instance, err := manifestList.LookupInstance(context.Background(), options.Architecture, options.OS, options.Variant)
if err != nil {
// NOTE: If we are not looking for a specific platform
// and already found the manifest list, then return it
@@ -316,7 +341,7 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo
return image, nil
}
- matches, err := imageReferenceMatchesContext(context.Background(), ref, &r.systemContext)
+ matches, err := r.imageReferenceMatchesContext(ref, options)
if err != nil {
return nil, err
}
@@ -428,12 +453,13 @@ func (r *Runtime) ResolveName(name string) (string, error) {
}
// imageReferenceMatchesContext return true if the specified reference matches
-// the platform (os, arch, variant) as specified by the system context.
-func imageReferenceMatchesContext(ctx context.Context, ref types.ImageReference, sys *types.SystemContext) (bool, error) {
- if sys == nil {
+// the platform (os, arch, variant) as specified by the lookup options.
+func (r *Runtime) imageReferenceMatchesContext(ref types.ImageReference, options *LookupImageOptions) (bool, error) {
+ if options.IgnorePlatform {
return true, nil
}
- img, err := ref.NewImage(ctx, sys)
+ ctx := context.Background()
+ img, err := ref.NewImage(ctx, &r.systemContext)
if err != nil {
return false, err
}
@@ -442,16 +468,8 @@ func imageReferenceMatchesContext(ctx context.Context, ref types.ImageReference,
if err != nil {
return false, err
}
- osChoice := sys.OSChoice
- if osChoice == "" {
- osChoice = runtime.GOOS
- }
- arch := sys.ArchitectureChoice
- if arch == "" {
- arch = runtime.GOARCH
- }
- if osChoice == data.Os && arch == data.Architecture {
- if sys.VariantChoice == "" || sys.VariantChoice == data.Variant {
+ if options.OS == data.Os && options.Architecture == data.Architecture {
+ if options.Variant == "" || options.Variant == data.Variant {
return true, nil
}
}
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
index 0d23d6ac6..af6efbbf2 100644
--- a/vendor/github.com/containers/common/pkg/config/config.go
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -1053,7 +1053,7 @@ func (c *Config) Write() error {
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
return err
}
- configFile, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0600)
+ configFile, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644)
if err != nil {
return err
}
diff --git a/vendor/github.com/containers/common/pkg/seccomp/default_linux.go b/vendor/github.com/containers/common/pkg/seccomp/default_linux.go
index edb1294d6..725e0bfc7 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/default_linux.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/default_linux.go
@@ -51,14 +51,9 @@ func DefaultProfile() *Seccomp {
{
Names: []string{
"bdflush",
- "clone3",
"io_pgetevents",
- "io_uring_enter",
- "io_uring_register",
- "io_uring_setup",
"kexec_file_load",
"kexec_load",
- "membarrier",
"migrate_pages",
"move_pages",
"nfsservctl",
@@ -71,10 +66,6 @@ func DefaultProfile() *Seccomp {
"pciconfig_iobase",
"pciconfig_read",
"pciconfig_write",
- "pkey_alloc",
- "pkey_free",
- "pkey_mprotect",
- "rseq",
"sgetmask",
"ssetmask",
"swapcontext",
@@ -118,6 +109,7 @@ func DefaultProfile() *Seccomp {
"clock_nanosleep",
"clock_nanosleep_time64",
"clone",
+ "clone3",
"close",
"close_range",
"connect",
@@ -191,6 +183,7 @@ func DefaultProfile() *Seccomp {
"getgroups",
"getgroups32",
"getitimer",
+ "get_mempolicy",
"getpeername",
"getpgid",
"getpgrp",
@@ -241,6 +234,7 @@ func DefaultProfile() *Seccomp {
"lstat",
"lstat64",
"madvise",
+ "mbind",
"memfd_create",
"mincore",
"mkdir",
@@ -286,6 +280,9 @@ func DefaultProfile() *Seccomp {
"pipe",
"pipe2",
"pivot_root",
+ "pkey_alloc",
+ "pkey_free",
+ "pkey_mprotect",
"poll",
"ppoll",
"ppoll_time64",
@@ -318,6 +315,7 @@ func DefaultProfile() *Seccomp {
"renameat2",
"restart_syscall",
"rmdir",
+ "rseq",
"rt_sigaction",
"rt_sigpending",
"rt_sigprocmask",
@@ -354,6 +352,7 @@ func DefaultProfile() *Seccomp {
"sendmsg",
"sendto",
"setns",
+ "set_mempolicy",
"set_robust_list",
"set_thread_area",
"set_tid_address",
@@ -665,31 +664,6 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
- "get_mempolicy",
- "mbind",
- "set_mempolicy",
- },
- Action: ActAllow,
- Args: []*Arg{},
- Includes: Filter{
- Caps: []string{"CAP_SYS_NICE"},
- },
- },
- {
- Names: []string{
- "get_mempolicy",
- "mbind",
- "set_mempolicy",
- },
- Action: ActErrno,
- ErrnoRet: &eperm,
- Args: []*Arg{},
- Excludes: Filter{
- Caps: []string{"CAP_SYS_NICE"},
- },
- },
- {
- Names: []string{
"acct",
},
Action: ActAllow,
diff --git a/vendor/github.com/containers/common/pkg/seccomp/seccomp.json b/vendor/github.com/containers/common/pkg/seccomp/seccomp.json
index 885240e50..eeb41d5d8 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/seccomp.json
+++ b/vendor/github.com/containers/common/pkg/seccomp/seccomp.json
@@ -54,14 +54,9 @@
{
"names": [
"bdflush",
- "clone3",
"io_pgetevents",
- "io_uring_enter",
- "io_uring_register",
- "io_uring_setup",
"kexec_file_load",
"kexec_load",
- "membarrier",
"migrate_pages",
"move_pages",
"nfsservctl",
@@ -74,10 +69,6 @@
"pciconfig_iobase",
"pciconfig_read",
"pciconfig_write",
- "pkey_alloc",
- "pkey_free",
- "pkey_mprotect",
- "rseq",
"sgetmask",
"ssetmask",
"swapcontext",
@@ -124,6 +115,7 @@
"clock_nanosleep",
"clock_nanosleep_time64",
"clone",
+ "clone3",
"close",
"close_range",
"connect",
@@ -197,6 +189,7 @@
"getgroups",
"getgroups32",
"getitimer",
+ "get_mempolicy",
"getpeername",
"getpgid",
"getpgrp",
@@ -247,6 +240,7 @@
"lstat",
"lstat64",
"madvise",
+ "mbind",
"memfd_create",
"mincore",
"mkdir",
@@ -292,6 +286,9 @@
"pipe",
"pipe2",
"pivot_root",
+ "pkey_alloc",
+ "pkey_free",
+ "pkey_mprotect",
"poll",
"ppoll",
"ppoll_time64",
@@ -324,6 +321,7 @@
"renameat2",
"restart_syscall",
"rmdir",
+ "rseq",
"rt_sigaction",
"rt_sigpending",
"rt_sigprocmask",
@@ -360,6 +358,7 @@
"sendmsg",
"sendto",
"setns",
+ "set_mempolicy",
"set_robust_list",
"set_thread_area",
"set_tid_address",
@@ -761,39 +760,6 @@
},
{
"names": [
- "get_mempolicy",
- "mbind",
- "set_mempolicy"
- ],
- "action": "SCMP_ACT_ALLOW",
- "args": [],
- "comment": "",
- "includes": {
- "caps": [
- "CAP_SYS_NICE"
- ]
- },
- "excludes": {}
- },
- {
- "names": [
- "get_mempolicy",
- "mbind",
- "set_mempolicy"
- ],
- "action": "SCMP_ACT_ERRNO",
- "args": [],
- "comment": "",
- "includes": {},
- "excludes": {
- "caps": [
- "CAP_SYS_NICE"
- ]
- },
- "errnoRet": 1
- },
- {
- "names": [
"acct"
],
"action": "SCMP_ACT_ALLOW",
diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go
index 6c899987a..8907e21ab 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.40.1-dev"
+const Version = "0.40.2-dev"
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 282b6ba66..c4cfc0d83 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -93,7 +93,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.40.1-0.20210617134614-c6578d76fb0d
+# github.com/containers/common v0.40.2-0.20210623133759-d13a31743aec
github.com/containers/common/libimage
github.com/containers/common/libimage/manifests
github.com/containers/common/pkg/apparmor