@@ -18,6 +18,7 @@ package canary
1818
1919import (
2020 "context"
21+ "encoding/json"
2122 "fmt"
2223
2324 "go.uber.org/zap"
@@ -26,6 +27,7 @@ import (
2627 "k8s.io/apimachinery/pkg/api/errors"
2728 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2829 "k8s.io/apimachinery/pkg/runtime/schema"
30+ "k8s.io/apimachinery/pkg/types"
2931 "k8s.io/client-go/kubernetes"
3032 "k8s.io/client-go/util/retry"
3133
@@ -34,7 +36,7 @@ import (
3436)
3537
3638var (
37- daemonSetScaleDownNodeSelector = map [string ]string {"flagger.app/scale-to-zero" : "true" }
39+ daemonSetScaleDownNodeSelector = map [string ]interface {} {"flagger.app/scale-to-zero" : "true" }
3840)
3941
4042// DaemonSetController is managing the operations for Kubernetes DaemonSet kind
@@ -54,39 +56,35 @@ func (c *DaemonSetController) ScaleToZero(cd *flaggerv1.Canary) error {
5456 return fmt .Errorf ("daemonset %s.%s get query error: %w" , targetName , cd .Namespace , err )
5557 }
5658
57- daeCopy := dae .DeepCopy ()
58- daeCopy .Spec .Template .Spec .NodeSelector = make (map [string ]string ,
59- len (dae .Spec .Template .Spec .NodeSelector )+ len (daemonSetScaleDownNodeSelector ))
60- for k , v := range dae .Spec .Template .Spec .NodeSelector {
61- daeCopy .Spec .Template .Spec .NodeSelector [k ] = v
59+ patch , err := c .getNodeSelectorPatch (daemonSetScaleDownNodeSelector )
60+ if err == nil {
61+ _ , err = c .kubeClient .AppsV1 ().DaemonSets (dae .Namespace ).Patch (context .TODO (), dae .GetName (), types .StrategicMergePatchType , patch , metav1.PatchOptions {})
6262 }
6363
64- for k , v := range daemonSetScaleDownNodeSelector {
65- daeCopy .Spec .Template .Spec .NodeSelector [k ] = v
66- }
67-
68- _ , err = c .kubeClient .AppsV1 ().DaemonSets (dae .Namespace ).Update (context .TODO (), daeCopy , metav1.UpdateOptions {})
6964 if err != nil {
70- return fmt .Errorf ("updating daemonset %s.%s failed: %w" , daeCopy .GetName (), daeCopy .Namespace , err )
65+ return fmt .Errorf ("updating daemonset %s.%s failed: %w" , dae .GetName (), dae .Namespace , err )
7166 }
7267 return nil
7368}
7469
7570func (c * DaemonSetController ) ScaleFromZero (cd * flaggerv1.Canary ) error {
7671 targetName := cd .Spec .TargetRef .Name
77- dep , err := c .kubeClient .AppsV1 ().DaemonSets (cd .Namespace ).Get (context .TODO (), targetName , metav1.GetOptions {})
72+ dae , err := c .kubeClient .AppsV1 ().DaemonSets (cd .Namespace ).Get (context .TODO (), targetName , metav1.GetOptions {})
7873 if err != nil {
7974 return fmt .Errorf ("daemonset %s.%s query error: %w" , targetName , cd .Namespace , err )
8075 }
8176
82- depCopy := dep . DeepCopy ()
77+ nodeSelector := map [ string ] interface {}{}
8378 for k := range daemonSetScaleDownNodeSelector {
84- delete (depCopy .Spec .Template .Spec .NodeSelector , k )
79+ nodeSelector [k ] = nil
80+ }
81+ patch , err := c .getNodeSelectorPatch (nodeSelector )
82+ if err == nil {
83+ _ , err = c .kubeClient .AppsV1 ().DaemonSets (dae .Namespace ).Patch (context .TODO (), dae .GetName (), types .StrategicMergePatchType , patch , metav1.PatchOptions {})
8584 }
8685
87- _ , err = c .kubeClient .AppsV1 ().DaemonSets (dep .Namespace ).Update (context .TODO (), depCopy , metav1.UpdateOptions {})
8886 if err != nil {
89- return fmt .Errorf ("scaling up daemonset %s.%s failed: %w" , depCopy .GetName (), depCopy .Namespace , err )
87+ return fmt .Errorf ("scaling up daemonset %s.%s failed: %w" , dae .GetName (), dae .Namespace , err )
9088 }
9189 return nil
9290}
@@ -324,6 +322,16 @@ func (c *DaemonSetController) getSelectorLabel(daemonSet *appsv1.DaemonSet) (str
324322 )
325323}
326324
325+ // createNodeSelectorPatch returns the nodeSelector field strategic patch used for scaling
326+ func (c * DaemonSetController ) getNodeSelectorPatch (nodeSelector map [string ]interface {}) ([]byte , error ) {
327+ nodeSelectorJSON , err := json .Marshal (nodeSelector )
328+ if err != nil {
329+ return nil , err
330+ }
331+ patch := []byte (fmt .Sprintf (`{"spec":{"template":{"spec":{"nodeSelector":%s}}}}` , nodeSelectorJSON ))
332+ return patch , nil
333+ }
334+
327335func (c * DaemonSetController ) HaveDependenciesChanged (cd * flaggerv1.Canary ) (bool , error ) {
328336 return c .configTracker .HasConfigChanged (cd )
329337}
0 commit comments