@@ -9,15 +9,19 @@ import (
9
9
"text/template"
10
10
11
11
"github.com/openshift/api/config"
12
+ configv1 "github.com/openshift/api/config/v1"
12
13
"github.com/openshift/library-go/pkg/manifest"
13
14
"github.com/pkg/errors"
15
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
14
16
"k8s.io/apimachinery/pkg/runtime/schema"
15
17
utilerrors "k8s.io/apimachinery/pkg/util/errors"
16
18
"k8s.io/apimachinery/pkg/util/sets"
19
+ "k8s.io/klog/v2"
20
+ "k8s.io/utils/ptr"
17
21
)
18
22
19
23
// Render renders critical manifests from /manifests to outputDir.
20
- func Render (outputDir , releaseImage , clusterProfile string ) error {
24
+ func Render (outputDir , releaseImage , featureGateManifestPath , clusterProfile string ) error {
21
25
var (
22
26
manifestsDir = filepath .Join (DefaultPayloadDir , CVOManifestDir )
23
27
releaseManifestsDir = filepath .Join (DefaultPayloadDir , ReleaseManifestDir )
@@ -31,6 +35,35 @@ func Render(outputDir, releaseImage, clusterProfile string) error {
31
35
}
32
36
)
33
37
38
+ var requiredFeatureSet * string
39
+ if featureGateManifestPath != "" {
40
+ manifests , err := manifest .ManifestsFromFiles ([]string {featureGateManifestPath })
41
+ if err != nil {
42
+ return fmt .Errorf ("loading FeatureGate manifest: %w" , err )
43
+ }
44
+ if len (manifests ) != 1 {
45
+ return fmt .Errorf ("FeatureGate manifest %s contains %d manifests, but expected only one" , featureGateManifestPath , len (manifests ))
46
+ }
47
+ featureGateManifest := manifests [0 ]
48
+ expectedGVK := schema.GroupVersionKind {Kind : "FeatureGate" , Version : configv1 .GroupVersion .Version , Group : config .GroupName }
49
+ if featureGateManifest .GVK != expectedGVK {
50
+ return fmt .Errorf ("FeatureGate manifest %s GroupVersionKind %v, but expected %v" , featureGateManifest .OriginalFilename , featureGateManifest .GVK , expectedGVK )
51
+ }
52
+ featureSet , found , err := unstructured .NestedString (featureGateManifest .Obj .Object , "spec" , "featureSet" )
53
+ if err != nil {
54
+ return fmt .Errorf ("%s spec.featureSet lookup was not a string: %w" , featureGateManifest .String (), err )
55
+ } else if found {
56
+ requiredFeatureSet = & featureSet
57
+ klog .Infof ("--feature-gate-manifest-path=%s results in feature set %q" , featureGateManifest .OriginalFilename , featureSet )
58
+ } else {
59
+ requiredFeatureSet = ptr.To [string ]("" )
60
+ klog .Infof ("--feature-gate-manifest-path=%s does not set spec.featureSet, using the default feature set" , featureGateManifest .OriginalFilename )
61
+ }
62
+ } else {
63
+ requiredFeatureSet = ptr.To [string ]("" )
64
+ klog .Info ("--feature-gate-manifest-path is unset, using the default feature set" )
65
+ }
66
+
34
67
tasks := []struct {
35
68
idir string
36
69
odir string
@@ -61,7 +94,7 @@ func Render(outputDir, releaseImage, clusterProfile string) error {
61
94
}}
62
95
var errs []error
63
96
for _ , task := range tasks {
64
- if err := renderDir (renderConfig , task .idir , task .odir , task .processTemplate , task .skipFiles , task .filterGroupKind ); err != nil {
97
+ if err := renderDir (renderConfig , task .idir , task .odir , requiredFeatureSet , & clusterProfile , task .processTemplate , task .skipFiles , task .filterGroupKind ); err != nil {
65
98
errs = append (errs , err )
66
99
}
67
100
}
@@ -73,7 +106,7 @@ func Render(outputDir, releaseImage, clusterProfile string) error {
73
106
return nil
74
107
}
75
108
76
- func renderDir (renderConfig manifestRenderConfig , idir , odir string , processTemplate bool , skipFiles sets.Set [string ], filterGroupKind sets.Set [schema.GroupKind ]) error {
109
+ func renderDir (renderConfig manifestRenderConfig , idir , odir string , requiredFeatureSet * string , clusterProfile * string , processTemplate bool , skipFiles sets.Set [string ], filterGroupKind sets.Set [schema.GroupKind ]) error {
77
110
if err := os .MkdirAll (odir , 0666 ); err != nil {
78
111
return err
79
112
}
@@ -97,6 +130,7 @@ func renderDir(renderConfig manifestRenderConfig, idir, odir string, processTemp
97
130
// CustomNoUpgrade, TechPreviewNoUpgrade and DevPreviewNoUpgrade may add features to manifests like the ClusterVersion CRD,
98
131
// but we do not need those features during bootstrap-render time. In those clusters, the production
99
132
// CVO will be along shortly to update the manifests and deliver the gated features.
133
+ // fixme: now that we have requiredFeatureSet, use it to do Manifest.Include() filtering here instead of making filename assumptions
100
134
continue
101
135
}
102
136
@@ -127,8 +161,13 @@ func renderDir(renderConfig manifestRenderConfig, idir, odir string, processTemp
127
161
128
162
filteredManifests := make ([]string , 0 , len (manifests ))
129
163
for _ , manifest := range manifests {
130
- if filterGroupKind .Has (manifest .GVK .GroupKind ()) {
164
+ if ! filterGroupKind .Has (manifest .GVK .GroupKind ()) {
165
+ klog .Infof ("excluding %s because we do not render that group/kind" , manifest .String ())
166
+ } else if err := manifest .Include (nil , requiredFeatureSet , clusterProfile , nil , nil ); err != nil {
167
+ klog .Infof ("excluding %s: %v" , manifest .String (), err )
168
+ } else {
131
169
filteredManifests = append (filteredManifests , string (manifest .Raw ))
170
+ klog .Infof ("including %s filtered by feature set %v and cluster profile %v" , manifest .String (), requiredFeatureSet , clusterProfile )
132
171
}
133
172
}
134
173
0 commit comments