@@ -174,59 +174,60 @@ func (r *ReconcileMachineSet) Reconcile(ctx context.Context, request reconcile.R
174
174
}
175
175
176
176
if r .gate .Enabled (featuregate .Feature (openshiftfeatures .FeatureGateMachineAPIMigration )) {
177
- machineSetName := machineSet .GetName ()
178
- machineSetCopy := machineSet .DeepCopy ()
179
- // Check Status.AuthoritativeAPI. If it's not set to MachineAPI. Set the
180
- // paused condition true and return early.
181
- //
182
- // Once we have a webhook, we want to remove the check that the AuthoritativeAPI
183
- // field is populated.
184
- if machineSet .Status .AuthoritativeAPI != "" &&
185
- machineSet .Status .AuthoritativeAPI != machinev1 .MachineAuthorityMachineAPI {
186
- conditions .Set (machineSetCopy , conditions .TrueConditionWithReason (
187
- machine .PausedCondition ,
188
- machine .PausedConditionReason ,
189
- "The AuthoritativeAPI is set to %s" , string (machineSet .Status .AuthoritativeAPI ),
190
- ))
191
-
192
- _ , err := updateMachineSetStatus (r .Client , machineSet , machineSetCopy .Status )
193
- if err != nil && ! apierrors .IsNotFound (err ) {
194
- klog .Errorf ("%v: error updating status: %v" , machineSetName , err )
195
- return reconcile.Result {}, fmt .Errorf ("error updating status: %w" , err )
196
- } else if apierrors .IsNotFound (err ) {
197
- return reconcile.Result {}, nil
177
+ switch machineSet .Status .AuthoritativeAPI {
178
+ case "" :
179
+ // An empty .status.authoritativeAPI normally means the resource has not yet been reconciled
180
+ // by the migration controller, which has the responsibility for propagating .spec.authoritativeAPI to the status.
181
+ // Pause the resource and take no further action but return until that field is populated.
182
+ desiredCondition := conditions .TrueConditionWithReason (
183
+ machine .PausedCondition , machine .PausedConditionReason ,
184
+ "The AuthoritativeAPI status is not yet set" ,
185
+ )
186
+
187
+ if _ , err := r .ensureUpdatedPausedCondition (machineSet , desiredCondition ,
188
+ fmt .Sprintf ("%v: machine set .status.authoritativeAPI is not yet set, ensuring machine set is paused" , machineSet .Name )); err != nil {
189
+ return reconcile.Result {}, fmt .Errorf ("failed to ensure paused condition: %w" , err )
198
190
}
191
+ klog .Infof ("%v: machine set is paused, taking no further action" , machineSet .Name )
199
192
200
- klog .Infof ("%v: machine set is paused, taking no further action" , machineSetName )
201
193
return reconcile.Result {}, nil
202
- }
203
194
204
- var pausedFalseReason string
205
- if machineSet .Status .AuthoritativeAPI != "" {
206
- pausedFalseReason = fmt .Sprintf ("The AuthoritativeAPI is set to %s" , string (machineSet .Status .AuthoritativeAPI ))
207
- } else {
208
- pausedFalseReason = "The AuthoritativeAPI is not set"
209
- }
195
+ case machinev1 .MachineAuthorityClusterAPI , machinev1 .MachineAuthorityMigrating :
196
+ // In case .status.authoritativeAPI is set to machinev1.MachineAuthorityClusterAPI, machinev1.MachineAuthorityMigrating
197
+ // the resource should be paused and not reconciled further.
198
+ desiredCondition := conditions .TrueConditionWithReason (
199
+ machine .PausedCondition , machine .PausedConditionReason ,
200
+ "The AuthoritativeAPI status is set to '%s'" , string (machineSet .Status .AuthoritativeAPI ),
201
+ )
202
+
203
+ if _ , err := r .ensureUpdatedPausedCondition (machineSet , desiredCondition ,
204
+ fmt .Sprintf ("%v: machine set .status.authoritativeAPI is set to '%s', ensuring machine set is paused" , machineSet .Name , machineSet .Status .AuthoritativeAPI )); err != nil {
205
+ return reconcile.Result {}, fmt .Errorf ("failed to ensure paused condition: %w" , err )
206
+ }
210
207
211
- // Set the paused condition to false, continue reconciliation
212
- conditions .Set (machineSetCopy , conditions .FalseCondition (
213
- machine .PausedCondition ,
214
- machine .NotPausedConditionReason ,
215
- machinev1 .ConditionSeverityInfo ,
216
- "%s" ,
217
- pausedFalseReason ,
218
- ))
208
+ klog .Infof ("%v: machine set is paused, taking no further action" , machineSet .Name )
219
209
220
- var err error
221
- machineSet , err = updateMachineSetStatus (r .Client , machineSet , machineSetCopy .Status )
222
- if err != nil && ! apierrors .IsNotFound (err ) {
223
- klog .Errorf ("%v: error updating status: %v" , machineSetName , err )
224
- return reconcile.Result {}, fmt .Errorf ("error updating status: %w" , err )
225
- } else if apierrors .IsNotFound (err ) {
226
210
return reconcile.Result {}, nil
227
- }
228
211
229
- klog .Infof ("%v: setting paused to false and continuing reconcile" , machineSetName )
212
+ case machinev1 .MachineAuthorityMachineAPI :
213
+ // The authority is MachineAPI and the resource should not be paused.
214
+ desiredCondition := conditions .FalseCondition (
215
+ machine .PausedCondition , machine .NotPausedConditionReason , machinev1 .ConditionSeverityInfo , "%s" ,
216
+ fmt .Sprintf ("The AuthoritativeAPI status is set to '%s'" , string (machineSet .Status .AuthoritativeAPI )),
217
+ )
218
+
219
+ if updated , err := r .ensureUpdatedPausedCondition (machineSet , desiredCondition ,
220
+ fmt .Sprintf ("%v: machine set .status.authoritativeAPI is set to '%s', unpausing machine set" , machineSet .Name , machineSet .Status .AuthoritativeAPI )); err != nil {
221
+ return reconcile.Result {}, fmt .Errorf ("failed to ensure paused condition: %w" , err )
222
+ } else if updated {
223
+ klog .Infof ("%v: setting machine set paused condition to false" , machineSet .Name )
224
+ }
225
+
226
+ // Fallthrough and continue reconciliation.
227
+ default :
228
+ klog .Errorf ("%v: invalid .status.authoritativeAPI '%s'" , machineSet .Name , machineSet .Status .AuthoritativeAPI )
229
+ return reconcile.Result {}, nil // Do not return an error to avoid immediate requeue.
230
+ }
230
231
}
231
232
232
233
result , err := r .reconcile (ctx , machineSet )
@@ -329,6 +330,23 @@ func (r *ReconcileMachineSet) reconcile(ctx context.Context, machineSet *machine
329
330
return reconcile.Result {}, nil
330
331
}
331
332
333
+ // ensureUpdatedPausedCondition updates the paused condition if needed.
334
+ func (r * ReconcileMachineSet ) ensureUpdatedPausedCondition (ms * machinev1.MachineSet , desiredCondition * machinev1.Condition , logMessage string ) (bool , error ) {
335
+ newMs := ms .DeepCopy ()
336
+ if ! conditions .IsEquivalentTo (conditions .Get (ms , machine .PausedCondition ), desiredCondition ) {
337
+ klog .Info (logMessage )
338
+ conditions .Set (newMs , desiredCondition )
339
+ if _ , err := updateMachineSetStatus (r .Client , ms , newMs .Status ); err != nil {
340
+ klog .Errorf ("%v: error updating status: %v" , newMs .Name , err )
341
+ return false , fmt .Errorf ("error updating status for machine set %s: %w" , newMs .Name , err )
342
+ }
343
+
344
+ return true , nil
345
+ }
346
+
347
+ return false , nil
348
+ }
349
+
332
350
// syncReplicas essentially scales machine resources up and down.
333
351
func (r * ReconcileMachineSet ) syncReplicas (ms * machinev1.MachineSet , machines []* machinev1.Machine ) error {
334
352
if ms .Spec .Replicas == nil {
0 commit comments