Add a manifest filter limiting the number of matches
Adds a manifest filter for pulling which ensures only one manifest from a manifest list is pulled even when multiple matches. Removes unused filter platform list. Signed-off-by: Derek McGowan <derek@mcgstyle.net>
This commit is contained in:
parent
0a3f87ec2e
commit
3d1082e06d
10
client.go
10
client.go
@ -338,7 +338,7 @@ func (c *Client) Fetch(ctx context.Context, ref string, opts ...RemoteOpt) (imag
|
|||||||
}
|
}
|
||||||
defer done(ctx)
|
defer done(ctx)
|
||||||
|
|
||||||
return c.fetch(ctx, fetchCtx, ref)
|
return c.fetch(ctx, fetchCtx, ref, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull downloads the provided content into containerd's content store
|
// Pull downloads the provided content into containerd's content store
|
||||||
@ -372,7 +372,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image
|
|||||||
}
|
}
|
||||||
defer done(ctx)
|
defer done(ctx)
|
||||||
|
|
||||||
img, err := c.fetch(ctx, pullCtx, ref)
|
img, err := c.fetch(ctx, pullCtx, ref, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -388,7 +388,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image
|
|||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string) (images.Image, error) {
|
func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, limit int) (images.Image, error) {
|
||||||
store := c.ContentStore()
|
store := c.ContentStore()
|
||||||
name, desc, err := rCtx.Resolver.Resolve(ctx, ref)
|
name, desc, err := rCtx.Resolver.Resolve(ctx, ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -414,6 +414,10 @@ func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string) (im
|
|||||||
childrenHandler = images.SetChildrenLabels(store, childrenHandler)
|
childrenHandler = images.SetChildrenLabels(store, childrenHandler)
|
||||||
// Filter children by platforms
|
// Filter children by platforms
|
||||||
childrenHandler = images.FilterPlatforms(childrenHandler, rCtx.PlatformMatcher)
|
childrenHandler = images.FilterPlatforms(childrenHandler, rCtx.PlatformMatcher)
|
||||||
|
// Sort and limit manifests if a finite number is needed
|
||||||
|
if limit > 0 {
|
||||||
|
childrenHandler = images.LimitManifests(childrenHandler, rCtx.PlatformMatcher, limit)
|
||||||
|
}
|
||||||
|
|
||||||
handler = images.Handlers(append(rCtx.BaseHandlers,
|
handler = images.Handlers(append(rCtx.BaseHandlers,
|
||||||
remotes.FetchHandler(store, fetcher),
|
remotes.FetchHandler(store, fetcher),
|
||||||
|
@ -19,6 +19,7 @@ package images
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/platforms"
|
"github.com/containerd/containerd/platforms"
|
||||||
@ -182,44 +183,6 @@ func SetChildrenLabels(manager content.Manager, f HandlerFunc) HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FilterPlatformList is a handler wrapper which limits the descriptors returned
|
|
||||||
// by a handler to the specified platforms.
|
|
||||||
func FilterPlatformList(f HandlerFunc, platformList ...string) HandlerFunc {
|
|
||||||
return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
|
||||||
children, err := f(ctx, desc)
|
|
||||||
if err != nil {
|
|
||||||
return children, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(platformList) == 0 {
|
|
||||||
return children, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var m platforms.Matcher
|
|
||||||
|
|
||||||
if len(platformList) > 0 {
|
|
||||||
ps := make([]ocispec.Platform, len(platformList))
|
|
||||||
for i, platform := range platformList {
|
|
||||||
p, err := platforms.Parse(platform)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ps[i] = p
|
|
||||||
}
|
|
||||||
m = platforms.Any(ps...)
|
|
||||||
}
|
|
||||||
|
|
||||||
var descs []ocispec.Descriptor
|
|
||||||
for _, d := range children {
|
|
||||||
if d.Platform == nil || m.Match(*d.Platform) {
|
|
||||||
descs = append(descs, d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return descs, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FilterPlatforms is a handler wrapper which limits the descriptors returned
|
// FilterPlatforms is a handler wrapper which limits the descriptors returned
|
||||||
// based on matching the specified platform matcher.
|
// based on matching the specified platform matcher.
|
||||||
func FilterPlatforms(f HandlerFunc, m platforms.Matcher) HandlerFunc {
|
func FilterPlatforms(f HandlerFunc, m platforms.Matcher) HandlerFunc {
|
||||||
@ -244,3 +207,37 @@ func FilterPlatforms(f HandlerFunc, m platforms.Matcher) HandlerFunc {
|
|||||||
return descs, nil
|
return descs, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LimitManifests is a handler wrapper which filters the manifest descriptors
|
||||||
|
// returned using the provided platform.
|
||||||
|
// The results will be ordered according to the comparison operator and
|
||||||
|
// use the ordering in the manifests for equal matches.
|
||||||
|
// A limit of 0 or less is considered no limit.
|
||||||
|
func LimitManifests(f HandlerFunc, m platforms.MatchComparer, n int) HandlerFunc {
|
||||||
|
return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
||||||
|
children, err := f(ctx, desc)
|
||||||
|
if err != nil {
|
||||||
|
return children, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch desc.MediaType {
|
||||||
|
case ocispec.MediaTypeImageIndex, MediaTypeDockerSchema2ManifestList:
|
||||||
|
sort.SliceStable(children, func(i, j int) bool {
|
||||||
|
if children[i].Platform == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if children[j].Platform == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return m.Less(*children[i].Platform, *children[j].Platform)
|
||||||
|
})
|
||||||
|
|
||||||
|
if n > 0 && len(children) > n {
|
||||||
|
children = children[:n]
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// only limit manifests from an index
|
||||||
|
}
|
||||||
|
return children, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user