libimage: push: ignore image platform

When pushing an image, make sure to ignore the platform of the image to
push exactly what the user wishes to.  Add a test to make sure we're not
regressing in the future.

To preserve previous behaviour with respect to attempting to push a
manifest list, move the platform check below resolving to a manifest
list.

Fixes: #containers/podman/issues/10344
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
Valentin Rothberg 2021-05-17 10:24:43 +02:00
parent 6fccae0c55
commit 724e7c92b5
3 changed files with 37 additions and 6 deletions

View File

@ -29,8 +29,10 @@ func (r *Runtime) Push(ctx context.Context, source, destination string, options
options = &PushOptions{}
}
// Look up the local image.
image, resolvedSource, err := r.LookupImage(source, nil)
// Look up the local image. Note that we need to ignore the platform
// and push what the user specified (containers/podman/issues/10344).
lookupOptions := &LookupImageOptions{IgnorePlatform: true}
image, resolvedSource, err := r.LookupImage(source, lookupOptions)
if err != nil {
return nil, err
}

View File

@ -66,3 +66,30 @@ func TestPush(t *testing.T) {
require.True(t, rmReports[i].Removed)
}
}
func TestPushOtherPlatform(t *testing.T) {
runtime, cleanup := testNewRuntime(t)
defer cleanup()
ctx := context.Background()
// Prefetch alpine.
pullOptions := &PullOptions{}
pullOptions.Writer = os.Stdout
pullOptions.Architecture = "arm64"
pulledImages, err := runtime.Pull(ctx, "docker.io/library/alpine:latest", config.PullPolicyAlways, pullOptions)
require.NoError(t, err)
require.Len(t, pulledImages, 1)
data, err := pulledImages[0].Inspect(ctx, false)
require.NoError(t, err)
require.Equal(t, "arm64", data.Architecture)
pushOptions := &PushOptions{}
pushOptions.Writer = os.Stdout
tmp, err := ioutil.TempFile("", "")
require.NoError(t, err)
tmp.Close()
defer os.Remove(tmp.Name())
_, err = runtime.Push(ctx, "docker.io/library/alpine:latest", "docker-archive:"+tmp.Name(), pushOptions)
require.NoError(t, err)
}

View File

@ -244,10 +244,7 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo
}
image := r.storageToImage(img, ref)
if options.IgnorePlatform {
logrus.Debugf("Found image %q as %q in local containers storage", name, candidate)
return image, nil
}
logrus.Debugf("Found image %q as %q in local containers storage", name, candidate)
// If we referenced a manifest list, we need to check whether we can
// find a matching instance in the local containers storage.
@ -256,6 +253,7 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo
return nil, err
}
if isManifestList {
logrus.Debugf("Candidate %q is a manifest list, looking up matching instance", candidate)
manifestList, err := image.ToManifestList()
if err != nil {
return nil, err
@ -270,6 +268,10 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo
}
}
if options.IgnorePlatform {
return image, nil
}
matches, err := imageReferenceMatchesContext(context.Background(), ref, &r.systemContext)
if err != nil {
return nil, err