mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			131 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			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
 | 
						|
}
 |