Commit 18ae1ba8 authored by Klaus Ma's avatar Klaus Ma

Handled taints on node in batch.

parent 90a45b2d
...@@ -18,7 +18,9 @@ go_test( ...@@ -18,7 +18,9 @@ go_test(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/api/install:go_default_library",
"//pkg/api/testapi:go_default_library", "//pkg/api/testapi:go_default_library",
"//pkg/controller/node/testutil:go_default_library",
"//pkg/securitycontext:go_default_library", "//pkg/securitycontext:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library", "//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
...@@ -32,6 +34,7 @@ go_test( ...@@ -32,6 +34,7 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library", "//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/fake:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library", "//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library", "//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/client-go/tools/record:go_default_library", "//vendor/k8s.io/client-go/tools/record:go_default_library",
......
...@@ -885,7 +885,12 @@ func (o ReplicaSetsBySizeNewer) Less(i, j int) bool { ...@@ -885,7 +885,12 @@ func (o ReplicaSetsBySizeNewer) Less(i, j int) bool {
return *(o[i].Spec.Replicas) > *(o[j].Spec.Replicas) return *(o[i].Spec.Replicas) > *(o[j].Spec.Replicas)
} }
func AddOrUpdateTaintOnNode(c clientset.Interface, nodeName string, taint *v1.Taint) error { // AddOrUpdateTaintOnNode add taints to the node. If taint was added into node, it'll issue API calls
// to update nodes; otherwise, no API calls. Return error if any.
func AddOrUpdateTaintOnNode(c clientset.Interface, nodeName string, taints ...*v1.Taint) error {
if len(taints) == 0 {
return nil
}
firstTry := true firstTry := true
return clientretry.RetryOnConflict(UpdateTaintBackoff, func() error { return clientretry.RetryOnConflict(UpdateTaintBackoff, func() error {
var err error var err error
...@@ -901,11 +906,20 @@ func AddOrUpdateTaintOnNode(c clientset.Interface, nodeName string, taint *v1.Ta ...@@ -901,11 +906,20 @@ func AddOrUpdateTaintOnNode(c clientset.Interface, nodeName string, taint *v1.Ta
if err != nil { if err != nil {
return err return err
} }
newNode, ok, err := taintutils.AddOrUpdateTaint(oldNode, taint)
if err != nil { var newNode *v1.Node
return fmt.Errorf("Failed to update taint annotation!") oldNodeCopy := oldNode
updated := false
for _, taint := range taints {
curNewNode, ok, err := taintutils.AddOrUpdateTaint(oldNodeCopy, taint)
if err != nil {
return fmt.Errorf("Failed to update taint of node!")
}
updated = updated || ok
newNode = curNewNode
oldNodeCopy = curNewNode
} }
if !ok { if !updated {
return nil return nil
} }
return PatchNodeTaints(c, nodeName, oldNode, newNode) return PatchNodeTaints(c, nodeName, oldNode, newNode)
...@@ -916,12 +930,15 @@ func AddOrUpdateTaintOnNode(c clientset.Interface, nodeName string, taint *v1.Ta ...@@ -916,12 +930,15 @@ func AddOrUpdateTaintOnNode(c clientset.Interface, nodeName string, taint *v1.Ta
// won't fail if target taint doesn't exist or has been removed. // won't fail if target taint doesn't exist or has been removed.
// If passed a node it'll check if there's anything to be done, if taint is not present it won't issue // If passed a node it'll check if there's anything to be done, if taint is not present it won't issue
// any API calls. // any API calls.
func RemoveTaintOffNode(c clientset.Interface, nodeName string, taint *v1.Taint, node *v1.Node) error { func RemoveTaintOffNode(c clientset.Interface, nodeName string, node *v1.Node, taints ...*v1.Taint) error {
if len(taints) == 0 {
return nil
}
// Short circuit for limiting amount of API calls. // Short circuit for limiting amount of API calls.
if node != nil { if node != nil {
match := false match := false
for i := range node.Spec.Taints { for _, taint := range taints {
if node.Spec.Taints[i].MatchTaint(taint) { if taintutils.TaintExists(node.Spec.Taints, taint) {
match = true match = true
break break
} }
...@@ -930,6 +947,7 @@ func RemoveTaintOffNode(c clientset.Interface, nodeName string, taint *v1.Taint, ...@@ -930,6 +947,7 @@ func RemoveTaintOffNode(c clientset.Interface, nodeName string, taint *v1.Taint,
return nil return nil
} }
} }
firstTry := true firstTry := true
return clientretry.RetryOnConflict(UpdateTaintBackoff, func() error { return clientretry.RetryOnConflict(UpdateTaintBackoff, func() error {
var err error var err error
...@@ -945,11 +963,20 @@ func RemoveTaintOffNode(c clientset.Interface, nodeName string, taint *v1.Taint, ...@@ -945,11 +963,20 @@ func RemoveTaintOffNode(c clientset.Interface, nodeName string, taint *v1.Taint,
if err != nil { if err != nil {
return err return err
} }
newNode, ok, err := taintutils.RemoveTaint(oldNode, taint)
if err != nil { var newNode *v1.Node
return fmt.Errorf("Failed to update taint annotation!") oldNodeCopy := oldNode
updated := false
for _, taint := range taints {
curNewNode, ok, err := taintutils.RemoveTaint(oldNodeCopy, taint)
if err != nil {
return fmt.Errorf("Failed to remove taint of node!")
}
updated = updated || ok
newNode = curNewNode
oldNodeCopy = curNewNode
} }
if !ok { if !updated {
return nil return nil
} }
return PatchNodeTaints(c, nodeName, oldNode, newNode) return PatchNodeTaints(c, nodeName, oldNode, newNode)
......
...@@ -303,7 +303,7 @@ func swapNodeControllerTaint(kubeClient clientset.Interface, taintToAdd, taintTo ...@@ -303,7 +303,7 @@ func swapNodeControllerTaint(kubeClient clientset.Interface, taintToAdd, taintTo
} }
glog.V(4).Infof("Added %v Taint to Node %v", taintToAdd, node.Name) glog.V(4).Infof("Added %v Taint to Node %v", taintToAdd, node.Name)
err = controller.RemoveTaintOffNode(kubeClient, node.Name, taintToRemove, node) err = controller.RemoveTaintOffNode(kubeClient, node.Name, node, taintToRemove)
if err != nil { if err != nil {
utilruntime.HandleError( utilruntime.HandleError(
fmt.Errorf( fmt.Errorf(
......
...@@ -1072,12 +1072,12 @@ func (nc *NodeController) markNodeForTainting(node *v1.Node) bool { ...@@ -1072,12 +1072,12 @@ func (nc *NodeController) markNodeForTainting(node *v1.Node) bool {
func (nc *NodeController) markNodeAsHealthy(node *v1.Node) (bool, error) { func (nc *NodeController) markNodeAsHealthy(node *v1.Node) (bool, error) {
nc.evictorLock.Lock() nc.evictorLock.Lock()
defer nc.evictorLock.Unlock() defer nc.evictorLock.Unlock()
err := controller.RemoveTaintOffNode(nc.kubeClient, node.Name, UnreachableTaintTemplate, node) err := controller.RemoveTaintOffNode(nc.kubeClient, node.Name, node, UnreachableTaintTemplate)
if err != nil { if err != nil {
glog.Errorf("Failed to remove taint from node %v: %v", node.Name, err) glog.Errorf("Failed to remove taint from node %v: %v", node.Name, err)
return false, err return false, err
} }
err = controller.RemoveTaintOffNode(nc.kubeClient, node.Name, NotReadyTaintTemplate, node) err = controller.RemoveTaintOffNode(nc.kubeClient, node.Name, node, NotReadyTaintTemplate)
if err != nil { if err != nil {
glog.Errorf("Failed to remove taint from node %v: %v", node.Name, err) glog.Errorf("Failed to remove taint from node %v: %v", node.Name, err)
return false, err return false, err
......
...@@ -2551,7 +2551,7 @@ func ExpectNodeHasLabel(c clientset.Interface, nodeName string, labelKey string, ...@@ -2551,7 +2551,7 @@ func ExpectNodeHasLabel(c clientset.Interface, nodeName string, labelKey string,
} }
func RemoveTaintOffNode(c clientset.Interface, nodeName string, taint v1.Taint) { func RemoveTaintOffNode(c clientset.Interface, nodeName string, taint v1.Taint) {
ExpectNoError(controller.RemoveTaintOffNode(c, nodeName, &taint, nil)) ExpectNoError(controller.RemoveTaintOffNode(c, nodeName, nil, &taint))
VerifyThatTaintIsGone(c, nodeName, &taint) VerifyThatTaintIsGone(c, nodeName, &taint)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment