You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
buildx/vendor/github.com/moby/buildkit/util/testutil/imageinfo.go

131 lines
3.0 KiB
Go

package testutil
import (
"context"
"encoding/json"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/platforms"
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
type ImageInfo struct {
Desc ocispecs.Descriptor
Manifest ocispecs.Manifest
Img ocispecs.Image
Layers []map[string]*TarItem
LayersRaw [][]byte
descPlatform string
}
type ImagesInfo struct {
Desc ocispecs.Descriptor
Index ocispecs.Index
Images []*ImageInfo
}
func (idx ImagesInfo) Find(platform string) *ImageInfo {
result := idx.Filter(platform)
if len(result.Images) == 0 {
return nil
}
return result.Images[0]
}
func (idx ImagesInfo) Filter(platform string) *ImagesInfo {
result := &ImagesInfo{Desc: idx.Desc}
for _, info := range idx.Images {
if info.descPlatform == platform {
result.Images = append(result.Images, info)
}
}
return result
}
func (idx ImagesInfo) FindAttestation(platform string) *ImageInfo {
img := idx.Find(platform)
if img == nil {
return nil
}
for _, info := range idx.Images {
if info.Desc.Annotations["vnd.docker.reference.digest"] == string(img.Desc.Digest) {
return info
}
}
return nil
}
func ReadImages(ctx context.Context, p content.Provider, desc ocispecs.Descriptor) (*ImagesInfo, error) {
idx := &ImagesInfo{Desc: desc}
dt, err := content.ReadBlob(ctx, p, desc)
if err != nil {
return nil, err
}
if err := json.Unmarshal(dt, &idx.Index); err != nil {
return nil, err
}
if !images.IsIndexType(idx.Index.MediaType) {
img, err := ReadImage(ctx, p, desc)
if err != nil {
return nil, err
}
img.descPlatform = platforms.Format(img.Img.Platform)
idx.Images = append(idx.Images, img)
return idx, nil
}
for _, m := range idx.Index.Manifests {
img, err := ReadImage(ctx, p, m)
if err != nil {
return nil, err
}
img.descPlatform = platforms.Format(*m.Platform)
idx.Images = append(idx.Images, img)
}
return idx, nil
}
func ReadImage(ctx context.Context, p content.Provider, desc ocispecs.Descriptor) (*ImageInfo, error) {
ii := &ImageInfo{Desc: desc}
dt, err := content.ReadBlob(ctx, p, desc)
if err != nil {
return nil, err
}
if err := json.Unmarshal(dt, &ii.Manifest); err != nil {
return nil, err
}
if !images.IsManifestType(ii.Manifest.MediaType) {
return nil, errors.Errorf("invalid manifest type %s", ii.Manifest.MediaType)
}
dt, err = content.ReadBlob(ctx, p, ii.Manifest.Config)
if err != nil {
return nil, err
}
if err := json.Unmarshal(dt, &ii.Img); err != nil {
return nil, err
}
ii.Layers = make([]map[string]*TarItem, len(ii.Manifest.Layers))
ii.LayersRaw = make([][]byte, len(ii.Manifest.Layers))
for i, l := range ii.Manifest.Layers {
dt, err := content.ReadBlob(ctx, p, l)
if err != nil {
return nil, err
}
ii.LayersRaw[i] = dt
if images.IsLayerType(l.MediaType) {
m, err := ReadTarToMap(dt, true)
if err != nil {
return nil, err
}
ii.Layers[i] = m
}
}
return ii, nil
}