4
4
"context"
5
5
"fmt"
6
6
"strings"
7
+ "sync"
7
8
"time"
8
9
9
10
corev1 "k8s.io/api/core/v1"
@@ -39,6 +40,10 @@ type nodeInformerController struct {
39
40
// sendInsight should be called to send produced insights to the update status controller
40
41
sendInsight sendInsightFn
41
42
43
+ // machineConfigVersionCache caches machine config versions
44
+ // 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
+ machineConfigVersionCache machineConfigVersionCache
46
+
42
47
// now is a function that returns the current time, used for testing
43
48
now func () metav1.Time
44
49
}
@@ -110,18 +115,6 @@ func (c *nodeInformerController) sync(ctx context.Context, syncCtx factory.SyncC
110
115
return fmt .Errorf ("failed to determine which machine config pool the node belongs to: %w" , err )
111
116
}
112
117
113
- machineConfigs , err := c .machineConfigs .List (labels .Everything ())
114
- if err != nil {
115
- return err
116
- }
117
-
118
- machineConfigVersions := map [string ]string {}
119
- for _ , mc := range machineConfigs {
120
- if openshiftVersion , ok := mc .Annotations [mco .ReleaseImageVersionAnnotationKey ]; ok && openshiftVersion != "" {
121
- machineConfigVersions [mc .Name ] = openshiftVersion
122
- }
123
- }
124
-
125
118
var mostRecentVersionInCVHistory string
126
119
clusterVersion , err := c .configClient .ConfigV1 ().ClusterVersions ().Get (ctx , "version" , metav1.GetOptions {})
127
120
if err != nil {
@@ -132,15 +125,32 @@ func (c *nodeInformerController) sync(ctx context.Context, syncCtx factory.SyncC
132
125
}
133
126
134
127
now := c .now ()
135
- if insight := assessNode (node , mcp , machineConfigVersions , mostRecentVersionInCVHistory , now ); insight != nil {
128
+ if insight := assessNode (node , mcp , c . machineConfigVersionCache . match , mostRecentVersionInCVHistory , now ); insight != nil {
136
129
msg , err = makeInsightMsgForNode (insight , now )
137
130
if err != nil {
138
131
klog .Errorf ("BUG: Could not create insight message: %v" , err )
139
132
return nil
140
133
}
141
134
}
142
135
case machineConfigKindName :
143
- return c .reconcileAllNodes (syncCtx .Queue ())
136
+ machineConfig , err := c .machineConfigs .Get (name )
137
+ if err != nil && ! kerrors .IsNotFound (err ) {
138
+ return err
139
+ }
140
+ if kerrors .IsNotFound (err ) {
141
+ // The machine config was deleted
142
+ if changed := c .machineConfigVersionCache .forget (name ); changed {
143
+
144
+ klog .V (2 ).Infof ("Reconciling all nodes as machine config %q is deleted" , name )
145
+ return c .reconcileAllNodes (syncCtx .Queue ())
146
+ }
147
+ return nil
148
+ }
149
+ if changed := c .machineConfigVersionCache .ingest (machineConfig ); changed {
150
+ klog .V (2 ).Infof ("Reconciling all nodes as machine config %q is refreshed" , name )
151
+ return c .reconcileAllNodes (syncCtx .Queue ())
152
+ }
153
+ return nil
144
154
case machineConfigPoolKindName :
145
155
return c .reconcileAllNodes (syncCtx .Queue ())
146
156
default :
@@ -155,6 +165,52 @@ func (c *nodeInformerController) sync(ctx context.Context, syncCtx factory.SyncC
155
165
return nil
156
166
}
157
167
168
+ type machineConfigVersionCache struct {
169
+ cache map [string ]string
170
+ lock sync.Mutex
171
+ }
172
+
173
+ func (c * machineConfigVersionCache ) ingest (mc * machineconfigv1.MachineConfig ) bool {
174
+ c .lock .Lock ()
175
+ defer c .lock .Unlock ()
176
+
177
+ v , ok := c .cache [mc .Name ]
178
+ if openshiftVersion , exist := mc .Annotations [mco .ReleaseImageVersionAnnotationKey ]; exist && openshiftVersion != "" {
179
+ if ! ok || v != openshiftVersion {
180
+ if c .cache == nil {
181
+ c .cache = make (map [string ]string )
182
+ }
183
+ c .cache [mc .Name ] = openshiftVersion
184
+ klog .V (4 ).Infof ("Cached MachineConfig %s with version %s" , mc .Name , openshiftVersion )
185
+ return true
186
+ }
187
+ } else if ok {
188
+ delete (c .cache , mc .Name )
189
+ klog .V (4 ).Infof ("Deleted MachineConfig %s from the cache as no version can be found" , mc .Name )
190
+ return true
191
+ }
192
+
193
+ return false
194
+ }
195
+
196
+ func (c * machineConfigVersionCache ) forget (name string ) bool {
197
+ c .lock .Lock ()
198
+ defer c .lock .Unlock ()
199
+ if _ , ok := c .cache [name ]; ok {
200
+ delete (c .cache , name )
201
+ klog .V (4 ).Infof ("Deleted MachineConfig %s from the cache" , name )
202
+ return true
203
+ }
204
+ return false
205
+ }
206
+
207
+ func (c * machineConfigVersionCache ) match (config string ) (string , bool ) {
208
+ c .lock .Lock ()
209
+ defer c .lock .Unlock ()
210
+ v , ok := c .cache [config ]
211
+ return v , ok
212
+ }
213
+
158
214
func (c * nodeInformerController ) reconcileAllNodes (queue workqueue.TypedRateLimitingInterface [any ]) error {
159
215
nodes , err := c .nodes .List (labels .Everything ())
160
216
if err != nil {
@@ -343,16 +399,16 @@ func toPointer(d time.Duration) *metav1.Duration {
343
399
return & v
344
400
}
345
401
346
- func assessNode (node * corev1.Node , mcp * machineconfigv1.MachineConfigPool , machineConfigVersions map [ string ] string , mostRecentVersionInCVHistory string , now metav1.Time ) * updatestatus.NodeStatusInsight {
402
+ func assessNode (node * corev1.Node , mcp * machineconfigv1.MachineConfigPool , machineConfigVersionMatcher func ( string ) ( string , bool ) , mostRecentVersionInCVHistory string , now metav1.Time ) * updatestatus.NodeStatusInsight {
347
403
if node == nil || mcp == nil {
348
404
return nil
349
405
}
350
406
351
407
desiredConfig , ok := node .Annotations [mco .DesiredMachineConfigAnnotationKey ]
352
408
noDesiredOnNode := ! ok
353
409
currentConfig := node .Annotations [mco .CurrentMachineConfigAnnotationKey ]
354
- currentVersion , foundCurrent := machineConfigVersions [ currentConfig ]
355
- desiredVersion , foundDesired := machineConfigVersions [ desiredConfig ]
410
+ currentVersion , foundCurrent := machineConfigVersionMatcher ( currentConfig )
411
+ desiredVersion , foundDesired := machineConfigVersionMatcher ( desiredConfig )
356
412
357
413
lns := mco .NewLayeredNodeState (node )
358
414
isUnavailable := lns .IsUnavailable (mcp )
0 commit comments