@@ -28,7 +28,6 @@ import (
28
28
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29
29
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
30
30
kerrors "k8s.io/apimachinery/pkg/util/errors"
31
- "k8s.io/apimachinery/pkg/util/sets"
32
31
"k8s.io/apimachinery/pkg/util/wait"
33
32
"k8s.io/apiserver/pkg/storage/names"
34
33
"k8s.io/klog/v2"
@@ -43,6 +42,7 @@ import (
43
42
capierrors "sigs.k8s.io/cluster-api/errors"
44
43
expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
45
44
utilexp "sigs.k8s.io/cluster-api/exp/util"
45
+ "sigs.k8s.io/cluster-api/internal/util/ssa"
46
46
"sigs.k8s.io/cluster-api/util"
47
47
"sigs.k8s.io/cluster-api/util/annotations"
48
48
"sigs.k8s.io/cluster-api/util/conditions"
@@ -376,100 +376,63 @@ func (r *MachinePoolReconciler) reconcileMachines(ctx context.Context, mp *expv1
376
376
return err
377
377
}
378
378
379
- updatedMachines , err := r .createMachinesIfNotExists (ctx , mp , machineList .Items , infraMachineList .Items )
380
- if err != nil {
381
- return errors .Wrapf (err , "failed to create machines for MachinePool %q in namespace %q" , mp .Name , mp .Namespace )
382
- }
383
-
384
- if err := r .ensureInfraMachineOnwerRefs (ctx , updatedMachines , infraMachineList .Items ); err != nil {
379
+ if err := r .createOrUpdateMachines (ctx , mp , machineList .Items , infraMachineList .Items ); err != nil {
385
380
return errors .Wrapf (err , "failed to create machines for MachinePool %q in namespace %q" , mp .Name , mp .Namespace )
386
381
}
387
382
388
383
return nil
389
384
}
390
385
391
- // createMachinesIfNotExists creates a MachinePool Machine for each infraMachine if it doesn't already exist and sets the owner reference and infraRef.
392
- func (r * MachinePoolReconciler ) createMachinesIfNotExists (ctx context.Context , mp * expv1.MachinePool , machines []clusterv1.Machine , infraMachines []unstructured.Unstructured ) ([]clusterv1. Machine , error ) {
386
+ // createOrUpdateMachines creates a MachinePool Machine for each infraMachine if it doesn't already exist and sets the owner reference and infraRef.
387
+ func (r * MachinePoolReconciler ) createOrUpdateMachines (ctx context.Context , mp * expv1.MachinePool , machines []clusterv1.Machine , infraMachines []unstructured.Unstructured ) error {
393
388
log := ctrl .LoggerFrom (ctx )
394
389
395
390
// Construct a set of names of infraMachines that already have a Machine.
396
- infraRefNames := sets. Set [string ]{}
391
+ infraMachineToMachine := map [string ]clusterv1. Machine {}
397
392
for _ , machine := range machines {
398
393
infraRef := machine .Spec .InfrastructureRef
399
- infraRefNames . Insert ( infraRef .Name )
394
+ infraMachineToMachine [ infraRef .Name ] = machine
400
395
}
401
396
402
397
createdMachines := []clusterv1.Machine {}
403
398
var errs []error
404
399
for i := range infraMachines {
405
400
infraMachine := & infraMachines [i ]
406
- // If infraMachine already has a Machine, skip it.
407
- if infraRefNames .Has (infraMachine .GetName ()) {
408
- log .V (4 ).Info ("Machine already exists for infraMachine" , "infraMachine" , klog .KObj (infraMachine ))
409
- continue
410
- }
411
- // Otherwise create a new Machine for the infraMachine.
412
- log .Info ("Creating new Machine for infraMachine" , infraMachine .GroupVersionKind ().Kind , klog .KObj (infraMachine ))
413
- machine := getNewMachine (mp , infraMachine )
414
- if err := r .Client .Create (ctx , machine ); err != nil {
415
- errs = append (errs , errors .Wrapf (err , "failed to create new Machine for infraMachine %q in namespace %q" , infraMachine .GetName (), infraMachine .GetNamespace ()))
416
- continue
401
+ // If infraMachine already has a Machine, update it if needed.
402
+ if existingMachine , ok := infraMachineToMachine [infraMachine .GetName ()]; ok {
403
+ log .V (2 ).Info ("Patching existing Machine for infraMachine" , "infraMachine" , klog .KObj (infraMachine ), "machine" , klog .KObj (& existingMachine ))
404
+
405
+ desiredMachine := computeDesiredMachine (mp , infraMachine , & existingMachine )
406
+ if err := ssa .Patch (ctx , r .Client , MachinePoolControllerName , desiredMachine , ssa.WithCachingProxy {Cache : r .ssaCache , Original : & existingMachine }); err != nil {
407
+ log .Error (err , "failed to update Machine" , "Machine" , klog .KObj (desiredMachine ))
408
+ errs = append (errs , errors .Wrapf (err , "failed to update Machine %q" , klog .KObj (desiredMachine )))
409
+ }
410
+ } else {
411
+ // Otherwise create a new Machine for the infraMachine.
412
+ log .Info ("Creating new Machine for infraMachine" , "infraMachine" , klog .KObj (infraMachine ))
413
+ machine := computeDesiredMachine (mp , infraMachine , nil )
414
+
415
+ if err := r .Client .Create (ctx , machine ); err != nil {
416
+ errs = append (errs , errors .Wrapf (err , "failed to create new Machine for infraMachine %q in namespace %q" , infraMachine .GetName (), infraMachine .GetNamespace ()))
417
+ continue
418
+ }
419
+
420
+ createdMachines = append (createdMachines , * machine )
417
421
}
418
- createdMachines = append (createdMachines , * machine )
419
422
}
420
- machines = append (machines , createdMachines ... )
421
423
if err := r .waitForMachineCreation (ctx , createdMachines ); err != nil {
422
424
errs = append (errs , errors .Wrapf (err , "failed to wait for machines to be created" ))
423
425
}
424
426
if len (errs ) > 0 {
425
- return nil , kerrors .NewAggregate (errs )
426
- }
427
-
428
- return machines , nil
429
- }
430
-
431
- // ensureInfraMachineOnwerRefs sets the ownerReferences on the each infraMachine to its associated MachinePool Machine if it hasn't already been done.
432
- func (r * MachinePoolReconciler ) ensureInfraMachineOnwerRefs (ctx context.Context , updatedMachines []clusterv1.Machine , infraMachines []unstructured.Unstructured ) error {
433
- log := ctrl .LoggerFrom (ctx )
434
- infraMachineNameToMachine := make (map [string ]clusterv1.Machine )
435
- for _ , machine := range updatedMachines {
436
- infraRef := machine .Spec .InfrastructureRef
437
- infraMachineNameToMachine [infraRef .Name ] = machine
438
- }
439
-
440
- for i := range infraMachines {
441
- infraMachine := & infraMachines [i ]
442
- ownerRefs := infraMachine .GetOwnerReferences ()
443
-
444
- machine , ok := infraMachineNameToMachine [infraMachine .GetName ()]
445
- if ! ok {
446
- return errors .Errorf ("failed to patch ownerRef for infraMachine %q because no Machine has an infraRef pointing to it" , infraMachine .GetName ())
447
- }
448
- machineRef := metav1 .NewControllerRef (& machine , machine .GroupVersionKind ())
449
- if ! util .HasOwnerRef (ownerRefs , * machineRef ) {
450
- log .V (2 ).Info ("Setting ownerRef on infraMachine" , "infraMachine" , infraMachine .GetName (), "namespace" , infraMachine .GetNamespace (), "machine" , machine .GetName ())
451
-
452
- patchHelper , err := patch .NewHelper (infraMachine , r .Client )
453
- if err != nil {
454
- return errors .Wrapf (err , "failed to create patch helper for %s" , klog .KObj (infraMachine ))
455
- }
456
-
457
- ownerRefs = util .EnsureOwnerRef (ownerRefs , * machineRef )
458
- infraMachine .SetOwnerReferences (ownerRefs )
459
-
460
- if err := patchHelper .Patch (ctx , infraMachine ); err != nil {
461
- return errors .Wrapf (err , "failed to patch %s" , klog .KObj (infraMachine ))
462
- }
463
-
464
- log .V (4 ).Info ("Successfully set ownerRef on infraMachine" , "infraMachine" , infraMachine .GetName (), "namespace" , infraMachine .GetNamespace (), "machine" , machine .GetName ())
465
- }
427
+ return kerrors .NewAggregate (errs )
466
428
}
467
429
468
430
return nil
469
431
}
470
432
471
- // getNewMachine creates a new Machine object.
472
- func getNewMachine (mp * expv1.MachinePool , infraMachine * unstructured.Unstructured ) * clusterv1.Machine {
433
+ // computeDesiredMachine constructs the desired Machine for an infraMachine.
434
+ // If the Machine exists, it ensures the Machine always owned by the MachinePool.
435
+ func computeDesiredMachine (mp * expv1.MachinePool , infraMachine * unstructured.Unstructured , existingMachine * clusterv1.Machine ) * clusterv1.Machine {
473
436
infraRef := corev1.ObjectReference {
474
437
APIVersion : infraMachine .GetAPIVersion (),
475
438
Kind : infraMachine .GetKind (),
@@ -492,6 +455,11 @@ func getNewMachine(mp *expv1.MachinePool, infraMachine *unstructured.Unstructure
492
455
},
493
456
}
494
457
458
+ if existingMachine != nil {
459
+ machine .SetName (existingMachine .Name )
460
+ machine .SetUID (existingMachine .UID )
461
+ }
462
+
495
463
for k , v := range mp .Spec .Template .Annotations {
496
464
machine .Annotations [k ] = v
497
465
}
0 commit comments