Skip to content

Commit e3edee0

Browse files
authored
Take runtime.GOARCH into account for list manifests (#1237)
1 parent a33a67e commit e3edee0

File tree

1 file changed

+31
-14
lines changed

1 file changed

+31
-14
lines changed

pkg/scan/scan.go

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"crypto/sha256"
55
"fmt"
66
"io"
7+
"runtime"
78

89
imageManifest "github.com/containers/image/v5/manifest"
910
"github.com/docker/distribution"
@@ -153,6 +154,34 @@ func renderDigest(manifest payloadGetter) (digest.Digest, error) {
153154
return dig, nil
154155
}
155156

157+
func handleManifestLists(reg types.Registry, remote, ref string, manifests []manifestlist.ManifestDescriptor) (digest.Digest, []string, error) {
158+
if len(manifests) == 0 {
159+
return "", nil, errors.Errorf("no valid manifests found for %s:%s", remote, ref)
160+
}
161+
if len(manifests) == 1 {
162+
return handleManifest(reg, manifests[0].MediaType, remote, manifests[0].Digest.String())
163+
}
164+
var amdManifest manifestlist.ManifestDescriptor
165+
var foundAMD bool
166+
for _, m := range manifests {
167+
if m.Platform.OS != "linux" {
168+
continue
169+
}
170+
// Matching platform for GOARCH takes priority so return immediately
171+
if m.Platform.Architecture == runtime.GOARCH {
172+
return handleManifest(reg, m.MediaType, remote, m.Digest.String())
173+
}
174+
if m.Platform.Architecture == "amd64" {
175+
foundAMD = true
176+
amdManifest = m
177+
}
178+
}
179+
if foundAMD {
180+
return handleManifest(reg, amdManifest.MediaType, remote, amdManifest.Digest.String())
181+
}
182+
return "", nil, errors.Errorf("no manifest in list matched linux and amd64 or %s architectures: %s:%s", runtime.GOARCH, remote, ref)
183+
}
184+
156185
func handleManifest(reg types.Registry, manifestType, remote, ref string) (digest.Digest, []string, error) {
157186
switch manifestType {
158187
case manifestV1.MediaTypeManifest:
@@ -203,25 +232,13 @@ func handleManifest(reg types.Registry, manifestType, remote, ref string) (diges
203232
if err != nil {
204233
return "", nil, err
205234
}
206-
for _, manifest := range manifestList.Manifests {
207-
// TODO(ROX-13284): Support multi-arch images.
208-
if manifest.Platform.OS == "linux" && manifest.Platform.Architecture == "amd64" {
209-
return handleManifest(reg, manifest.MediaType, remote, manifest.Digest.String())
210-
}
211-
}
212-
return "", nil, errors.New("No corresponding manifest found from Docker manifest list object")
235+
return handleManifestLists(reg, remote, ref, manifestList.Manifests)
213236
case registry.MediaTypeImageIndex:
214237
imageIndex, err := reg.ImageIndex(remote, ref)
215238
if err != nil {
216239
return "", nil, err
217240
}
218-
for _, manifest := range imageIndex.Manifests {
219-
// TODO(ROX-13284): Support multi-arch images.
220-
if manifest.Platform.OS == "linux" && manifest.Platform.Architecture == "amd64" {
221-
return handleManifest(reg, manifest.MediaType, remote, manifest.Digest.String())
222-
}
223-
}
224-
return "", nil, errors.New("No corresponding manifest found from OCI image index object")
241+
return handleManifestLists(reg, remote, ref, imageIndex.Manifests)
225242
default:
226243
return "", nil, fmt.Errorf("Could not parse manifest type %q", manifestType)
227244
}

0 commit comments

Comments
 (0)