Add filter fields to image store types
Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
parent
9ae92f16e0
commit
40d3fa3afd
@ -20,6 +20,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/api/types"
|
||||||
transfertypes "github.com/containerd/containerd/api/types/transfer"
|
transfertypes "github.com/containerd/containerd/api/types/transfer"
|
||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
@ -39,23 +40,73 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Store struct {
|
type Store struct {
|
||||||
// TODO: Put these configurations in object which can convert to/from any
|
|
||||||
// Embed generated type
|
|
||||||
imageName string
|
imageName string
|
||||||
imageLabels map[string]string
|
imageLabels map[string]string
|
||||||
platforms platforms.MatchComparer
|
platforms []ocispec.Platform
|
||||||
allMetadata bool
|
allMetadata bool
|
||||||
labelMap func(ocispec.Descriptor) []string
|
labelMap func(ocispec.Descriptor) []string
|
||||||
manifestLimit int
|
manifestLimit int
|
||||||
|
|
||||||
// TODO: Convert these to unpack platforms
|
unpacks []UnpackConfiguration
|
||||||
unpacks []unpack.Platform
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStore(image string) *Store {
|
// UnpackConfiguration specifies the platform and snapshotter to use for resolving
|
||||||
return &Store{
|
// the unpack Platform, if snapshotter is not specified the platform default will
|
||||||
|
// be used.
|
||||||
|
type UnpackConfiguration struct {
|
||||||
|
Platform ocispec.Platform
|
||||||
|
Snapshotter string
|
||||||
|
}
|
||||||
|
|
||||||
|
// StoreOpt defines options when configuring an image store source or destination
|
||||||
|
type StoreOpt func(*Store)
|
||||||
|
|
||||||
|
// WithImageLabels are the image labels to apply to a new image
|
||||||
|
func WithImageLabels(labels map[string]string) StoreOpt {
|
||||||
|
return func(s *Store) {
|
||||||
|
s.imageLabels = labels
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPlatforms specifies which platforms to fetch content for
|
||||||
|
func WithPlatforms(p ...ocispec.Platform) StoreOpt {
|
||||||
|
return func(s *Store) {
|
||||||
|
s.platforms = append(s.platforms, p...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithManifestLimit defines the max number of manifests to fetch
|
||||||
|
func WithManifestLimit(limit int) StoreOpt {
|
||||||
|
return func(s *Store) {
|
||||||
|
s.manifestLimit = limit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithAllMetadata(s *Store) {
|
||||||
|
s.allMetadata = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithUnpack specifies a platform to unpack for and an optional snapshotter to use
|
||||||
|
func WithUnpack(p ocispec.Platform, snapshotter string) StoreOpt {
|
||||||
|
return func(s *Store) {
|
||||||
|
s.unpacks = append(s.unpacks, UnpackConfiguration{
|
||||||
|
Platform: p,
|
||||||
|
Snapshotter: snapshotter,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStore creates a new image store source or Destination
|
||||||
|
func NewStore(image string, opts ...StoreOpt) *Store {
|
||||||
|
s := &Store{
|
||||||
imageName: image,
|
imageName: image,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (is *Store) String() string {
|
func (is *Store) String() string {
|
||||||
@ -63,19 +114,25 @@ func (is *Store) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (is *Store) ImageFilter(h images.HandlerFunc, cs content.Store) images.HandlerFunc {
|
func (is *Store) ImageFilter(h images.HandlerFunc, cs content.Store) images.HandlerFunc {
|
||||||
|
var p platforms.MatchComparer
|
||||||
|
if len(is.platforms) == 0 {
|
||||||
|
p = platforms.All
|
||||||
|
} else {
|
||||||
|
p = platforms.Ordered(is.platforms...)
|
||||||
|
}
|
||||||
h = images.SetChildrenMappedLabels(cs, h, is.labelMap)
|
h = images.SetChildrenMappedLabels(cs, h, is.labelMap)
|
||||||
if is.allMetadata {
|
if is.allMetadata {
|
||||||
// Filter manifests by platforms but allow to handle manifest
|
// Filter manifests by platforms but allow to handle manifest
|
||||||
// and configuration for not-target platforms
|
// and configuration for not-target platforms
|
||||||
h = remotes.FilterManifestByPlatformHandler(h, is.platforms)
|
h = remotes.FilterManifestByPlatformHandler(h, p)
|
||||||
} else {
|
} else {
|
||||||
// Filter children by platforms if specified.
|
// Filter children by platforms if specified.
|
||||||
h = images.FilterPlatforms(h, is.platforms)
|
h = images.FilterPlatforms(h, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort and limit manifests if a finite number is needed
|
// Sort and limit manifests if a finite number is needed
|
||||||
if is.manifestLimit > 0 {
|
if is.manifestLimit > 0 {
|
||||||
h = images.LimitManifests(h, is.platforms, is.manifestLimit)
|
h = images.LimitManifests(h, p, is.manifestLimit)
|
||||||
}
|
}
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
@ -116,13 +173,23 @@ func (is *Store) Get(ctx context.Context, store images.Store) (images.Image, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (is *Store) UnpackPlatforms() []unpack.Platform {
|
func (is *Store) UnpackPlatforms() []unpack.Platform {
|
||||||
return is.unpacks
|
unpacks := make([]unpack.Platform, len(is.unpacks))
|
||||||
|
for i, uc := range is.unpacks {
|
||||||
|
unpacks[i].SnapshotterKey = uc.Snapshotter
|
||||||
|
unpacks[i].Platform = platforms.Only(uc.Platform)
|
||||||
|
}
|
||||||
|
return unpacks
|
||||||
}
|
}
|
||||||
|
|
||||||
func (is *Store) MarshalAny(ctx context.Context, sm streaming.StreamCreator) (typeurl.Any, error) {
|
func (is *Store) MarshalAny(context.Context, streaming.StreamCreator) (typeurl.Any, error) {
|
||||||
|
//unpack.Platform
|
||||||
s := &transfertypes.ImageStore{
|
s := &transfertypes.ImageStore{
|
||||||
Name: is.imageName,
|
Name: is.imageName,
|
||||||
// TODO: Support other fields
|
Labels: is.imageLabels,
|
||||||
|
ManifestLimit: uint32(is.manifestLimit),
|
||||||
|
AllMetadata: is.allMetadata,
|
||||||
|
Platforms: platformsToProto(is.platforms),
|
||||||
|
Unpacks: unpackToProto(is.unpacks),
|
||||||
}
|
}
|
||||||
return typeurl.MarshalAny(s)
|
return typeurl.MarshalAny(s)
|
||||||
}
|
}
|
||||||
@ -134,7 +201,64 @@ func (is *Store) UnmarshalAny(ctx context.Context, sm streaming.StreamGetter, a
|
|||||||
}
|
}
|
||||||
|
|
||||||
is.imageName = s.Name
|
is.imageName = s.Name
|
||||||
// TODO: Support other fields
|
is.imageLabels = s.Labels
|
||||||
|
is.manifestLimit = int(s.ManifestLimit)
|
||||||
|
is.allMetadata = s.AllMetadata
|
||||||
|
is.platforms = platformFromProto(s.Platforms)
|
||||||
|
is.unpacks = unpackFromProto(s.Unpacks)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func platformsToProto(platforms []ocispec.Platform) []*types.Platform {
|
||||||
|
ap := make([]*types.Platform, len(platforms))
|
||||||
|
for i := range platforms {
|
||||||
|
p := types.Platform{
|
||||||
|
OS: platforms[i].OS,
|
||||||
|
Architecture: platforms[i].Architecture,
|
||||||
|
Variant: platforms[i].Variant,
|
||||||
|
}
|
||||||
|
|
||||||
|
ap[i] = &p
|
||||||
|
}
|
||||||
|
return ap
|
||||||
|
}
|
||||||
|
|
||||||
|
func platformFromProto(platforms []*types.Platform) []ocispec.Platform {
|
||||||
|
op := make([]ocispec.Platform, len(platforms))
|
||||||
|
for i := range platforms {
|
||||||
|
op[i].OS = platforms[i].OS
|
||||||
|
op[i].Architecture = platforms[i].Architecture
|
||||||
|
op[i].Variant = platforms[i].Variant
|
||||||
|
}
|
||||||
|
return op
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackToProto(uc []UnpackConfiguration) []*transfertypes.UnpackConfiguration {
|
||||||
|
auc := make([]*transfertypes.UnpackConfiguration, len(uc))
|
||||||
|
for i := range uc {
|
||||||
|
p := types.Platform{
|
||||||
|
OS: uc[i].Platform.OS,
|
||||||
|
Architecture: uc[i].Platform.Architecture,
|
||||||
|
Variant: uc[i].Platform.Variant,
|
||||||
|
}
|
||||||
|
auc[i] = &transfertypes.UnpackConfiguration{
|
||||||
|
Platform: &p,
|
||||||
|
Snapshotter: uc[i].Snapshotter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return auc
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackFromProto(auc []*transfertypes.UnpackConfiguration) []UnpackConfiguration {
|
||||||
|
uc := make([]UnpackConfiguration, len(auc))
|
||||||
|
for i := range auc {
|
||||||
|
uc[i].Snapshotter = auc[i].Snapshotter
|
||||||
|
if auc[i].Platform != nil {
|
||||||
|
uc[i].Platform.OS = auc[i].Platform.OS
|
||||||
|
uc[i].Platform.Architecture = auc[i].Platform.Architecture
|
||||||
|
uc[i].Platform.Variant = auc[i].Platform.Variant
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uc
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user