@@ -19,24 +19,28 @@ import (
19
19
"errors"
20
20
"fmt"
21
21
"io/ioutil"
22
+ "os"
23
+ "path/filepath"
22
24
23
25
"github.com/operator-framework/operator-sdk/internal/olm"
24
26
olmresourceclient "github.com/operator-framework/operator-sdk/internal/olm/client"
25
27
opinternal "github.com/operator-framework/operator-sdk/internal/olm/operator/internal"
26
28
"github.com/operator-framework/operator-sdk/internal/util/k8sutil"
27
29
28
- manifests "github.com/operator-framework/api/pkg/manifests"
30
+ "github.com/operator-framework/api/pkg/manifests"
29
31
valerrors "github.com/operator-framework/api/pkg/validation/errors"
30
32
olmapiv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1"
31
33
olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
32
- registry "github.com/operator-framework/operator-registry/pkg/registry"
34
+ "github.com/operator-framework/operator-registry/pkg/lib/bundle"
35
+ "github.com/operator-framework/operator-registry/pkg/registry"
33
36
log "github.com/sirupsen/logrus"
34
37
apiextinstall "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install"
35
38
apierrors "k8s.io/apimachinery/pkg/api/errors"
36
39
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
37
40
"k8s.io/apimachinery/pkg/runtime"
38
41
"k8s.io/apimachinery/pkg/types"
39
42
"k8s.io/client-go/kubernetes/scheme"
43
+ "sigs.k8s.io/yaml"
40
44
)
41
45
42
46
const defaultNamespace = "default"
@@ -71,14 +75,17 @@ func (c *OLMCmd) newManager() (*operatorManager, error) {
71
75
version : c .OperatorVersion ,
72
76
forceRegistry : c .ForceRegistry ,
73
77
}
74
- rc , ns , err := k8sutil .GetKubeconfigAndNamespace (c .KubeconfigPath )
75
- if err != nil {
76
- return nil , fmt .Errorf ("failed to get namespace from kubeconfig %s: %w" , c .KubeconfigPath , err )
77
- }
78
+
79
+ // Namespace in which OLM is deployed.
78
80
if m .olmNamespace = c .OLMNamespace ; m .olmNamespace == "" {
79
81
m .olmNamespace = olm .DefaultOLMNamespace
80
82
}
81
83
84
+ // Cluster and operator namespace info.
85
+ rc , ns , err := k8sutil .GetKubeconfigAndNamespace (c .KubeconfigPath )
86
+ if err != nil {
87
+ return nil , fmt .Errorf ("failed to get namespace from kubeconfig %s: %w" , c .KubeconfigPath , err )
88
+ }
82
89
if ns == "" {
83
90
ns = defaultNamespace
84
91
}
@@ -91,6 +98,8 @@ func (c *OLMCmd) newManager() (*operatorManager, error) {
91
98
return nil , fmt .Errorf ("failed to create SDK OLM client: %w" , err )
92
99
}
93
100
}
101
+
102
+ // Parse k8s objects.
94
103
for _ , path := range c .IncludePaths {
95
104
if path != "" {
96
105
objs , err := readObjectsFromFile (path )
@@ -108,7 +117,10 @@ func (c *OLMCmd) newManager() (*operatorManager, error) {
108
117
if hasSub || hasCatSrc && ! (hasSub && hasCatSrc ) {
109
118
return nil , errors .New ("both a CatalogSource and Subscription must be supplied if one is supplied" )
110
119
}
111
- pkg , bundles , results := manifests .GetManifestsDir (c .ManifestsDir )
120
+
121
+ // Operator bundles and metadata.
122
+ var results []valerrors.ManifestResult
123
+ m .pkg , m .bundles , results = manifests .GetManifestsDir (c .ManifestsDir )
112
124
if len (results ) != 0 {
113
125
badResults := []valerrors.ManifestResult {}
114
126
for _ , result := range results {
@@ -120,7 +132,17 @@ func (c *OLMCmd) newManager() (*operatorManager, error) {
120
132
return nil , fmt .Errorf ("bundle dir had errors: %s" , badResults )
121
133
}
122
134
}
123
- m .pkg , m .bundles = pkg , bundles
135
+ // Prefer annotations over a package manifest, which is now deprecated.
136
+ if annotations , err := findAnnotations (c .ManifestsDir ); err == nil {
137
+ m .pkg = translateAnnotationsToPackage (annotations , fmt .Sprintf ("%s.v%s" , annotations .GetName (), m .version ))
138
+ } else if ! os .IsNotExist (err ) {
139
+ return nil , fmt .Errorf ("error finding annotations: %v" , err )
140
+ }
141
+ if m .pkg .PackageName == "" {
142
+ return nil , errors .New ("no package metadata found" )
143
+ }
144
+
145
+ // Handle installModes.
124
146
if c .InstallMode == "" {
125
147
// Default to OwnNamespace.
126
148
m .installMode = olmapiv1alpha1 .InstallModeTypeOwnNamespace
@@ -134,15 +156,51 @@ func (c *OLMCmd) newManager() (*operatorManager, error) {
134
156
if err := m .installModeCompatible (m .installMode ); err != nil {
135
157
return nil , err
136
158
}
159
+
137
160
return m , nil
138
161
}
139
162
163
+ // findAnnotations returns annotations metadata from '<dir>/metadata/annotations.yaml'.
164
+ func findAnnotations (dir string ) (annotations registry.AnnotationsFile , err error ) {
165
+ annotationsPath := filepath .Join (dir , bundle .MetadataDir , bundle .AnnotationsFile )
166
+ b , err := ioutil .ReadFile (annotationsPath )
167
+ if err != nil {
168
+ return annotations , err
169
+ }
170
+ if err = yaml .Unmarshal (b , & annotations ); err != nil {
171
+ return annotations , err
172
+ }
173
+ return annotations , nil
174
+ }
175
+
176
+ // translateAnnotationsToPackage creates a package manifest from an annotations
177
+ // file. We use this workaround because registry-server will not populate the
178
+ // database directory from an annotations.yaml file. This is what an index image
179
+ // build does:
180
+ // https://github.com/operator-framework/operator-registry/blob/v1.9.0/pkg/registry/populator.go#L285
181
+ func translateAnnotationsToPackage (annotations registry.AnnotationsFile , csvName string ) registry.PackageManifest {
182
+ pkg := registry.PackageManifest {
183
+ PackageName : annotations .GetName (),
184
+ DefaultChannelName : annotations .GetDefaultChannelName (),
185
+ }
186
+
187
+ for _ , channel := range annotations .GetChannels () {
188
+ pkg .Channels = append (pkg .Channels , registry.PackageChannel {
189
+ Name : channel ,
190
+ CurrentCSVName : csvName ,
191
+ })
192
+ }
193
+
194
+ return pkg
195
+ }
196
+
140
197
func (m * operatorManager ) run (ctx context.Context ) (err error ) {
141
198
// Ensure OLM is installed.
142
199
olmVer , err := m .client .GetInstalledVersion (ctx , m .olmNamespace )
143
200
if err != nil {
144
201
return fmt .Errorf ("error getting installed OLM version: %w" , err )
145
202
}
203
+
146
204
pkgName := m .pkg .PackageName
147
205
bundle , err := getBundleForVersion (m .bundles , m .version )
148
206
if err != nil {
@@ -152,6 +210,7 @@ func (m *operatorManager) run(ctx context.Context) (err error) {
152
210
if err != nil {
153
211
return fmt .Errorf ("error getting CSV from bundle: %w" , err )
154
212
}
213
+
155
214
// Only check CSV here, since other deployed operators/versions may be
156
215
// running with shared CRDs.
157
216
obj , err := runtime .DefaultUnstructuredConverter .ToUnstructured (csv )
@@ -169,6 +228,7 @@ func (m *operatorManager) run(ctx context.Context) (err error) {
169
228
if err = m .registryUp (ctx , m .olmNamespace ); err != nil {
170
229
return fmt .Errorf ("error creating registry resources: %w" , err )
171
230
}
231
+
172
232
log .Info ("Creating resources" )
173
233
if ! m .hasCatalogSource () {
174
234
registryGRPCAddr := opinternal .GetRegistryServiceAddr (pkgName , m .olmNamespace )
@@ -205,6 +265,7 @@ func (m *operatorManager) run(ctx context.Context) (err error) {
205
265
if err = m .client .DoCreate (ctx , objects ... ); err != nil {
206
266
return fmt .Errorf ("error creating operator resources: %w" , err )
207
267
}
268
+
208
269
// BUG(estroz): if m.namespace is not contained in m.installModeNamespaces,
209
270
// DoCSVWait will fail.
210
271
nn := types.NamespacedName {
@@ -234,6 +295,7 @@ func (m *operatorManager) cleanup(ctx context.Context) (err error) {
234
295
if err != nil {
235
296
return fmt .Errorf ("error getting installed OLM version: %w" , err )
236
297
}
298
+
237
299
pkgName := m .pkg .PackageName
238
300
bundle , err := getBundleForVersion (m .bundles , m .version )
239
301
if err != nil {
@@ -247,6 +309,7 @@ func (m *operatorManager) cleanup(ctx context.Context) (err error) {
247
309
if err = m .registryDown (ctx , m .olmNamespace ); err != nil {
248
310
return fmt .Errorf ("error removing registry resources: %w" , err )
249
311
}
312
+
250
313
log .Info ("Deleting resources" )
251
314
if ! m .hasCatalogSource () {
252
315
m .olmObjects = append (m .olmObjects , newCatalogSource (pkgName , m .namespace ))
@@ -287,6 +350,7 @@ func (m operatorManager) registryUp(ctx context.Context, namespace string) error
287
350
Pkg : m .pkg ,
288
351
Bundles : m .bundles ,
289
352
}
353
+
290
354
registryStale , err := rr .IsManifestDataStale (ctx , namespace )
291
355
if err != nil {
292
356
if ! apierrors .IsNotFound (err ) {
@@ -310,6 +374,7 @@ func (m operatorManager) registryUp(ctx context.Context, namespace string) error
310
374
if err = rr .CreateRegistryManifests (ctx , namespace ); err != nil {
311
375
return fmt .Errorf ("error registering bundle: %w" , err )
312
376
}
377
+
313
378
return nil
314
379
}
315
380
@@ -319,12 +384,14 @@ func (m *operatorManager) registryDown(ctx context.Context, namespace string) er
319
384
Pkg : m .pkg ,
320
385
Bundles : m .bundles ,
321
386
}
387
+
322
388
if m .forceRegistry {
323
389
log .Printf ("Deleting registry" )
324
390
if err := rr .DeleteRegistryManifests (ctx , namespace ); err != nil {
325
391
return fmt .Errorf ("error deleting registered bundle: %w" , err )
326
392
}
327
393
}
394
+
328
395
return nil
329
396
}
330
397
0 commit comments