@@ -486,14 +486,17 @@ func (c *controller) updateMachineStatusAndNodeCondition(ctx context.Context, ma
486486 return machineutils .ShortRetry , err
487487}
488488
489- // syncMachineNodeTemplate syncs nodeTemplates between machine and corresponding node-object.
490- // It ensures, that any nodeTemplate element available on Machine should be available on node-object.
489+ // syncNodeTemplates syncs nodeTemplates between machine, machineClass and corresponding node-object.
490+ // It ensures that any nodeTemplate element available on Machine should be available on node-object.
491+ // It ensures that MachineClass.NodeTemplate.VirtualCapacity is synced to the Node's Capacity.
491492// Although there could be more elements already available on node-object which will not be touched.
492- func (c * controller ) syncMachineNodeTemplates (ctx context.Context , machine * v1alpha1.Machine ) (machineutils.RetryPeriod , error ) {
493+ func (c * controller ) syncNodeTemplates (ctx context.Context , machine * v1alpha1.Machine , machineClass * v1alpha1. MachineClass ) (machineutils.RetryPeriod , error ) {
493494 var (
494- initializedNodeAnnotation bool
495- currentlyAppliedALTJSONByte []byte
496- lastAppliedALT v1alpha1.NodeTemplateSpec
495+ initializedNodeAnnotation bool
496+ currentlyAppliedALTJSONByte []byte
497+ lastAppliedALT v1alpha1.NodeTemplateSpec
498+ currentlyAppliedVirtualCapacityJSONByte []byte
499+ lastAppliedVirtualCapacity v1.ResourceList
497500 )
498501
499502 node , err := c .nodeLister .Get (getNodeName (machine ))
@@ -524,10 +527,30 @@ func (c *controller) syncMachineNodeTemplates(ctx context.Context, machine *v1al
524527 }
525528 }
526529
530+ lastAppliedVirtualCapacityJSONString , exists := node .Annotations [machineutils .LastAppliedVirtualCapacityAnnotation ]
531+ if exists {
532+ err = json .Unmarshal ([]byte (lastAppliedVirtualCapacityJSONString ), & lastAppliedVirtualCapacity )
533+ if err != nil {
534+ klog .Errorf ("Error occurred while syncing node virtual capacity: %s" , err )
535+ return machineutils .ShortRetry , err
536+ }
537+ }
538+
527539 annotationsChanged := SyncMachineAnnotations (machine , nodeCopy , lastAppliedALT .Annotations )
528540 labelsChanged := SyncMachineLabels (machine , nodeCopy , lastAppliedALT .Labels )
529541 taintsChanged := SyncMachineTaints (machine , nodeCopy , lastAppliedALT .Spec .Taints )
530542
543+ var virtualCapacityChanged bool
544+ var desiredVirtualCapacity v1.ResourceList
545+ if machineClass != nil && machineClass .NodeTemplate != nil {
546+ desiredVirtualCapacity = machineClass .NodeTemplate .VirtualCapacity
547+ virtualCapacityChanged = SyncVirtualCapacity (desiredVirtualCapacity , nodeCopy , lastAppliedVirtualCapacity )
548+ }
549+
550+ if ! initializedNodeAnnotation && ! annotationsChanged && ! labelsChanged && ! taintsChanged && ! virtualCapacityChanged {
551+ return machineutils .LongRetry , nil
552+ }
553+
531554 // Update node-object with latest nodeTemplate elements if elements have changed.
532555 if initializedNodeAnnotation || labelsChanged || annotationsChanged || taintsChanged {
533556
@@ -548,23 +571,44 @@ func (c *controller) syncMachineNodeTemplates(ctx context.Context, machine *v1al
548571 return machineutils .ShortRetry , err
549572 }
550573 nodeCopy .Annotations [machineutils .LastAppliedALTAnnotation ] = string (currentlyAppliedALTJSONByte )
574+ }
551575
552- _ , err := c .targetCoreClient .CoreV1 ().Nodes ().Update (ctx , nodeCopy , metav1.UpdateOptions {})
576+ if virtualCapacityChanged {
577+ klog .V (3 ).Infof ("virtualCapacity changed, attempting UpdateStatus for node.Status.Capacity of node %q to %v" , nodeCopy .Name , nodeCopy .Status .Capacity )
578+ // must patch the Node’s status subresource, because capacity lives under status
579+ nodeUpdated , err := c .targetCoreClient .CoreV1 ().Nodes ().UpdateStatus (ctx , nodeCopy , metav1.UpdateOptions {})
553580 if err != nil {
554- // Keep retrying until update goes through
555- klog .Errorf ("Updated failed for node object of machine %q. Retrying, error: %q" , machine .Name , err )
581+ klog .Errorf ("UpdateStatus failed for node %q of machine %q. error: %q" , node .Name , machine .Name , err )
582+ return machineutils .ShortRetry , err
583+ }
584+ klog .V (3 ).Infof ("node.Status.Capacity of node %q updated to: %v" , node .Name , nodeUpdated .Status .Capacity )
585+ currentlyAppliedVirtualCapacityJSONByte , err = json .Marshal (desiredVirtualCapacity )
586+ if err != nil {
587+ klog .Errorf ("Error occurred while syncing node virtual capacity of node %q: %v" , node .Name , err )
588+ return machineutils .ShortRetry , err
589+ }
590+ nodeCopy = nodeUpdated .DeepCopy ()
591+ if len (desiredVirtualCapacity ) == 0 {
592+ delete (nodeCopy .Annotations , machineutils .LastAppliedVirtualCapacityAnnotation )
556593 } else {
557- // Return error to continue in next reconcile
558- err = errSuccessfulALTsync
594+ nodeCopy .Annotations [machineutils .LastAppliedVirtualCapacityAnnotation ] = string (currentlyAppliedVirtualCapacityJSONByte )
559595 }
596+ }
560597
561- if apierrors .IsConflict (err ) {
562- return machineutils .ConflictRetry , err
563- }
564- return machineutils .ShortRetry , err
598+ _ , err = c .targetCoreClient .CoreV1 ().Nodes ().Update (ctx , nodeCopy , metav1.UpdateOptions {})
599+ if err != nil {
600+ // Keep retrying until update goes through
601+ klog .Errorf ("Updated failed for node object of machine %q. Retrying, error: %q" , machine .Name , err )
602+ } else {
603+ // Return error to continue in next reconcile
604+ err = errSuccessfulALTsync
565605 }
566606
567- return machineutils .LongRetry , nil
607+ if apierrors .IsConflict (err ) {
608+ return machineutils .ConflictRetry , err
609+ }
610+ return machineutils .ShortRetry , err
611+
568612}
569613
570614// SyncMachineAnnotations syncs the annotations of the machine with node-objects.
@@ -719,6 +763,37 @@ func SyncMachineTaints(
719763 return toBeUpdated
720764}
721765
766+ // SyncVirtualCapacity syncs the MachineClass.NodeTemplate.VirtualCapacity with the Node.Status.Capacity
767+ // It returns true if update is needed else false.
768+ func SyncVirtualCapacity (desiredVirtualCapacity v1.ResourceList , node * v1.Node , lastAppliedVirtualCapacity v1.ResourceList ) bool {
769+ toBeUpdated := false
770+
771+ if node .Status .Capacity == nil {
772+ node .Status .Capacity = v1.ResourceList {}
773+ }
774+ if desiredVirtualCapacity == nil {
775+ desiredVirtualCapacity = v1.ResourceList {}
776+ }
777+
778+ // Delete any keys that existed in the past but has been deleted now
779+ for prevKey := range lastAppliedVirtualCapacity {
780+ if _ , exists := desiredVirtualCapacity [prevKey ]; ! exists {
781+ delete (node .Status .Capacity , prevKey )
782+ toBeUpdated = true
783+ }
784+ }
785+
786+ // Add/Update any key that doesn't exist or whose value as changed
787+ for targKey , targQuant := range desiredVirtualCapacity {
788+ if nodeQuant , exists := node .Status .Capacity [targKey ]; ! exists || ! nodeQuant .Equal (targQuant ) {
789+ node .Status .Capacity [targKey ] = targQuant
790+ toBeUpdated = true
791+ }
792+ }
793+
794+ return toBeUpdated
795+ }
796+
722797// machineCreateErrorHandler updates the machine status based on
723798// CreateMachineResponse and the error during the machine creation
724799func (c * controller ) machineCreateErrorHandler (ctx context.Context , machine * v1alpha1.Machine , createMachineResponse * driver.CreateMachineResponse , err error ) (machineutils.RetryPeriod , error ) {
0 commit comments