pull: custom platform: do not use local image name

Do not use the name of the locally resolved image when pulling an image
with a custom platform.  As we recently re-discovered [1], many
multi-arch images in the wild do not adhere to the OCI image spec and
either declare custom or simply wrong platforms (arch, os, variant).

To address such wrong images, we enforce the pull-always policy whenever
a custom arch, os or variant is specified.  We have to do that since we
cannot reliably perform platform matches to any image we would find in
the local containers storage.

To complete the fix, we need to ignore any local image and not use the
locally resolved name which we usually have to do (see [2]).

Let's assume we have a local image "localhost/foo" (arch=amd64).  If we
perform a `pull --arch=arm64`, we would not attempt to be pulling
`localhost/foo` but use the ordinary short-name resolution and look for
a matching alias or walk the unqualified-search registries.

In other words: short-name resolution of multi-arch images is prone to
errors but we should continue supporting images in the wild.

[1] containers/podman/issues/10682
[2] containers/buildah/issues/2904

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
Valentin Rothberg 2021-06-27 13:05:08 +02:00
parent b40eec5f98
commit 37f6e92ece
1 changed files with 25 additions and 14 deletions

View File

@ -384,6 +384,9 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str
}
}
customPlatform := false
if len(options.Architecture)+len(options.OS)+len(options.Variant) > 0 {
customPlatform = true
// 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
@ -393,10 +396,11 @@ 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 && len(options.Architecture)+len(options.OS)+len(options.Variant) > 0 {
if pullPolicy != config.PullPolicyAlways {
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 {
@ -422,8 +426,15 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str
}
// If we found a local image, we should use it's locally resolved name
// (see containers/buildah #2904).
if localImage != nil {
// (see containers/buildah/issues/2904). An exception is if a custom
// platform is specified (e.g., `--arch=arm64`). In that case, we need
// to pessimistically pull the image since some images declare wrong
// platforms making platform checks absolutely unreliable (see
// containers/podman/issues/10682).
//
// In other words: multi-arch support can only be as good as the images
// in the wild.
if localImage != nil && !customPlatform {
if imageName != resolvedImageName {
logrus.Debugf("Image %s resolved to local image %s which will be used for pulling", imageName, resolvedImageName)
}