1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package partial
16
17 import (
18 "fmt"
19
20 v1 "github.com/google/go-containerregistry/pkg/v1"
21 "github.com/google/go-containerregistry/pkg/v1/match"
22 "github.com/google/go-containerregistry/pkg/v1/types"
23 )
24
25
26 func FindManifests(index v1.ImageIndex, matcher match.Matcher) ([]v1.Descriptor, error) {
27
28 indexManifest, err := index.IndexManifest()
29 if err != nil {
30 return nil, fmt.Errorf("unable to get raw index: %w", err)
31 }
32 manifests := []v1.Descriptor{}
33
34 for _, manifest := range indexManifest.Manifests {
35 if matcher(manifest) {
36 manifests = append(manifests, manifest)
37 }
38 }
39 return manifests, nil
40 }
41
42
43
44
45 func FindImages(index v1.ImageIndex, matcher match.Matcher) ([]v1.Image, error) {
46 matches := []v1.Image{}
47 manifests, err := FindManifests(index, matcher)
48 if err != nil {
49 return nil, err
50 }
51 for _, desc := range manifests {
52
53 if !desc.MediaType.IsImage() {
54 continue
55 }
56 img, err := index.Image(desc.Digest)
57 if err != nil {
58 return nil, err
59 }
60 matches = append(matches, img)
61 }
62 return matches, nil
63 }
64
65
66
67
68 func FindIndexes(index v1.ImageIndex, matcher match.Matcher) ([]v1.ImageIndex, error) {
69 matches := []v1.ImageIndex{}
70 manifests, err := FindManifests(index, matcher)
71 if err != nil {
72 return nil, err
73 }
74 for _, desc := range manifests {
75 if !desc.MediaType.IsIndex() {
76 continue
77 }
78
79 idx, err := index.ImageIndex(desc.Digest)
80 if err != nil {
81 return nil, err
82 }
83 matches = append(matches, idx)
84 }
85 return matches, nil
86 }
87
88 type withManifests interface {
89 Manifests() ([]Describable, error)
90 }
91
92 type withLayer interface {
93 Layer(v1.Hash) (v1.Layer, error)
94 }
95
96 type describable struct {
97 desc v1.Descriptor
98 }
99
100 func (d describable) Digest() (v1.Hash, error) {
101 return d.desc.Digest, nil
102 }
103
104 func (d describable) Size() (int64, error) {
105 return d.desc.Size, nil
106 }
107
108 func (d describable) MediaType() (types.MediaType, error) {
109 return d.desc.MediaType, nil
110 }
111
112 func (d describable) Descriptor() (*v1.Descriptor, error) {
113 return &d.desc, nil
114 }
115
116
117
118
119
120
121
122 func Manifests(idx v1.ImageIndex) ([]Describable, error) {
123 if wm, ok := idx.(withManifests); ok {
124 return wm.Manifests()
125 }
126
127 return ComputeManifests(idx)
128 }
129
130
131 func ComputeManifests(idx v1.ImageIndex) ([]Describable, error) {
132 m, err := idx.IndexManifest()
133 if err != nil {
134 return nil, err
135 }
136 manifests := []Describable{}
137 for _, desc := range m.Manifests {
138 switch {
139 case desc.MediaType.IsImage():
140 img, err := idx.Image(desc.Digest)
141 if err != nil {
142 return nil, err
143 }
144 manifests = append(manifests, img)
145 case desc.MediaType.IsIndex():
146 idx, err := idx.ImageIndex(desc.Digest)
147 if err != nil {
148 return nil, err
149 }
150 manifests = append(manifests, idx)
151 default:
152 if wl, ok := idx.(withLayer); ok {
153 layer, err := wl.Layer(desc.Digest)
154 if err != nil {
155 return nil, err
156 }
157 manifests = append(manifests, layer)
158 } else {
159 manifests = append(manifests, describable{desc})
160 }
161 }
162 }
163
164 return manifests, nil
165 }
166
View as plain text