@@ -28,6 +28,7 @@ import (
28
28
"github.com/operator-framework/operator-sdk/internal/scaffold"
29
29
"github.com/operator-framework/operator-sdk/internal/util/fileutil"
30
30
"github.com/operator-framework/operator-sdk/internal/util/k8sutil"
31
+ "github.com/operator-framework/operator-sdk/internal/util/projutil"
31
32
"github.com/operator-framework/operator-sdk/internal/util/yamlutil"
32
33
33
34
"github.com/blang/semver"
@@ -51,9 +52,17 @@ const (
51
52
// Input keys for CSV generator whose values are the filepaths for the respective input directories
52
53
53
54
// DeployDirKey is for the location of the operator manifests directory e.g "deploy/production"
55
+ // The Deployment and RBAC manifests from this directory will be used to populate the CSV
56
+ // install strategy: spec.install
54
57
DeployDirKey = "deploy"
55
58
// APIsDirKey is for the location of the API types directory e.g "pkg/apis"
59
+ // The CSV annotation comments will be parsed from the types under this path.
56
60
APIsDirKey = "apis"
61
+ // CRDsDirKey is for the location of the CRD manifests directory e.g "deploy/crds"
62
+ // Both the CRD and CR manifests from this path will be used to populate CSV fields
63
+ // metadata.annotations.alm-examples for CR examples
64
+ // and spec.customresourcedefinitions.owned for owned CRDs
65
+ CRDsDirKey = "crds"
57
66
)
58
67
59
68
type csvGenerator struct {
@@ -107,6 +116,10 @@ func NewCSV(cfg gen.Config, csvVersion, fromVersion string) gen.Generator {
107
116
g .Inputs [APIsDirKey ] = scaffold .ApisDir
108
117
}
109
118
119
+ if crdsDir , ok := g .Inputs [CRDsDirKey ]; ! ok || crdsDir == "" {
120
+ g .Inputs [CRDsDirKey ] = filepath .Join (g .Inputs [DeployDirKey ], "crds" )
121
+ }
122
+
110
123
return g
111
124
}
112
125
@@ -366,60 +379,24 @@ func (g csvGenerator) updateCSVVersions(csv *olmapiv1alpha1.ClusterServiceVersio
366
379
// user-defined manifests and updates csv.
367
380
func (g csvGenerator ) updateCSVFromManifests (csv * olmapiv1alpha1.ClusterServiceVersion ) (err error ) {
368
381
kindManifestMap := map [schema.GroupVersionKind ][][]byte {}
369
- crGVKSet := map [schema.GroupVersionKind ]struct {}{}
370
- err = filepath .Walk (g .Inputs [DeployDirKey ], func (path string , info os.FileInfo , werr error ) error {
371
- if werr != nil {
372
- log .Debugf ("Failed to walk dir: %v" , werr )
373
- return werr
374
- }
375
- // Only read manifest from files, not directories
376
- if info .IsDir () {
377
- // Skip walking olm-catalog dir if it's present in the deploy directory
378
- if info .Name () == OLMCatalogChildDir {
379
- return filepath .SkipDir
380
- }
381
- return nil
382
- }
383
382
384
- b , err := ioutil .ReadFile (path )
385
- if err != nil {
386
- return err
387
- }
388
- scanner := yamlutil .NewYAMLScanner (b )
389
- for scanner .Scan () {
390
- manifest := scanner .Bytes ()
391
- typeMeta , err := k8sutil .GetTypeMetaFromBytes (manifest )
392
- if err != nil {
393
- log .Infof ("No TypeMeta in %s, skipping file" , path )
394
- continue
395
- }
396
- gvk := typeMeta .GroupVersionKind ()
397
- kindManifestMap [gvk ] = append (kindManifestMap [gvk ], manifest )
398
- switch typeMeta .Kind {
399
- case "CustomResourceDefinition" :
400
- // Collect CRD kinds to filter them out from unsupported manifest types.
401
- // The CRD version type doesn't matter as long as it has a group, kind,
402
- // and versions in the expected fields.
403
- crd := v1beta1.CustomResourceDefinition {}
404
- if err = yaml .Unmarshal (manifest , & crd ); err != nil {
405
- return err
406
- }
407
- for _ , ver := range crd .Spec .Versions {
408
- crGVK := schema.GroupVersionKind {
409
- Group : crd .Spec .Group ,
410
- Version : ver .Name ,
411
- Kind : crd .Spec .Names .Kind ,
412
- }
413
- crGVKSet [crGVK ] = struct {}{}
414
- }
415
- }
416
- }
417
- return scanner .Err ()
418
- })
383
+ // Read CRD and CR manifests from CRD dir
384
+ if err := updateFromManifests (g .Inputs [CRDsDirKey ], kindManifestMap ); err != nil {
385
+ return err
386
+ }
387
+
388
+ // Get owned CRDs from CRD manifests
389
+ ownedCRDs , err := getOwnedCRDs (kindManifestMap )
419
390
if err != nil {
420
- return fmt .Errorf ("failed to walk manifests directory for CSV updates: %v" , err )
391
+ return err
392
+ }
393
+
394
+ // Read Deployment and RBAC manifests from Deploy dir
395
+ if err := updateFromManifests (g .Inputs [DeployDirKey ], kindManifestMap ); err != nil {
396
+ return err
421
397
}
422
398
399
+ // Update CSV from all manifest types
423
400
crUpdaters := crs {}
424
401
for gvk , manifests := range kindManifestMap {
425
402
// We don't necessarily care about sorting by a field value, more about
@@ -437,7 +414,8 @@ func (g csvGenerator) updateCSVFromManifests(csv *olmapiv1alpha1.ClusterServiceV
437
414
case "CustomResourceDefinition" :
438
415
err = crds (manifests ).apply (csv )
439
416
default :
440
- if _ , ok := crGVKSet [gvk ]; ok {
417
+ // Only update CR examples for owned CRD types
418
+ if _ , ok := ownedCRDs [gvk ]; ok {
441
419
crUpdaters = append (crUpdaters , crs (manifests )... )
442
420
} else {
443
421
log .Infof ("Skipping manifest %s" , gvk )
@@ -462,3 +440,65 @@ func (g csvGenerator) updateCSVFromManifests(csv *olmapiv1alpha1.ClusterServiceV
462
440
}
463
441
return nil
464
442
}
443
+
444
+ func updateFromManifests (dir string , kindManifestMap map [schema.GroupVersionKind ][][]byte ) error {
445
+ files , err := ioutil .ReadDir (dir )
446
+ if err != nil {
447
+ return err
448
+ }
449
+ // Read and scan all files into kindManifestMap
450
+ wd := projutil .MustGetwd ()
451
+ for _ , f := range files {
452
+ if f .IsDir () {
453
+ continue
454
+ }
455
+ path := filepath .Join (wd , dir , f .Name ())
456
+ b , err := ioutil .ReadFile (path )
457
+ if err != nil {
458
+ return err
459
+ }
460
+ scanner := yamlutil .NewYAMLScanner (b )
461
+ for scanner .Scan () {
462
+ manifest := scanner .Bytes ()
463
+ typeMeta , err := k8sutil .GetTypeMetaFromBytes (manifest )
464
+ if err != nil {
465
+ log .Infof ("No TypeMeta in %s, skipping file" , path )
466
+ continue
467
+ }
468
+
469
+ gvk := typeMeta .GroupVersionKind ()
470
+ kindManifestMap [gvk ] = append (kindManifestMap [gvk ], manifest )
471
+ }
472
+ if scanner .Err () != nil {
473
+ return scanner .Err ()
474
+ }
475
+ }
476
+ return nil
477
+ }
478
+
479
+ func getOwnedCRDs (kindManifestMap map [schema.GroupVersionKind ][][]byte ) (map [schema.GroupVersionKind ]struct {}, error ) {
480
+ ownedCRDs := map [schema.GroupVersionKind ]struct {}{}
481
+ for gvk , manifests := range kindManifestMap {
482
+ if gvk .Kind != "CustomResourceDefinition" {
483
+ continue
484
+ }
485
+ // Collect CRD kinds to filter them out from unsupported manifest types.
486
+ // The CRD version type doesn't matter as long as it has a group, kind,
487
+ // and versions in the expected fields.
488
+ for _ , manifest := range manifests {
489
+ crd := v1beta1.CustomResourceDefinition {}
490
+ if err := yaml .Unmarshal (manifest , & crd ); err != nil {
491
+ return ownedCRDs , err
492
+ }
493
+ for _ , ver := range crd .Spec .Versions {
494
+ crGVK := schema.GroupVersionKind {
495
+ Group : crd .Spec .Group ,
496
+ Version : ver .Name ,
497
+ Kind : crd .Spec .Names .Kind ,
498
+ }
499
+ ownedCRDs [crGVK ] = struct {}{}
500
+ }
501
+ }
502
+ }
503
+ return ownedCRDs , nil
504
+ }
0 commit comments