...
1 package resolve
2
3 import (
4 "fmt"
5
6 "github.com/google/go-containerregistry/pkg/name"
7 v1 "github.com/google/go-containerregistry/pkg/v1"
8 "github.com/google/go-containerregistry/pkg/v1/remote"
9
10 "edge-infra.dev/pkg/f8n/warehouse/oci"
11 "edge-infra.dev/pkg/f8n/warehouse/oci/walk"
12 "edge-infra.dev/pkg/f8n/warehouse/pallet"
13 )
14
15
16
17
18 func Ref(ref name.Reference) (map[string]pallet.Pallet, error) {
19 desc, err := remote.Get(ref)
20 if err != nil {
21 return nil, err
22 }
23 switch {
24 case desc.MediaType.IsIndex():
25 oart, err := desc.ImageIndex()
26 if err != nil {
27 return nil, fmt.Errorf("Invalid descriptor, failed conversion to ImageIndex")
28 }
29 return Resolve(oart)
30 case desc.MediaType.IsImage():
31 oart, err := desc.Image()
32 if err != nil {
33 return nil, fmt.Errorf("Invalid descriptor, failed conversion to Image")
34 }
35 return Resolve(oart)
36 }
37 return nil, fmt.Errorf("Invalid descriptor, MediaType must be Image or ImageIndex")
38 }
39
40
41
42
43
44
45 func Resolve(a oci.Artifact, opts ...Option) (map[string]pallet.Pallet, error) {
46 options := makeOptions(opts...)
47 resolved := map[string]pallet.Pallet{}
48 walker := &walk.Fns{
49 Index: func(imgIdx v1.ImageIndex, _ v1.ImageIndex) error {
50 p, err := pallet.New(imgIdx)
51 if err != nil {
52 return err
53 }
54 digest, err := p.Digest()
55 if err != nil {
56 return err
57 }
58
59
60 if existing, ok := resolved[p.Name()]; ok {
61 if err := checkForConflicts(existing, digest, options); err != nil {
62 return err
63 }
64 }
65 resolved[p.Name()] = p
66 return nil
67 },
68 Image: func(img v1.Image, parent v1.ImageIndex) error {
69
70
71 isPkg, err := oci.IsPackage(img, parent)
72 if !isPkg || err != nil {
73 return err
74 }
75
76 p, err := pallet.New(img)
77 if err != nil {
78 return err
79 }
80 digest, err := p.Digest()
81 if err != nil {
82 return err
83 }
84
85
86 if existing, ok := resolved[p.Name()]; ok {
87 if err := checkForConflicts(existing, digest, options); err != nil {
88 return err
89 }
90 }
91 resolved[p.Name()] = p
92 return nil
93 },
94 }
95
96 if err := walk.Walk(a, walker); err != nil {
97 return nil, err
98 }
99
100 return resolved, nil
101 }
102
103 func checkForConflicts(p pallet.Pallet, d v1.Hash, o options) error {
104 palletD, err := p.Digest()
105 if err != nil {
106 return err
107 }
108
109 switch {
110 case palletD == d:
111 return nil
112 case o.acceptFirst:
113 return nil
114 case o.strict:
115 return fmt.Errorf("resolve: %w", oci.NewConflictErr(p.Name(), palletD, d))
116 default:
117 return nil
118 }
119 }
120
View as plain text