-
Notifications
You must be signed in to change notification settings - Fork 71
/
packagemanifestloader.go
134 lines (106 loc) · 3.05 KB
/
packagemanifestloader.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package manifests
import (
"fmt"
"os"
"path/filepath"
"strings"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/yaml"
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
)
// bundleLoader loads a bundle directory from disk
type packageManifestLoader struct {
dir string
bundles []*Bundle
pkg *PackageManifest
}
func NewPackageManifestLoader(dir string) packageManifestLoader {
return packageManifestLoader{
dir: dir,
}
}
func (p *packageManifestLoader) LoadPackage() error {
errs := make([]error, 0)
if err := filepath.Walk(p.dir, collectWalkErrs(p.LoadPackagesWalkFunc, &errs)); err != nil {
errs = append(errs, err)
}
if err := filepath.Walk(p.dir, collectWalkErrs(p.LoadBundleWalkFunc, &errs)); err != nil {
errs = append(errs, err)
}
return utilerrors.NewAggregate(errs)
}
// LoadPackagesWalkFunc attempts to unmarshal the file at the given path into a PackageManifest resource.
// If unmarshaling is successful, the PackageManifest is added to the loader's store.
func (p *packageManifestLoader) LoadPackagesWalkFunc(path string, f os.FileInfo, err error) error {
if f == nil {
return fmt.Errorf("invalid file: %v", f)
}
if f.IsDir() {
if strings.HasPrefix(f.Name(), ".") {
return filepath.SkipDir
}
return nil
}
if strings.HasPrefix(f.Name(), ".") {
return nil
}
fileReader, err := os.Open(path)
if err != nil {
return fmt.Errorf("unable to load package from file %s: %s", path, err)
}
defer fileReader.Close()
decoder := yaml.NewYAMLOrJSONDecoder(fileReader, 30)
manifest := PackageManifest{}
if err = decoder.Decode(&manifest); err != nil {
if err != nil {
return fmt.Errorf("could not decode contents of file %s into package: %s", path, err)
}
}
if manifest.IsEmpty() {
return nil
}
if p.pkg != nil {
return fmt.Errorf("multiple package manifest files found in directory")
}
p.pkg = &manifest
return nil
}
func (p *packageManifestLoader) LoadBundleWalkFunc(path string, f os.FileInfo, err error) error {
if f == nil {
return fmt.Errorf("invalid file: %v", f)
}
if f.IsDir() {
if strings.HasPrefix(f.Name(), ".") {
return filepath.SkipDir
}
return nil
}
if strings.HasPrefix(f.Name(), ".") {
return nil
}
fileReader, err := os.Open(path)
if err != nil {
return fmt.Errorf("unable to load file %s: %s", path, err)
}
defer fileReader.Close()
decoder := yaml.NewYAMLOrJSONDecoder(fileReader, 30)
csv := unstructured.Unstructured{}
if err = decoder.Decode(&csv); err != nil {
return nil
}
if csv.GetKind() != operatorsv1alpha1.ClusterServiceVersionKind {
return nil
}
var errs []error
bundle, err := loadBundle(csv.GetName(), filepath.Dir(path))
if err != nil {
errs = append(errs, fmt.Errorf("error loading objs in directory: %s", err))
}
if bundle == nil || bundle.CSV == nil {
errs = append(errs, fmt.Errorf("no bundle csv found"))
return utilerrors.NewAggregate(errs)
}
p.bundles = append(p.bundles, bundle)
return utilerrors.NewAggregate(errs)
}