@@ -40,6 +40,9 @@ type nodeInformerController struct {
40
40
// sendInsight should be called to send produced insights to the update status controller
41
41
sendInsight sendInsightFn
42
42
43
+ // machineConfigPoolSelectorCache caches the label selectors converted from the node selectors of the machine config pools by their names.
44
+ machineConfigPoolSelectorCache machineConfigPoolSelectorCache
45
+
43
46
// machineConfigVersionCache caches machine config versions
44
47
// The cache stores the name of MC as the key and the release image version as its value which is retrieved from the annotation of the MC.
45
48
machineConfigVersionCache machineConfigVersionCache
@@ -106,13 +109,19 @@ func (c *nodeInformerController) sync(ctx context.Context, syncCtx factory.SyncC
106
109
return err
107
110
}
108
111
109
- pools , err := c .machineConfigPools . List (labels .Everything ( ))
110
- if err != nil {
111
- return err
112
+ mcpName := c .machineConfigPoolSelectorCache . whichMCP (labels .Set ( node . Labels ))
113
+ if mcpName == "" {
114
+ return fmt . Errorf ( "failed to determine which machine config pool the node %s belongs to" , node . Name )
112
115
}
113
- mcp , err := whichMCP (node , pools )
116
+ klog .V (4 ).Infof ("Node %s belongs to machine config pool %s" , node .Name , mcpName )
117
+
118
+ mcp , err := c .machineConfigPools .Get (mcpName )
114
119
if err != nil {
115
- return fmt .Errorf ("failed to determine which machine config pool the node belongs to: %w" , err )
120
+ if kerrors .IsNotFound (err ) {
121
+ // it will be another event if a MCP is deleted
122
+ return nil
123
+ }
124
+ return err
116
125
}
117
126
118
127
var mostRecentVersionInCVHistory string
@@ -152,7 +161,23 @@ func (c *nodeInformerController) sync(ctx context.Context, syncCtx factory.SyncC
152
161
}
153
162
return nil
154
163
case machineConfigPoolKindName :
155
- return c .reconcileAllNodes (syncCtx .Queue ())
164
+ machineConfigPool , err := c .machineConfigPools .Get (name )
165
+ if err != nil && ! kerrors .IsNotFound (err ) {
166
+ return err
167
+ }
168
+ if kerrors .IsNotFound (err ) {
169
+ // The pool was deleted
170
+ if changed := c .machineConfigPoolSelectorCache .forget (name ); changed {
171
+ klog .V (2 ).Infof ("Reconciling all nodes as machine config pool %q is deleted" , name )
172
+ return c .reconcileAllNodes (syncCtx .Queue ())
173
+ }
174
+ return nil
175
+ }
176
+ if changed := c .machineConfigPoolSelectorCache .ingest (machineConfigPool ); changed {
177
+ klog .V (2 ).Infof ("Reconciling all nodes as machine config pool %q is refreshed" , name )
178
+ return c .reconcileAllNodes (syncCtx .Queue ())
179
+ }
180
+ return nil
156
181
default :
157
182
return fmt .Errorf ("invalid queue key %s with unexpected type %s" , queueKey , t )
158
183
}
@@ -211,6 +236,73 @@ func (c *machineConfigVersionCache) match(config string) (string, bool) {
211
236
return v , ok
212
237
}
213
238
239
+ type machineConfigPoolSelectorCache struct {
240
+ cache map [string ]labels.Selector
241
+ lock sync.Mutex
242
+ }
243
+
244
+ func (c * machineConfigPoolSelectorCache ) whichMCP (labels labels.Labels ) string {
245
+ c .lock .Lock ()
246
+ defer c .lock .Unlock ()
247
+
248
+ if v , ok := c .cache [mco .MachineConfigPoolMaster ]; ok && v .Matches (labels ) {
249
+ return mco .MachineConfigPoolMaster
250
+ }
251
+
252
+ for k , v := range c .cache {
253
+ if k == mco .MachineConfigPoolMaster || k == mco .MachineConfigPoolWorker {
254
+ continue
255
+ }
256
+ if v .Matches (labels ) {
257
+ return k
258
+ }
259
+ }
260
+
261
+ if v , ok := c .cache [mco .MachineConfigPoolWorker ]; ok && v .Matches (labels ) {
262
+ return mco .MachineConfigPoolWorker
263
+ }
264
+
265
+ return ""
266
+ }
267
+
268
+ func (c * machineConfigPoolSelectorCache ) ingest (pool * machineconfigv1.MachineConfigPool ) bool {
269
+ c .lock .Lock ()
270
+ defer c .lock .Unlock ()
271
+
272
+ v , ok := c .cache [pool .Name ]
273
+ s , err := metav1 .LabelSelectorAsSelector (pool .Spec .NodeSelector )
274
+ if err != nil {
275
+ klog .Errorf ("Failed to convert to a label selector from the node selector of MachineConfigPool %s : %v" , pool .Name , err )
276
+ if ok {
277
+ delete (c .cache , pool .Name )
278
+ klog .V (4 ).Infof ("Deleted MachineConfigPool %s from the cache" , pool .Name )
279
+ return true
280
+ } else {
281
+ return false
282
+ }
283
+ }
284
+ if ! ok || v .String () != s .String () {
285
+ if c .cache == nil {
286
+ c .cache = make (map [string ]labels.Selector )
287
+ }
288
+ c .cache [pool .Name ] = s
289
+ klog .V (4 ).Infof ("Cached MachineConfigPool %s with selector %s" , pool .Name , s .String ())
290
+ return true
291
+ }
292
+ return false
293
+ }
294
+
295
+ func (c * machineConfigPoolSelectorCache ) forget (mcpName string ) bool {
296
+ c .lock .Lock ()
297
+ defer c .lock .Unlock ()
298
+ if _ , ok := c .cache [mcpName ]; ok {
299
+ delete (c .cache , mcpName )
300
+ klog .V (4 ).Infof ("Deleted MachineConfigPool %s from the cache" , mcpName )
301
+ return true
302
+ }
303
+ return false
304
+ }
305
+
214
306
func (c * nodeInformerController ) reconcileAllNodes (queue workqueue.TypedRateLimitingInterface [any ]) error {
215
307
nodes , err := c .nodes .List (labels .Everything ())
216
308
if err != nil {
@@ -235,41 +327,6 @@ func makeInsightMsgForNode(nodeInsight *updatestatus.NodeStatusInsight, acquired
235
327
return makeWorkerPoolsInsightMsg (insight , nodesInformerName )
236
328
}
237
329
238
- func whichMCP (node * corev1.Node , pools []* machineconfigv1.MachineConfigPool ) (* machineconfigv1.MachineConfigPool , error ) {
239
- var masterSelector labels.Selector
240
- var workerSelector labels.Selector
241
- customSelectors := map [string ]labels.Selector {}
242
- poolsMap := make (map [string ]* machineconfigv1.MachineConfigPool , len (pools ))
243
- for _ , pool := range pools {
244
- poolsMap [pool .Name ] = pool
245
- s , err := metav1 .LabelSelectorAsSelector (pool .Spec .NodeSelector )
246
- if err != nil {
247
- return nil , fmt .Errorf ("failed to get label selector from the pool %s: %w" , pool .Name , err )
248
- }
249
- switch pool .Name {
250
- case mco .MachineConfigPoolMaster :
251
- masterSelector = s
252
- case mco .MachineConfigPoolWorker :
253
- workerSelector = s
254
- default :
255
- customSelectors [pool .Name ] = s
256
- }
257
- }
258
-
259
- if masterSelector != nil && masterSelector .Matches (labels .Set (node .Labels )) {
260
- return poolsMap [mco .MachineConfigPoolMaster ], nil
261
- }
262
- for name , selector := range customSelectors {
263
- if selector .Matches (labels .Set (node .Labels )) {
264
- return poolsMap [name ], nil
265
- }
266
- }
267
- if workerSelector != nil && workerSelector .Matches (labels .Set (node .Labels )) {
268
- return poolsMap [mco .MachineConfigPoolWorker ], nil
269
- }
270
- return nil , fmt .Errorf ("failed to find a matching node selector from %d machine config pools" , len (pools ))
271
- }
272
-
273
330
func isNodeDegraded (node * corev1.Node ) bool {
274
331
// Inspired by: https://github.com/openshift/machine-config-operator/blob/master/pkg/controller/node/status.go
275
332
if node .Annotations == nil {
0 commit comments