Skip to content

Commit

Permalink
pull: custom platform: do not use local image name
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
vrothberg committed Jun 27, 2021
1 parent f393ddc commit f55ab69
Showing 1 changed file with 25 additions and 14 deletions.
39 changes: 25 additions & 14 deletions libimage/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,18 +374,22 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str
}
}

// 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
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
// 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 {
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 {
Expand All @@ -412,8 +416,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)
}
Expand Down

0 comments on commit f55ab69

Please sign in to comment.