@@ -18,6 +18,7 @@ package kubernetes
1818
1919import (
2020 "context"
21+ "encoding/json"
2122 "fmt"
2223 "os"
2324 "strings"
@@ -27,6 +28,7 @@ import (
2728 corev1 "k8s.io/api/core/v1"
2829 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2930 "k8s.io/apimachinery/pkg/labels"
31+ "k8s.io/apimachinery/pkg/types"
3032 "k8s.io/apimachinery/pkg/util/wait"
3133 "k8s.io/client-go/kubernetes"
3234 "k8s.io/client-go/tools/clientcmd"
@@ -95,25 +97,24 @@ func (c *Client) GetNodeLabelValue(nodeName, label string) (string, error) {
9597}
9698
9799// UpdateNodeLabels updates the labels on a Node given a Node name and a string map of label key-value pairs
100+ // This method uses a strategic merge patch to avoid conflicts with concurrent updates
98101func (c * Client ) UpdateNodeLabels (nodeName string , nodeLabels map [string ]string ) error {
99- // Get the node
100- node , err := c . clientset . CoreV1 (). Nodes (). Get ( c . ctx , nodeName , metav1. GetOptions {})
101- if err != nil {
102- return fmt . Errorf ( "failed to get node %s: %w" , nodeName , err )
102+ patch := map [ string ] interface {}{
103+ "metadata" : map [ string ] interface {}{
104+ "labels" : nodeLabels ,
105+ },
103106 }
104107
105- if node .Labels == nil {
106- node .Labels = make (map [string ]string )
107- }
108- for k , v := range nodeLabels {
109- node .Labels [k ] = v
108+ patchBytes , err := json .Marshal (patch )
109+ if err != nil {
110+ return fmt .Errorf ("failed to marshal patch: %w" , err )
110111 }
111112
112- // Update the node
113- _ , err = c .clientset .CoreV1 ().Nodes ().Update (c .ctx , node , metav1.UpdateOptions {})
113+ _ , err = c .clientset .CoreV1 ().Nodes ().Patch (c .ctx , nodeName , types .StrategicMergePatchType , patchBytes , metav1.PatchOptions {})
114114 if err != nil {
115- return fmt .Errorf ("failed to update labels of node %s: %w" , nodeName , err )
115+ return fmt .Errorf ("failed to update the labels of node %s: %w" , nodeName , err )
116116 }
117+
117118 return nil
118119}
119120
0 commit comments