@@ -4,10 +4,11 @@ import (
44 "bytes"
55 "context"
66 "fmt"
7- operatorv1informers "github.com/openshift/client-go/operator/informers/externalversions/operator/v1"
87 "os"
98 "sync"
109
10+ operatorv1informers "github.com/openshift/client-go/operator/informers/externalversions/operator/v1"
11+
1112 operatorv1 "github.com/openshift/api/operator/v1"
1213 configv1informers "github.com/openshift/client-go/config/informers/externalversions"
1314 v1 "github.com/openshift/client-go/config/informers/externalversions/config/v1"
@@ -69,6 +70,12 @@ func HandleDualReplicaClusters(ctx context.Context,
6970
7071 klog .Infof ("detected DualReplica topology" )
7172
73+ // We only set the CEO available status to false during the initial setup
74+ initialSetup , err := isInitialSetup (operatorClient )
75+ if err != nil {
76+ return false , fmt .Errorf ("could not determine if we are in the initial setup: %w" , err )
77+ }
78+
7279 runExternalEtcdSupportController (ctx , controllerContext , operatorClient , envVarGetter , kubeInformersForNamespaces ,
7380 configInformers , networkInformer , controlPlaneNodeInformer , etcdInformer , kubeClient )
7481 runTnfResourceController (ctx , controllerContext , kubeClient , dynamicClient , operatorClient , kubeInformersForNamespaces )
@@ -78,7 +85,7 @@ func HandleDualReplicaClusters(ctx context.Context,
7885 // we need node names for assigning auth and after-setup jobs to specific nodes
7986 var once sync.Once
8087 klog .Infof ("watching for nodes..." )
81- _ , err : = controlPlaneNodeInformer .AddEventHandler (cache.ResourceEventHandlerFuncs {
88+ _ , err = controlPlaneNodeInformer .AddEventHandler (cache.ResourceEventHandlerFuncs {
8289 AddFunc : func (obj interface {}) {
8390 node , ok := obj .(* corev1.Node )
8491 if ! ok {
@@ -102,11 +109,17 @@ func HandleDualReplicaClusters(ctx context.Context,
102109 klog .Infof ("found 2 control plane nodes (%q, %q), creating TNF jobs" , nodeList [0 ].GetName (), nodeList [1 ].GetName ())
103110 // the order of job creation does not matter, the jobs wait on each other as needed
104111 for _ , node := range nodeList {
105- runJobController (ctx , tools .JobTypeAuth , & node .Name , controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces )
106- runJobController (ctx , tools .JobTypeAfterSetup , & node .Name , controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces )
112+ runJobController (ctx , tools .JobTypeAuth , & node .Name , controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces , jobs .DefaultConditions )
113+ runJobController (ctx , tools .JobTypeAfterSetup , & node .Name , controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces , jobs .DefaultConditions )
114+ }
115+
116+ setupConditions := jobs .DefaultConditions
117+ if initialSetup {
118+ setupConditions = append (setupConditions , operatorv1 .OperatorStatusTypeAvailable )
107119 }
108- runJobController (ctx , tools .JobTypeSetup , nil , controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces )
109- runJobController (ctx , tools .JobTypeFencing , nil , controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces )
120+
121+ runJobController (ctx , tools .JobTypeSetup , nil , controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces , setupConditions )
122+ runJobController (ctx , tools .JobTypeFencing , nil , controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces , jobs .DefaultConditions )
110123 })
111124 },
112125 })
@@ -138,6 +151,20 @@ func HandleDualReplicaClusters(ctx context.Context,
138151 return true , nil
139152}
140153
154+ func isInitialSetup (operatorClient v1helpers.StaticPodOperatorClient ) (bool , error ) {
155+ // Detect if the cluster is already running in ExternalEtcd mode
156+ operatorSpec , _ , _ , err := operatorClient .GetStaticPodOperatorState ()
157+ if err != nil {
158+ return false , fmt .Errorf ("could not get operator spec: %w" , err )
159+ }
160+ externalEtcdMode , err := ceohelpers .IsExternalEtcdSupport (operatorSpec )
161+ if err != nil {
162+ return false , fmt .Errorf ("could not determine if useExternalEtcdSupport config override is set: %w" , err )
163+ }
164+
165+ return ! externalEtcdMode , nil
166+ }
167+
141168func isDualReplicaTopoly (ctx context.Context , featureGateAccessor featuregates.FeatureGateAccess , configInformers configv1informers.SharedInformerFactory ) (bool , error ) {
142169 if isDualReplicaTopology , err := ceohelpers .IsDualReplicaTopology (ctx , configInformers .Config ().V1 ().Infrastructures ().Lister ()); err != nil {
143170 return false , fmt .Errorf ("could not determine DualReplicaTopology, aborting controller start: %w" , err )
@@ -201,7 +228,7 @@ func runTnfResourceController(ctx context.Context, controllerContext *controller
201228 go tnfResourceController .Run (ctx , 1 )
202229}
203230
204- func runJobController (ctx context.Context , jobType tools.JobType , nodeName * string , controllerContext * controllercmd.ControllerContext , operatorClient v1helpers.StaticPodOperatorClient , kubeClient kubernetes.Interface , kubeInformersForNamespaces v1helpers.KubeInformersForNamespaces ) {
231+ func runJobController (ctx context.Context , jobType tools.JobType , nodeName * string , controllerContext * controllercmd.ControllerContext , operatorClient v1helpers.StaticPodOperatorClient , kubeClient kubernetes.Interface , kubeInformersForNamespaces v1helpers.KubeInformersForNamespaces , conditions [] string ) {
205232 nodeNameForLogs := "n/a"
206233 if nodeName != nil {
207234 nodeNameForLogs = * nodeName
@@ -214,6 +241,7 @@ func runJobController(ctx context.Context, jobType tools.JobType, nodeName *stri
214241 operatorClient ,
215242 kubeClient ,
216243 kubeInformersForNamespaces .InformersFor (operatorclient .TargetNamespace ).Batch ().V1 ().Jobs (),
244+ conditions ,
217245 []factory.Informer {},
218246 []jobs.JobHookFunc {
219247 func (_ * operatorv1.OperatorSpec , job * batchv1.Job ) error {
0 commit comments