@@ -19,6 +19,7 @@ package images
1919import (
2020 "context"
2121 "fmt"
22+ "sort"
2223
2324 "github.com/containerd/containerd/content"
2425 "github.com/containerd/containerd/platforms"
@@ -182,65 +183,61 @@ func SetChildrenLabels(manager content.Manager, f HandlerFunc) HandlerFunc {
182183 }
183184}
184185
185- // FilterPlatformList is a handler wrapper which limits the descriptors returned
186- // by a handler to the specified platforms .
187- func FilterPlatformList (f HandlerFunc , platformList ... string ) HandlerFunc {
186+ // FilterPlatforms is a handler wrapper which limits the descriptors returned
187+ // based on matching the specified platform matcher .
188+ func FilterPlatforms (f HandlerFunc , m platforms. Matcher ) HandlerFunc {
188189 return func (ctx context.Context , desc ocispec.Descriptor ) ([]ocispec.Descriptor , error ) {
189190 children , err := f (ctx , desc )
190191 if err != nil {
191192 return children , err
192193 }
193194
194- if len (platformList ) == 0 {
195- return children , nil
196- }
197-
198- var m platforms.Matcher
195+ var descs []ocispec.Descriptor
199196
200- if len ( platformList ) > 0 {
201- ps := make ([]ocispec. Platform , len ( platformList ))
202- for i , platform := range platformList {
203- p , err := platforms . Parse ( platform )
204- if err != nil {
205- return nil , err
197+ if m == nil {
198+ descs = children
199+ } else {
200+ for _ , d := range children {
201+ if d . Platform == nil || m . Match ( * d . Platform ) {
202+ descs = append ( descs , d )
206203 }
207- ps [i ] = p
208- }
209- m = platforms .Any (ps ... )
210- }
211-
212- var descs []ocispec.Descriptor
213- for _ , d := range children {
214- if d .Platform == nil || m .Match (* d .Platform ) {
215- descs = append (descs , d )
216204 }
217205 }
218206
219207 return descs , nil
220208 }
221209}
222210
223- // FilterPlatforms is a handler wrapper which limits the descriptors returned
224- // based on matching the specified platform matcher.
225- func FilterPlatforms (f HandlerFunc , m platforms.Matcher ) HandlerFunc {
211+ // LimitManifests is a handler wrapper which filters the manifest descriptors
212+ // returned using the provided platform.
213+ // The results will be ordered according to the comparison operator and
214+ // use the ordering in the manifests for equal matches.
215+ // A limit of 0 or less is considered no limit.
216+ func LimitManifests (f HandlerFunc , m platforms.MatchComparer , n int ) HandlerFunc {
226217 return func (ctx context.Context , desc ocispec.Descriptor ) ([]ocispec.Descriptor , error ) {
227218 children , err := f (ctx , desc )
228219 if err != nil {
229220 return children , err
230221 }
231222
232- var descs []ocispec. Descriptor
233-
234- if m == nil {
235- descs = children
236- } else {
237- for _ , d := range children {
238- if d .Platform == nil || m . Match ( * d . Platform ) {
239- descs = append ( descs , d )
223+ switch desc . MediaType {
224+ case ocispec . MediaTypeImageIndex , MediaTypeDockerSchema2ManifestList :
225+ sort . SliceStable ( children , func ( i , j int ) bool {
226+ if children [ i ]. Platform == nil {
227+ return false
228+ }
229+ if children [ j ] .Platform == nil {
230+ return true
240231 }
232+ return m .Less (* children [i ].Platform , * children [j ].Platform )
233+ })
234+
235+ if n > 0 && len (children ) > n {
236+ children = children [:n ]
241237 }
238+ default :
239+ // only limit manifests from an index
242240 }
243-
244- return descs , nil
241+ return children , nil
245242 }
246243}
0 commit comments