Skip to content

Commit b5be41e

Browse files
cursoragentrgarcia
andcommitted
Fix: Resolve multi-arch tags to platform-specific digests
Co-authored-by: raf <raf@onkernel.com>
1 parent 58aba1f commit b5be41e

File tree

2 files changed

+54
-4
lines changed

2 files changed

+54
-4
lines changed

lib/images/oci.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,21 @@ func (c *ociClient) inspectManifest(ctx context.Context, imageRef string) (strin
8080

8181
// Use system authentication (reads from ~/.docker/config.json, etc.)
8282
// Default retry: only on network errors, max ~1.3s total
83-
descriptor, err := remote.Head(ref,
83+
// WithPlatform ensures we resolve multi-arch tags/digests to the
84+
// platform-specific manifest digest that pullToOCILayout will actually pull.
85+
img, err := remote.Image(ref,
8486
remote.WithContext(ctx),
85-
remote.WithAuthFromKeychain(authn.DefaultKeychain))
87+
remote.WithAuthFromKeychain(authn.DefaultKeychain),
88+
remote.WithPlatform(currentPlatform()))
8689
if err != nil {
87-
return "", fmt.Errorf("fetch manifest: %w", wrapRegistryError(err))
90+
return "", fmt.Errorf("fetch image manifest: %w", wrapRegistryError(err))
8891
}
8992

90-
return descriptor.Digest.String(), nil
93+
d, err := img.Digest()
94+
if err != nil {
95+
return "", fmt.Errorf("compute image digest: %w", err)
96+
}
97+
return d.String(), nil
9198
}
9299

93100
// pullResult contains the metadata and digest from pulling an image

lib/images/oci_inspect_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package images
2+
3+
import (
4+
"context"
5+
"testing"
6+
"time"
7+
8+
"github.com/google/go-containerregistry/pkg/authn"
9+
"github.com/google/go-containerregistry/pkg/name"
10+
"github.com/google/go-containerregistry/pkg/v1/remote"
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
func TestInspectManifestReturnsPlatformSpecificDigestForMultiArch(t *testing.T) {
15+
// alpine:latest is a multi-arch image on Docker Hub; we should resolve the
16+
// digest of the platform-specific manifest that we will actually pull.
17+
const imageRef = "docker.io/library/alpine:latest"
18+
19+
client, err := newOCIClient(t.TempDir())
20+
require.NoError(t, err)
21+
22+
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
23+
defer cancel()
24+
25+
gotDigest, err := client.inspectManifest(ctx, imageRef)
26+
require.NoError(t, err)
27+
require.NotEmpty(t, gotDigest)
28+
29+
ref, err := name.ParseReference(imageRef)
30+
require.NoError(t, err)
31+
32+
img, err := remote.Image(ref,
33+
remote.WithContext(ctx),
34+
remote.WithAuthFromKeychain(authn.DefaultKeychain),
35+
remote.WithPlatform(currentPlatform()))
36+
require.NoError(t, err)
37+
38+
want, err := img.Digest()
39+
require.NoError(t, err)
40+
41+
require.Equal(t, want.String(), gotDigest)
42+
}
43+

0 commit comments

Comments
 (0)