@@ -35,7 +35,6 @@ import (
35
35
configv1 "github.com/openshift/api/config/v1"
36
36
clientset "github.com/openshift/client-go/config/clientset/versioned"
37
37
configinformers "github.com/openshift/client-go/config/informers/externalversions"
38
- configlistersv1 "github.com/openshift/client-go/config/listers/config/v1"
39
38
operatorclientset "github.com/openshift/client-go/operator/clientset/versioned"
40
39
operatorinformers "github.com/openshift/client-go/operator/informers/externalversions"
41
40
"github.com/openshift/library-go/pkg/config/clusterstatus"
@@ -190,13 +189,13 @@ func (o *Options) Run(ctx context.Context) error {
190
189
}
191
190
192
191
clusterVersionConfigInformerFactory , configInformerFactory := o .prepareConfigInformerFactories (cb )
193
- _ , _ , err = o .processInitialFeatureGate (ctx , configInformerFactory )
192
+ startingFeatureSet , startingCvoGates , err : = o .processInitialFeatureGate (ctx , configInformerFactory )
194
193
if err != nil {
195
194
return fmt .Errorf ("error processing feature gates: %w" , err )
196
195
}
197
196
198
197
// initialize the controllers and attempt to load the payload information
199
- controllerCtx , err := o .NewControllerContext (cb , clusterVersionConfigInformerFactory , configInformerFactory )
198
+ controllerCtx , err := o .NewControllerContext (cb , startingFeatureSet , startingCvoGates , clusterVersionConfigInformerFactory , configInformerFactory )
200
199
if err != nil {
201
200
return err
202
201
}
@@ -244,7 +243,7 @@ func (o *Options) getOpenShiftVersion() string {
244
243
return releaseMetadata .Version
245
244
}
246
245
247
- func (o * Options ) processInitialFeatureGate (ctx context.Context , configInformerFactory configinformers.SharedInformerFactory ) (configv1.FeatureSet , * featuregates.CvoGates , error ) {
246
+ func (o * Options ) processInitialFeatureGate (ctx context.Context , configInformerFactory configinformers.SharedInformerFactory ) (configv1.FeatureSet , featuregates.CvoGates , error ) {
248
247
featureGates := configInformerFactory .Config ().V1 ().FeatureGates ().Lister ()
249
248
configInformerFactory .Start (ctx .Done ())
250
249
configInformerFactory .WaitForCacheSync (ctx .Done ())
@@ -256,8 +255,8 @@ func (o *Options) processInitialFeatureGate(ctx context.Context, configInformerF
256
255
var clusterFeatureGate * configv1.FeatureGate
257
256
258
257
// client-go automatically retries some network blip errors on GETs for 30s by default, and we want to
259
- // retry the remaining ones ourselves. If we fail longer than that, the operator won't be able to do work
260
- // anyway. Return the error and crashloop.
258
+ // retry the remaining ones ourselves. If we fail longer than that, CVO won't be able to do work anyway.
259
+ // Return the error and crashloop.
261
260
//
262
261
// We implement the timeout with a context because the timeout in PollImmediateWithContext does not behave
263
262
// well when ConditionFunc takes longer time to execute, like here where the GET can be retried by client-go
@@ -284,17 +283,17 @@ func (o *Options) processInitialFeatureGate(ctx context.Context, configInformerF
284
283
}
285
284
}); err != nil {
286
285
if lastError != nil {
287
- return "" , nil , lastError
286
+ return "" , cvoGates , lastError
288
287
}
289
- return "" , nil , err
288
+ return "" , cvoGates , err
290
289
}
291
290
292
291
if cvoGates .UnknownVersion () {
293
292
klog .Warningf ("CVO features for version %s could not be detected from FeatureGate; will use defaults plus special UnknownVersion feature gate" , cvoOpenShiftVersion )
294
293
}
295
294
klog .Infof ("CVO features for version %s enabled at startup: %+v" , cvoOpenShiftVersion , cvoGates )
296
295
297
- return startingFeatureSet , & cvoGates , nil
296
+ return startingFeatureSet , cvoGates , nil
298
297
}
299
298
300
299
// run launches a number of goroutines to handle manifest application,
@@ -362,7 +361,7 @@ func (o *Options) run(ctx context.Context, controllerCtx *Context, lock resource
362
361
resultChannel <- asyncResult {name : "metrics server" , error : err }
363
362
}()
364
363
}
365
- if err := controllerCtx .InitializeFromPayload (runContext , restConfig , burstRestConfig ); err != nil {
364
+ if err := controllerCtx .CVO . InitializeFromPayload (runContext , restConfig , burstRestConfig ); err != nil {
366
365
if firstError == nil {
367
366
firstError = err
368
367
}
@@ -577,13 +576,17 @@ type Context struct {
577
576
// OperatorInformerFactory should be used to get informers / listers for code that works with resources from the
578
577
// operator.openshift.io group
579
578
OperatorInformerFactory operatorinformers.SharedInformerFactory
580
-
581
- fgLister configlistersv1.FeatureGateLister
582
579
}
583
580
584
581
// NewControllerContext initializes the default Context for the current Options. It does
585
582
// not start any background processes.
586
- func (o * Options ) NewControllerContext (cb * ClientBuilder , clusterVersionConfigInformerFactory , configInformerFactory configinformers.SharedInformerFactory ) (* Context , error ) {
583
+ func (o * Options ) NewControllerContext (
584
+ cb * ClientBuilder ,
585
+ startingFeatureSet configv1.FeatureSet ,
586
+ startingCvoGates featuregates.CvoGates ,
587
+ clusterVersionConfigInformerFactory ,
588
+ configInformerFactory configinformers.SharedInformerFactory ,
589
+ ) (* Context , error ) {
587
590
kubeClient := cb .KubeClientOrDie (internal .ConfigNamespace , useProtobuf )
588
591
openshiftConfigInformerFactory := coreinformers .NewSharedInformerFactoryWithOptions (kubeClient , resyncPeriod (o .ResyncInterval ), coreinformers .WithNamespace (internal .ConfigNamespace ))
589
592
openshiftConfigManagedInformerFactory := coreinformers .NewSharedInformerFactoryWithOptions (kubeClient , resyncPeriod (o .ResyncInterval ), coreinformers .WithNamespace (internal .ConfigManagedNamespace ))
@@ -621,12 +624,14 @@ func (o *Options) NewControllerContext(cb *ClientBuilder, clusterVersionConfigIn
621
624
o .InjectClusterIdIntoPromQL ,
622
625
o .UpdateService ,
623
626
stringsToCapabilities (o .AlwaysEnableCapabilities ),
627
+ startingFeatureSet ,
628
+ startingCvoGates ,
624
629
)
625
630
if err != nil {
626
631
return nil , err
627
632
}
628
633
629
- featureChangeStopper , err := featuregates .NewChangeStopper (configInformerFactory .Config ().V1 ().FeatureGates ())
634
+ featureChangeStopper , err := featuregates .NewChangeStopper (configInformerFactory .Config ().V1 ().FeatureGates (), startingFeatureSet , startingCvoGates )
630
635
if err != nil {
631
636
return nil , err
632
637
}
@@ -639,8 +644,6 @@ func (o *Options) NewControllerContext(cb *ClientBuilder, clusterVersionConfigIn
639
644
OperatorInformerFactory : operatorInformerFactory ,
640
645
CVO : cvo ,
641
646
StopOnFeatureGateChange : featureChangeStopper ,
642
-
643
- fgLister : configInformerFactory .Config ().V1 ().FeatureGates ().Lister (),
644
647
}
645
648
646
649
if o .EnableAutoUpdate {
@@ -663,70 +666,6 @@ func (o *Options) NewControllerContext(cb *ClientBuilder, clusterVersionConfigIn
663
666
return ctx , nil
664
667
}
665
668
666
- // InitializeFromPayload initializes the CVO and FeatureGate ChangeStoppers controllers from the payload. It extracts the
667
- // current CVO version from the initial payload and uses it to determine the initial the required featureset and enabled
668
- // feature gates. Both the payload and determined feature information are used to initialize CVO and feature gate
669
- // ChangeStopper controllers.
670
- func (c * Context ) InitializeFromPayload (ctx context.Context , restConfig * rest.Config , burstRestConfig * rest.Config ) error {
671
- var startingFeatureSet configv1.FeatureSet
672
- var clusterFeatureGate * configv1.FeatureGate
673
-
674
- // client-go automatically retries some network blip errors on GETs for 30s by default, and we want to
675
- // retry the remaining ones ourselves. If we fail longer than that, the operator won't be able to do work
676
- // anyway. Return the error and crashloop.
677
- //
678
- // We implement the timeout with a context because the timeout in PollImmediateWithContext does not behave
679
- // well when ConditionFunc takes longer time to execute, like here where the GET can be retried by client-go
680
- var lastError error
681
- if err := wait .PollUntilContextTimeout (context .Background (), 2 * time .Second , 25 * time .Second , true , func (ctx context.Context ) (bool , error ) {
682
- gate , fgErr := c .fgLister .Get ("cluster" )
683
- switch {
684
- case apierrors .IsNotFound (fgErr ):
685
- // if we have no featuregates, then the cluster is using the default featureset, which is "".
686
- // This excludes everything that could possibly depend on a different feature set.
687
- startingFeatureSet = ""
688
- klog .Infof ("FeatureGate not found in cluster, using default feature set %q at startup" , startingFeatureSet )
689
- return true , nil
690
- case fgErr != nil :
691
- lastError = fgErr
692
- klog .Warningf ("Failed to get FeatureGate from cluster: %v" , fgErr )
693
- return false , nil
694
- default :
695
- clusterFeatureGate = gate
696
- startingFeatureSet = gate .Spec .FeatureSet
697
- klog .Infof ("FeatureGate found in cluster, using its feature set %q at startup" , startingFeatureSet )
698
- return true , nil
699
- }
700
- }); err != nil {
701
- if lastError != nil {
702
- return lastError
703
- }
704
- return err
705
- }
706
-
707
- payload , err := c .CVO .LoadInitialPayload (ctx , startingFeatureSet , restConfig )
708
- if err != nil {
709
- return err
710
- }
711
-
712
- var cvoGates featuregates.CvoGates
713
- if clusterFeatureGate != nil {
714
- cvoGates = featuregates .CvoGatesFromFeatureGate (clusterFeatureGate , payload .Release .Version )
715
- } else {
716
- cvoGates = featuregates .DefaultCvoGates (payload .Release .Version )
717
- }
718
-
719
- if cvoGates .UnknownVersion () {
720
- klog .Infof ("CVO features for version %s could not be detected from FeatureGate; will use defaults plus special UnknownVersion feature gate" , payload .Release .Version )
721
- }
722
- klog .Infof ("CVO features for version %s enabled at startup: %+v" , payload .Release .Version , cvoGates )
723
-
724
- c .StopOnFeatureGateChange .SetStartingFeatures (startingFeatureSet , cvoGates )
725
- c .CVO .InitializeFromPayload (payload , startingFeatureSet , cvoGates , restConfig , burstRestConfig )
726
-
727
- return nil
728
- }
729
-
730
669
func stringsToCapabilities (names []string ) []configv1.ClusterVersionCapability {
731
670
caps := make ([]configv1.ClusterVersionCapability , len (names ))
732
671
for i , c := range names {
0 commit comments