4
4
"context"
5
5
"fmt"
6
6
"os"
7
+ "sync"
7
8
8
9
operatorv1 "github.com/openshift/api/operator/v1"
9
10
configv1informers "github.com/openshift/client-go/config/informers/externalversions"
@@ -16,8 +17,10 @@ import (
16
17
"github.com/openshift/library-go/pkg/operator/v1helpers"
17
18
batchv1 "k8s.io/api/batch/v1"
18
19
corev1 "k8s.io/api/core/v1"
20
+ "k8s.io/apimachinery/pkg/labels"
19
21
"k8s.io/client-go/dynamic"
20
22
"k8s.io/client-go/kubernetes"
23
+ corev1listers "k8s.io/client-go/listers/core/v1"
21
24
"k8s.io/client-go/tools/cache"
22
25
"k8s.io/klog/v2"
23
26
@@ -55,25 +58,47 @@ func HandleDualReplicaClusters(
55
58
runExternalEtcdSupportController (ctx , controllerContext , operatorClient , envVarGetter , kubeInformersForNamespaces , configInformers , networkInformer , controlPlaneNodeInformer , kubeClient )
56
59
runTnfResourceController (ctx , controllerContext , kubeClient , dynamicClient , operatorClient , kubeInformersForNamespaces )
57
60
58
- // we need node names for assigning auth jobs to specific nodes
61
+ controlPlaneNodeLister := corev1listers .NewNodeLister (controlPlaneNodeInformer .GetIndexer ())
62
+
63
+ // we need node names for assigning auth and after-setup jobs to specific nodes
64
+ var once sync.Once
59
65
klog .Infof ("watching for nodes..." )
60
66
_ , err := controlPlaneNodeInformer .AddEventHandler (cache.ResourceEventHandlerFuncs {
61
67
AddFunc : func (obj interface {}) {
62
68
node , ok := obj .(* corev1.Node )
63
69
if ! ok {
64
- klog .Warningf ("failed to convert node to Node %+v" , obj )
70
+ klog .Warningf ("failed to convert added object to Node %+v" , obj )
71
+ return
72
+ }
73
+ klog .Infof ("node added: %s" , node .GetName ())
74
+
75
+ // ensure we have both control plane nodes before creating jobs
76
+ nodeList , err := controlPlaneNodeLister .List (labels .Everything ())
77
+ if err != nil {
78
+ klog .Errorf ("failed to list control plane nodes while waiting to create TNF jobs: %v" , err )
79
+ return
65
80
}
66
- runTnfAuthJobController (ctx , node .GetName (), controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces )
67
- runTnfAfterSetupJobController (ctx , node .GetName (), controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces )
81
+ if len (nodeList ) != 2 {
82
+ klog .Info ("not starting TNF jobs yet, waiting for 2 control plane nodes to exist" )
83
+ return
84
+ }
85
+ // we can have 2 nodes on the first call of AddFunc already, ensure we create job controllers once only
86
+ once .Do (func () {
87
+ klog .Infof ("found 2 control plane nodes (%q, %q), creating TNF jobs" , nodeList [0 ].GetName (), nodeList [1 ].GetName ())
88
+ // the order of job creation does not matter, the jobs wait on each other as needed
89
+ for _ , node := range nodeList {
90
+ runTnfAuthJobController (ctx , node .GetName (), controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces )
91
+ runTnfAfterSetupJobController (ctx , node .GetName (), controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces )
92
+ }
93
+ runTnfSetupJobController (ctx , controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces )
94
+ })
68
95
},
69
96
})
70
97
if err != nil {
71
98
klog .Errorf ("failed to add eventhandler to control plane informer: %v" , err )
72
99
return false , err
73
100
}
74
101
75
- runTnfSetupJobController (ctx , controllerContext , operatorClient , kubeClient , kubeInformersForNamespaces )
76
-
77
102
return true , nil
78
103
}
79
104
0 commit comments