From 75eb9b4434b57d0560ad96c973a430df8f9f8ef5 Mon Sep 17 00:00:00 2001 From: Klaus Ma Date: Thu, 11 May 2017 16:49:18 +0800 Subject: [PATCH] Checked node condition for DaemonSets when updating node. --- pkg/controller/daemon/daemoncontroller.go | 37 ++++++++++++++++++- .../daemon/daemoncontroller_test.go | 37 +++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/pkg/controller/daemon/daemoncontroller.go b/pkg/controller/daemon/daemoncontroller.go index 6054b15e38f..4cecb660329 100644 --- a/pkg/controller/daemon/daemoncontroller.go +++ b/pkg/controller/daemon/daemoncontroller.go @@ -426,13 +426,46 @@ func (dsc *DaemonSetsController) addNode(obj interface{}) { } } +// nodeInSameCondition returns true if all effective types ("Status" is true) equals; +// otherwise, returns false. +func nodeInSameCondition(old []v1.NodeCondition, cur []v1.NodeCondition) bool { + if len(old) == 0 && len(cur) == 0 { + return true + } + + c1map := map[v1.NodeConditionType]v1.ConditionStatus{} + for _, c := range old { + if c.Status == v1.ConditionTrue { + c1map[c.Type] = c.Status + } + } + + for _, c := range cur { + if c.Status != v1.ConditionTrue { + continue + } + + if _, found := c1map[c.Type]; !found { + return false + } + + delete(c1map, c.Type) + } + + return len(c1map) == 0 +} + func (dsc *DaemonSetsController) updateNode(old, cur interface{}) { oldNode := old.(*v1.Node) curNode := cur.(*v1.Node) - if reflect.DeepEqual(oldNode.Labels, curNode.Labels) && reflect.DeepEqual(oldNode.Spec.Taints, curNode.Spec.Taints) { - // If node labels and taints didn't change, we can ignore this update. + + if reflect.DeepEqual(oldNode.Labels, curNode.Labels) && + reflect.DeepEqual(oldNode.Spec.Taints, curNode.Spec.Taints) && + nodeInSameCondition(oldNode.Status.Conditions, curNode.Status.Conditions) { + // If node labels, taints and condition didn't change, we can ignore this update. return } + dsList, err := dsc.dsLister.List(labels.Everything()) if err != nil { glog.V(4).Infof("Error enqueueing daemon sets: %v", err) diff --git a/pkg/controller/daemon/daemoncontroller_test.go b/pkg/controller/daemon/daemoncontroller_test.go index d7ee241d448..b4703e0dd6c 100644 --- a/pkg/controller/daemon/daemoncontroller_test.go +++ b/pkg/controller/daemon/daemoncontroller_test.go @@ -1219,6 +1219,43 @@ func TestUpdateNode(t *testing.T) { ds: newDaemonSet("ds"), shouldEnqueue: true, }, + { + test: "Node conditions changed", + oldNode: func() *v1.Node { + node := newNode("node1", nil) + node.Status.Conditions = []v1.NodeCondition{ + {Type: v1.NodeOutOfDisk, Status: v1.ConditionTrue}, + } + return node + }(), + newNode: newNode("node1", nil), + ds: newDaemonSet("ds"), + shouldEnqueue: true, + }, + { + test: "Node conditions not changed", + oldNode: func() *v1.Node { + node := newNode("node1", nil) + node.Status.Conditions = []v1.NodeCondition{ + {Type: v1.NodeOutOfDisk, Status: v1.ConditionTrue}, + {Type: v1.NodeMemoryPressure, Status: v1.ConditionFalse}, + {Type: v1.NodeDiskPressure, Status: v1.ConditionFalse}, + {Type: v1.NodeNetworkUnavailable, Status: v1.ConditionFalse}, + {Type: v1.NodeInodePressure, Status: v1.ConditionFalse}, + } + return node + }(), + newNode: func() *v1.Node { + node := newNode("node1", nil) + node.Status.Conditions = []v1.NodeCondition{ + {Type: v1.NodeOutOfDisk, Status: v1.ConditionTrue}, + {Type: v1.NodeInodePressure, Status: v1.ConditionFalse}, + } + return node + }(), + ds: newDaemonSet("ds"), + shouldEnqueue: false, + }, } for _, c := range cases { manager, podControl, _ := newTestController()