in pkg/containerd/store.go [184:262]
func (c *store) All(ctx context.Context, ref Reference) ([]string, error) {
img, err := c.client.ImageService().Get(ctx, ref.Name())
if err != nil {
return nil, err
}
keys := []string{}
err = images.Walk(ctx, images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
keys = append(keys, desc.Digest.String())
switch desc.MediaType {
case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
var idx ocispec.Index
b, err := content.ReadBlob(ctx, c.client.ContentStore(), desc)
if err != nil {
return nil, err
}
if err := json.Unmarshal(b, &idx); err != nil {
return nil, err
}
var descs []ocispec.Descriptor
for _, m := range idx.Manifests {
if !c.platform.Match(*m.Platform) {
continue
}
descs = append(descs, m)
}
if len(descs) == 0 {
return nil, fmt.Errorf("could not find platform architecture in manifest: %v", desc.Digest)
}
// Platform matching is a bit weird in that multiple platforms can match.
// There is however a "best" match that should be used.
// This logic is used by Containerd to determine which layer to pull so we should use the same logic.
sort.SliceStable(descs, func(i, j int) bool {
if descs[i].Platform == nil {
return false
}
if descs[j].Platform == nil {
return true
}
return c.platform.Less(*descs[i].Platform, *descs[j].Platform)
})
return []ocispec.Descriptor{descs[0]}, nil
case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
var manifest ocispec.Manifest
b, err := content.ReadBlob(ctx, c.client.ContentStore(), desc)
if err != nil {
return nil, err
}
if err := json.Unmarshal(b, &manifest); err != nil {
return nil, err
}
keys = append(keys, manifest.Config.Digest.String())
for _, layer := range manifest.Layers {
keys = append(keys, layer.Digest.String())
}
return nil, nil
default:
return nil, fmt.Errorf("unexpected media type %v for digest: %v", desc.MediaType, desc.Digest)
}
}), img.Target)
if err != nil {
return nil, fmt.Errorf("failed to walk image manifests: %w", err)
}
if len(keys) == 0 {
return nil, fmt.Errorf("no image digests found")
}
return keys, nil
}