Merge branch 'master' of github.com:kubernetes/kubernetes into branch1
This commit is contained in:
@@ -18,7 +18,9 @@ go_test(
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/install:go_default_library",
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/controller/testutil:go_default_library",
|
||||
"//pkg/securitycontext:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
@@ -32,6 +34,7 @@ go_test(
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets: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/fake: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/record:go_default_library",
|
||||
@@ -125,6 +128,7 @@ filegroup(
|
||||
"//pkg/controller/service:all-srcs",
|
||||
"//pkg/controller/serviceaccount:all-srcs",
|
||||
"//pkg/controller/statefulset:all-srcs",
|
||||
"//pkg/controller/testutil:all-srcs",
|
||||
"//pkg/controller/ttl:all-srcs",
|
||||
"//pkg/controller/volume/attachdetach:all-srcs",
|
||||
"//pkg/controller/volume/events:all-srcs",
|
||||
|
@@ -43,7 +43,7 @@ go_test(
|
||||
"//pkg/cloudprovider:go_default_library",
|
||||
"//pkg/cloudprovider/providers/fake:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/node/testutil:go_default_library",
|
||||
"//pkg/controller/testutil:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//plugin/pkg/scheduler/algorithm:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
|
@@ -34,7 +34,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
fakecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/fake"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/node/testutil"
|
||||
"k8s.io/kubernetes/pkg/controller/testutil"
|
||||
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
||||
"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm"
|
||||
)
|
||||
|
@@ -885,50 +885,11 @@ func (o ReplicaSetsBySizeNewer) Less(i, j int) bool {
|
||||
return *(o[i].Spec.Replicas) > *(o[j].Spec.Replicas)
|
||||
}
|
||||
|
||||
func AddOrUpdateTaintOnNode(c clientset.Interface, nodeName string, taint *v1.Taint) error {
|
||||
firstTry := true
|
||||
return clientretry.RetryOnConflict(UpdateTaintBackoff, func() error {
|
||||
var err error
|
||||
var oldNode *v1.Node
|
||||
// First we try getting node from the API server cache, as it's cheaper. If it fails
|
||||
// we get it from etcd to be sure to have fresh data.
|
||||
if firstTry {
|
||||
oldNode, err = c.Core().Nodes().Get(nodeName, metav1.GetOptions{ResourceVersion: "0"})
|
||||
firstTry = false
|
||||
} else {
|
||||
oldNode, err = c.Core().Nodes().Get(nodeName, metav1.GetOptions{})
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newNode, ok, err := taintutils.AddOrUpdateTaint(oldNode, taint)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to update taint annotation!")
|
||||
}
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return PatchNodeTaints(c, nodeName, oldNode, newNode)
|
||||
})
|
||||
}
|
||||
|
||||
// RemoveTaintOffNode is for cleaning up taints temporarily added to node,
|
||||
// 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
|
||||
// any API calls.
|
||||
func RemoveTaintOffNode(c clientset.Interface, nodeName string, taint *v1.Taint, node *v1.Node) error {
|
||||
// Short circuit for limiting amount of API calls.
|
||||
if node != nil {
|
||||
match := false
|
||||
for i := range node.Spec.Taints {
|
||||
if node.Spec.Taints[i].MatchTaint(taint) {
|
||||
match = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !match {
|
||||
return nil
|
||||
}
|
||||
// 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
|
||||
return clientretry.RetryOnConflict(UpdateTaintBackoff, func() error {
|
||||
@@ -945,11 +906,77 @@ func RemoveTaintOffNode(c clientset.Interface, nodeName string, taint *v1.Taint,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newNode, ok, err := taintutils.RemoveTaint(oldNode, taint)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to update taint annotation!")
|
||||
|
||||
var newNode *v1.Node
|
||||
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 PatchNodeTaints(c, nodeName, oldNode, newNode)
|
||||
})
|
||||
}
|
||||
|
||||
// RemoveTaintOffNode is for cleaning up taints temporarily added to node,
|
||||
// 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
|
||||
// any API calls.
|
||||
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.
|
||||
if node != nil {
|
||||
match := false
|
||||
for _, taint := range taints {
|
||||
if taintutils.TaintExists(node.Spec.Taints, taint) {
|
||||
match = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !match {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
firstTry := true
|
||||
return clientretry.RetryOnConflict(UpdateTaintBackoff, func() error {
|
||||
var err error
|
||||
var oldNode *v1.Node
|
||||
// First we try getting node from the API server cache, as it's cheaper. If it fails
|
||||
// we get it from etcd to be sure to have fresh data.
|
||||
if firstTry {
|
||||
oldNode, err = c.Core().Nodes().Get(nodeName, metav1.GetOptions{ResourceVersion: "0"})
|
||||
firstTry = false
|
||||
} else {
|
||||
oldNode, err = c.Core().Nodes().Get(nodeName, metav1.GetOptions{})
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var newNode *v1.Node
|
||||
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 !updated {
|
||||
return nil
|
||||
}
|
||||
return PatchNodeTaints(c, nodeName, oldNode, newNode)
|
||||
|
@@ -37,12 +37,15 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
utiltesting "k8s.io/client-go/util/testing"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
_ "k8s.io/kubernetes/pkg/api/install"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/controller/testutil"
|
||||
"k8s.io/kubernetes/pkg/securitycontext"
|
||||
)
|
||||
|
||||
@@ -479,3 +482,358 @@ func TestComputeHash(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveTaintOffNode(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
nodeHandler *testutil.FakeNodeHandler
|
||||
nodeName string
|
||||
taintsToRemove []*v1.Taint
|
||||
expectedTaints []v1.Taint
|
||||
requestCount int
|
||||
}{
|
||||
{
|
||||
name: "remove one taint from node",
|
||||
nodeHandler: &testutil.FakeNodeHandler{
|
||||
Existing: []*v1.Node{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
},
|
||||
Spec: v1.NodeSpec{
|
||||
Taints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Clientset: fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}),
|
||||
},
|
||||
nodeName: "node1",
|
||||
taintsToRemove: []*v1.Taint{
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
expectedTaints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
},
|
||||
requestCount: 4,
|
||||
},
|
||||
{
|
||||
name: "remove multiple taints from node",
|
||||
nodeHandler: &testutil.FakeNodeHandler{
|
||||
Existing: []*v1.Node{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
},
|
||||
Spec: v1.NodeSpec{
|
||||
Taints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
{Key: "key3", Value: "value3", Effect: "NoSchedule"},
|
||||
{Key: "key4", Value: "value4", Effect: "NoExecute"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Clientset: fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}),
|
||||
},
|
||||
nodeName: "node1",
|
||||
taintsToRemove: []*v1.Taint{
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
{Key: "key3", Value: "value3", Effect: "NoSchedule"},
|
||||
},
|
||||
expectedTaints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key4", Value: "value4", Effect: "NoExecute"},
|
||||
},
|
||||
requestCount: 4,
|
||||
},
|
||||
{
|
||||
name: "remove no-exist taints from node",
|
||||
nodeHandler: &testutil.FakeNodeHandler{
|
||||
Existing: []*v1.Node{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
},
|
||||
Spec: v1.NodeSpec{
|
||||
Taints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Clientset: fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}),
|
||||
},
|
||||
nodeName: "node1",
|
||||
taintsToRemove: []*v1.Taint{
|
||||
{Key: "key3", Value: "value3", Effect: "NoSchedule"},
|
||||
},
|
||||
expectedTaints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
requestCount: 2,
|
||||
},
|
||||
{
|
||||
name: "remove taint from node without taints",
|
||||
nodeHandler: &testutil.FakeNodeHandler{
|
||||
Existing: []*v1.Node{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
},
|
||||
},
|
||||
},
|
||||
Clientset: fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}),
|
||||
},
|
||||
nodeName: "node1",
|
||||
taintsToRemove: []*v1.Taint{
|
||||
{Key: "key3", Value: "value3", Effect: "NoSchedule"},
|
||||
},
|
||||
expectedTaints: nil,
|
||||
requestCount: 2,
|
||||
},
|
||||
{
|
||||
name: "remove empty taint list from node without taints",
|
||||
nodeHandler: &testutil.FakeNodeHandler{
|
||||
Existing: []*v1.Node{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
},
|
||||
},
|
||||
},
|
||||
Clientset: fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}),
|
||||
},
|
||||
nodeName: "node1",
|
||||
taintsToRemove: []*v1.Taint{},
|
||||
expectedTaints: nil,
|
||||
requestCount: 2,
|
||||
},
|
||||
{
|
||||
name: "remove empty taint list from node",
|
||||
nodeHandler: &testutil.FakeNodeHandler{
|
||||
Existing: []*v1.Node{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
},
|
||||
Spec: v1.NodeSpec{
|
||||
Taints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Clientset: fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}),
|
||||
},
|
||||
nodeName: "node1",
|
||||
taintsToRemove: []*v1.Taint{},
|
||||
expectedTaints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
requestCount: 2,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
node, _ := test.nodeHandler.Get(test.nodeName, metav1.GetOptions{})
|
||||
if err := RemoveTaintOffNode(test.nodeHandler, test.nodeName, node, test.taintsToRemove...); err != nil {
|
||||
t.Errorf("%s: RemoveTaintOffNode() error = %v", test.name, err)
|
||||
}
|
||||
|
||||
node, _ = test.nodeHandler.Get(test.nodeName, metav1.GetOptions{})
|
||||
if !reflect.DeepEqual(node.Spec.Taints, test.expectedTaints) {
|
||||
t.Errorf("%s: failed to remove taint off node: expected %+v, got %+v",
|
||||
test.name, test.expectedTaints, node.Spec.Taints)
|
||||
}
|
||||
|
||||
if test.nodeHandler.RequestCount != test.requestCount {
|
||||
t.Errorf("%s: unexpected request count: expected %+v, got %+v",
|
||||
test.name, test.requestCount, test.nodeHandler.RequestCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddOrUpdateTaintOnNode(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
nodeHandler *testutil.FakeNodeHandler
|
||||
nodeName string
|
||||
taintsToAdd []*v1.Taint
|
||||
expectedTaints []v1.Taint
|
||||
requestCount int
|
||||
}{
|
||||
{
|
||||
name: "add one taint on node",
|
||||
nodeHandler: &testutil.FakeNodeHandler{
|
||||
Existing: []*v1.Node{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
},
|
||||
Spec: v1.NodeSpec{
|
||||
Taints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Clientset: fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}),
|
||||
},
|
||||
nodeName: "node1",
|
||||
taintsToAdd: []*v1.Taint{
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
expectedTaints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
requestCount: 3,
|
||||
},
|
||||
{
|
||||
name: "add multiple taints to node",
|
||||
nodeHandler: &testutil.FakeNodeHandler{
|
||||
Existing: []*v1.Node{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
},
|
||||
Spec: v1.NodeSpec{
|
||||
Taints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Clientset: fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}),
|
||||
},
|
||||
nodeName: "node1",
|
||||
taintsToAdd: []*v1.Taint{
|
||||
{Key: "key3", Value: "value3", Effect: "NoSchedule"},
|
||||
{Key: "key4", Value: "value4", Effect: "NoExecute"},
|
||||
},
|
||||
expectedTaints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
{Key: "key3", Value: "value3", Effect: "NoSchedule"},
|
||||
{Key: "key4", Value: "value4", Effect: "NoExecute"},
|
||||
},
|
||||
requestCount: 3,
|
||||
},
|
||||
{
|
||||
name: "add exist taints to node",
|
||||
nodeHandler: &testutil.FakeNodeHandler{
|
||||
Existing: []*v1.Node{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
},
|
||||
Spec: v1.NodeSpec{
|
||||
Taints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Clientset: fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}),
|
||||
},
|
||||
nodeName: "node1",
|
||||
taintsToAdd: []*v1.Taint{
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
expectedTaints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
requestCount: 3,
|
||||
},
|
||||
{
|
||||
name: "add taint to node without taints",
|
||||
nodeHandler: &testutil.FakeNodeHandler{
|
||||
Existing: []*v1.Node{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
},
|
||||
},
|
||||
},
|
||||
Clientset: fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}),
|
||||
},
|
||||
nodeName: "node1",
|
||||
taintsToAdd: []*v1.Taint{
|
||||
{Key: "key3", Value: "value3", Effect: "NoSchedule"},
|
||||
},
|
||||
expectedTaints: []v1.Taint{
|
||||
{Key: "key3", Value: "value3", Effect: "NoSchedule"},
|
||||
},
|
||||
requestCount: 3,
|
||||
},
|
||||
{
|
||||
name: "add empty taint list to node without taints",
|
||||
nodeHandler: &testutil.FakeNodeHandler{
|
||||
Existing: []*v1.Node{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
},
|
||||
},
|
||||
},
|
||||
Clientset: fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}),
|
||||
},
|
||||
nodeName: "node1",
|
||||
taintsToAdd: []*v1.Taint{},
|
||||
expectedTaints: nil,
|
||||
requestCount: 1,
|
||||
},
|
||||
{
|
||||
name: "add empty taint list to node",
|
||||
nodeHandler: &testutil.FakeNodeHandler{
|
||||
Existing: []*v1.Node{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
},
|
||||
Spec: v1.NodeSpec{
|
||||
Taints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Clientset: fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}),
|
||||
},
|
||||
nodeName: "node1",
|
||||
taintsToAdd: []*v1.Taint{},
|
||||
expectedTaints: []v1.Taint{
|
||||
{Key: "key1", Value: "value1", Effect: "NoSchedule"},
|
||||
{Key: "key2", Value: "value2", Effect: "NoExecute"},
|
||||
},
|
||||
requestCount: 1,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if err := AddOrUpdateTaintOnNode(test.nodeHandler, test.nodeName, test.taintsToAdd...); err != nil {
|
||||
t.Errorf("%s: AddOrUpdateTaintOnNode() error = %v", test.name, err)
|
||||
}
|
||||
|
||||
node, _ := test.nodeHandler.Get(test.nodeName, metav1.GetOptions{})
|
||||
if !reflect.DeepEqual(node.Spec.Taints, test.expectedTaints) {
|
||||
t.Errorf("%s: failed to add taint to node: expected %+v, got %+v",
|
||||
test.name, test.expectedTaints, node.Spec.Taints)
|
||||
}
|
||||
|
||||
if test.nodeHandler.RequestCount != test.requestCount {
|
||||
t.Errorf("%s: unexpected request count: expected %+v, got %+v",
|
||||
test.name, test.requestCount, test.nodeHandler.RequestCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1514,7 +1514,6 @@ func TestUpdateNode(t *testing.T) {
|
||||
{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
|
||||
}(),
|
||||
@@ -1522,7 +1521,6 @@ func TestUpdateNode(t *testing.T) {
|
||||
node := newNode("node1", nil)
|
||||
node.Status.Conditions = []v1.NodeCondition{
|
||||
{Type: v1.NodeOutOfDisk, Status: v1.ConditionTrue},
|
||||
{Type: v1.NodeInodePressure, Status: v1.ConditionFalse},
|
||||
}
|
||||
return node
|
||||
}(),
|
||||
|
@@ -328,12 +328,6 @@ func (e *EndpointController) syncService(key string) error {
|
||||
// service is deleted. However, if we're down at the time when
|
||||
// the service is deleted, we will miss that deletion, so this
|
||||
// doesn't completely solve the problem. See #6877.
|
||||
namespace, name, err := cache.SplitMetaNamespaceKey(key)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(fmt.Errorf("Need to delete endpoint with key %q, but couldn't understand the key: %v", key, err))
|
||||
// Don't retry, as the key isn't going to magically become understandable.
|
||||
return nil
|
||||
}
|
||||
err = e.client.Core().Endpoints(namespace).Delete(name, nil)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
|
@@ -24,7 +24,7 @@ go_test(
|
||||
"//pkg/cloudprovider:go_default_library",
|
||||
"//pkg/cloudprovider/providers/fake:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/node/testutil:go_default_library",
|
||||
"//pkg/controller/testutil:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//pkg/util/node:go_default_library",
|
||||
"//pkg/util/taints:go_default_library",
|
||||
@@ -115,9 +115,6 @@ filegroup(
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/controller/node/testutil:all-srcs",
|
||||
],
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
@@ -25,7 +25,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/kubernetes/pkg/controller/node/testutil"
|
||||
"k8s.io/kubernetes/pkg/controller/testutil"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@@ -303,7 +303,7 @@ func swapNodeControllerTaint(kubeClient clientset.Interface, taintToAdd, taintTo
|
||||
}
|
||||
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 {
|
||||
utilruntime.HandleError(
|
||||
fmt.Errorf(
|
||||
|
@@ -1072,12 +1072,12 @@ func (nc *NodeController) markNodeForTainting(node *v1.Node) bool {
|
||||
func (nc *NodeController) markNodeAsHealthy(node *v1.Node) (bool, error) {
|
||||
nc.evictorLock.Lock()
|
||||
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 {
|
||||
glog.Errorf("Failed to remove taint from node %v: %v", node.Name, 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 {
|
||||
glog.Errorf("Failed to remove taint from node %v: %v", node.Name, err)
|
||||
return false, err
|
||||
|
@@ -39,7 +39,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
fakecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/fake"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/node/testutil"
|
||||
"k8s.io/kubernetes/pkg/controller/testutil"
|
||||
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
||||
"k8s.io/kubernetes/pkg/util/node"
|
||||
taintutils "k8s.io/kubernetes/pkg/util/taints"
|
||||
|
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/kubernetes/pkg/controller/node/testutil"
|
||||
"k8s.io/kubernetes/pkg/controller/testutil"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clienttesting "k8s.io/client-go/testing"
|
||||
|
@@ -39,7 +39,7 @@ go_test(
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/node/testutil:go_default_library",
|
||||
"//pkg/controller/testutil:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
|
@@ -30,7 +30,7 @@ import (
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/node/testutil"
|
||||
"k8s.io/kubernetes/pkg/controller/testutil"
|
||||
)
|
||||
|
||||
type FakeController struct{}
|
||||
|
@@ -68,30 +68,31 @@ type FakeNodeHandler struct {
|
||||
DeleteWaitChan chan struct{}
|
||||
}
|
||||
|
||||
// FakeLegacyHandler is a fake implemtation of CoreV1Interface.
|
||||
type FakeLegacyHandler struct {
|
||||
v1core.CoreV1Interface
|
||||
n *FakeNodeHandler
|
||||
}
|
||||
|
||||
// GetUpdatedNodesCopy returns a slice of Nodes with updates applied.
|
||||
func (c *FakeNodeHandler) GetUpdatedNodesCopy() []*v1.Node {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
updatedNodesCopy := make([]*v1.Node, len(c.UpdatedNodes), len(c.UpdatedNodes))
|
||||
for i, ptr := range c.UpdatedNodes {
|
||||
func (m *FakeNodeHandler) GetUpdatedNodesCopy() []*v1.Node {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
updatedNodesCopy := make([]*v1.Node, len(m.UpdatedNodes), len(m.UpdatedNodes))
|
||||
for i, ptr := range m.UpdatedNodes {
|
||||
updatedNodesCopy[i] = ptr
|
||||
}
|
||||
return updatedNodesCopy
|
||||
}
|
||||
|
||||
// Core returns fake CoreInterface.
|
||||
func (c *FakeNodeHandler) Core() v1core.CoreV1Interface {
|
||||
return &FakeLegacyHandler{c.Clientset.Core(), c}
|
||||
func (m *FakeNodeHandler) Core() v1core.CoreV1Interface {
|
||||
return &FakeLegacyHandler{m.Clientset.Core(), m}
|
||||
}
|
||||
|
||||
// CoreV1 returns fake CoreV1Interface
|
||||
func (c *FakeNodeHandler) CoreV1() v1core.CoreV1Interface {
|
||||
return &FakeLegacyHandler{c.Clientset.CoreV1(), c}
|
||||
func (m *FakeNodeHandler) CoreV1() v1core.CoreV1Interface {
|
||||
return &FakeLegacyHandler{m.Clientset.CoreV1(), m}
|
||||
}
|
||||
|
||||
// Nodes return fake NodeInterfaces.
|
||||
@@ -115,9 +116,8 @@ func (m *FakeNodeHandler) Create(node *v1.Node) (*v1.Node, error) {
|
||||
nodeCopy := *node
|
||||
m.CreatedNodes = append(m.CreatedNodes, &nodeCopy)
|
||||
return node, nil
|
||||
} else {
|
||||
return nil, errors.New("Create error.")
|
||||
}
|
||||
return nil, errors.New("create error")
|
||||
}
|
||||
|
||||
// Get returns a Node from the fake store.
|
Reference in New Issue
Block a user