Merge pull request #32378 from kevin-wangzefeng/update-taints-e2e

Automatic merge from submit-queue

update taints e2e, restrict taints operation with key, effect

Since taints are now unique by key, effect on a node, this PR is to restrict existing taints adding/removing/updating operations in taints e2e.
Also fixes https://github.com/kubernetes/kubernetes/issues/31066#issuecomment-242870101
Related prior Issue/PR #29362 and #30590
This commit is contained in:
Kubernetes Submit Queue
2016-09-10 13:20:51 -07:00
committed by GitHub
7 changed files with 201 additions and 79 deletions

View File

@@ -3059,7 +3059,7 @@ func AddOrUpdateTaintOnNode(c *client.Client, nodeName string, taint api.Taint)
var newTaints []api.Taint
updated := false
for _, existingTaint := range nodeTaints {
if existingTaint.Key == taint.Key {
if taint.MatchTaint(existingTaint) {
newTaints = append(newTaints, taint)
updated = true
continue
@@ -3093,49 +3093,49 @@ func AddOrUpdateTaintOnNode(c *client.Client, nodeName string, taint api.Taint)
}
}
func taintExists(taints []api.Taint, taintKey string) bool {
func taintExists(taints []api.Taint, taintToFind api.Taint) bool {
for _, taint := range taints {
if taint.Key == taintKey {
if taint.MatchTaint(taintToFind) {
return true
}
}
return false
}
func ExpectNodeHasTaint(c *client.Client, nodeName string, taintKey string) {
By("verifying the node has the taint " + taintKey)
func ExpectNodeHasTaint(c *client.Client, nodeName string, taint api.Taint) {
By("verifying the node has the taint " + taint.ToString())
node, err := c.Nodes().Get(nodeName)
ExpectNoError(err)
nodeTaints, err := api.GetTaintsFromNodeAnnotations(node.Annotations)
ExpectNoError(err)
if len(nodeTaints) == 0 || !taintExists(nodeTaints, taintKey) {
Failf("Failed to find taint %s on node %s", taintKey, nodeName)
if len(nodeTaints) == 0 || !taintExists(nodeTaints, taint) {
Failf("Failed to find taint %s on node %s", taint.ToString(), nodeName)
}
}
func deleteTaintByKey(taints []api.Taint, taintKey string) ([]api.Taint, error) {
func deleteTaint(oldTaints []api.Taint, taintToDelete api.Taint) ([]api.Taint, error) {
newTaints := []api.Taint{}
found := false
for _, taint := range taints {
if taint.Key == taintKey {
for _, oldTaint := range oldTaints {
if oldTaint.MatchTaint(taintToDelete) {
found = true
continue
}
newTaints = append(newTaints, taint)
newTaints = append(newTaints, taintToDelete)
}
if !found {
return nil, fmt.Errorf("taint key=\"%s\" not found.", taintKey)
return nil, fmt.Errorf("taint %s not found.", taintToDelete.ToString())
}
return newTaints, nil
}
// RemoveTaintOffNode is for cleaning up taints temporarily added to node,
// won't fail if target taint doesn't exist or has been removed.
func RemoveTaintOffNode(c *client.Client, nodeName string, taintKey string) {
By("removing the taint " + taintKey + " off the node " + nodeName)
func RemoveTaintOffNode(c *client.Client, nodeName string, taint api.Taint) {
By("removing the taint " + taint.ToString() + " off the node " + nodeName)
for attempt := 0; attempt < UpdateRetries; attempt++ {
node, err := c.Nodes().Get(nodeName)
ExpectNoError(err)
@@ -3146,11 +3146,11 @@ func RemoveTaintOffNode(c *client.Client, nodeName string, taintKey string) {
return
}
if !taintExists(nodeTaints, taintKey) {
if !taintExists(nodeTaints, taint) {
return
}
newTaints, err := deleteTaintByKey(nodeTaints, taintKey)
newTaints, err := deleteTaint(nodeTaints, taint)
ExpectNoError(err)
taintsData, err := json.Marshal(newTaints)
@@ -3161,7 +3161,7 @@ func RemoveTaintOffNode(c *client.Client, nodeName string, taintKey string) {
if !apierrs.IsConflict(err) {
ExpectNoError(err)
} else {
Logf("Conflict when trying to add/update taint %v to %v", taintKey, nodeName)
Logf("Conflict when trying to add/update taint %s to node %v", taint.ToString(), nodeName)
}
} else {
break
@@ -3171,11 +3171,11 @@ func RemoveTaintOffNode(c *client.Client, nodeName string, taintKey string) {
nodeUpdated, err := c.Nodes().Get(nodeName)
ExpectNoError(err)
By("verifying the node doesn't have the taint " + taintKey)
By("verifying the node doesn't have the taint " + taint.ToString())
taintsGot, err := api.GetTaintsFromNodeAnnotations(nodeUpdated.Annotations)
ExpectNoError(err)
if taintExists(taintsGot, taintKey) {
Failf("Failed removing taint " + taintKey + " of the node " + nodeName)
if taintExists(taintsGot, taint) {
Failf("Failed removing taint " + taint.ToString() + " of the node " + nodeName)
}
}

View File

@@ -1232,76 +1232,83 @@ var _ = framework.KubeDescribe("Kubectl client", func() {
framework.KubeDescribe("Kubectl taint", func() {
It("should update the taint on a node", func() {
taintName := fmt.Sprintf("kubernetes.io/e2e-taint-key-%s", string(uuid.NewUUID()))
taintValue := "testing-taint-value"
taintEffect := fmt.Sprintf("%s", api.TaintEffectNoSchedule)
testTaint := api.Taint{
Key: fmt.Sprintf("kubernetes.io/e2e-taint-key-%s", string(uuid.NewUUID())),
Value: "testing-taint-value",
Effect: api.TaintEffectNoSchedule,
}
nodes, err := c.Nodes().List(api.ListOptions{})
Expect(err).NotTo(HaveOccurred())
node := nodes.Items[0]
nodeName := node.Name
By("adding the taint " + taintName + " with value " + taintValue + " and taint effect " + taintEffect + " to a node")
framework.RunKubectlOrDie("taint", "nodes", nodeName, taintName+"="+taintValue+":"+taintEffect)
By("verifying the node has the taint " + taintName + " with the value " + taintValue)
By("adding the taint " + testTaint.ToString() + " to a node")
framework.RunKubectlOrDie("taint", "nodes", nodeName, testTaint.ToString())
By("verifying the node has the taint " + testTaint.ToString())
output := framework.RunKubectlOrDie("describe", "node", nodeName)
requiredStrings := [][]string{
{"Name:", nodeName},
{"Taints:"},
{taintName + "=" + taintValue + ":" + taintEffect},
{testTaint.ToString()},
}
checkOutput(output, requiredStrings)
By("removing the taint " + taintName + " of a node")
framework.RunKubectlOrDie("taint", "nodes", nodeName, taintName+":"+taintEffect+"-")
By("verifying the node doesn't have the taint " + taintName)
By("removing the taint " + testTaint.ToString() + " of a node")
framework.RunKubectlOrDie("taint", "nodes", nodeName, testTaint.Key+":"+string(testTaint.Effect)+"-")
By("verifying the node doesn't have the taint " + testTaint.Key)
output = framework.RunKubectlOrDie("describe", "node", nodeName)
if strings.Contains(output, taintName) {
framework.Failf("Failed removing taint " + taintName + " of the node " + nodeName)
if strings.Contains(output, testTaint.Key) {
framework.Failf("Failed removing taint " + testTaint.Key + " of the node " + nodeName)
}
})
It("should remove all the taints with the same key off a node", func() {
taintName := fmt.Sprintf("kubernetes.io/e2e-taint-key-%s", string(uuid.NewUUID()))
taintValue := "testing-taint-value"
taintEffect := fmt.Sprintf("%s", api.TaintEffectNoSchedule)
testTaint := api.Taint{
Key: fmt.Sprintf("kubernetes.io/e2e-taint-key-%s", string(uuid.NewUUID())),
Value: "testing-taint-value",
Effect: api.TaintEffectNoSchedule,
}
nodes, err := c.Nodes().List(api.ListOptions{})
Expect(err).NotTo(HaveOccurred())
node := nodes.Items[0]
nodeName := node.Name
By("adding the taint " + taintName + " with value " + taintValue + " and taint effect " + taintEffect + " to a node")
framework.RunKubectlOrDie("taint", "nodes", nodeName, taintName+"="+taintValue+":"+taintEffect)
By("verifying the node has the taint " + taintName + " with the value " + taintValue)
By("adding the taint " + testTaint.ToString() + " to a node")
framework.RunKubectlOrDie("taint", "nodes", nodeName, testTaint.ToString())
By("verifying the node has the taint " + testTaint.ToString())
output := framework.RunKubectlOrDie("describe", "node", nodeName)
requiredStrings := [][]string{
{"Name:", nodeName},
{"Taints:"},
{taintName + "=" + taintValue + ":" + taintEffect},
{testTaint.ToString()},
}
checkOutput(output, requiredStrings)
newTaintValue := "another-testing-taint-value"
newTaintEffect := fmt.Sprintf("%s", api.TaintEffectPreferNoSchedule)
By("adding another taint " + taintName + " with value " + newTaintValue + " and taint effect " + newTaintEffect + " to the node")
framework.RunKubectlOrDie("taint", "nodes", nodeName, taintName+"="+newTaintValue+":"+newTaintEffect)
By("verifying the node has the taint " + taintName + " with the value " + newTaintValue)
newTestTaint := api.Taint{
Key: testTaint.Key,
Value: "another-testing-taint-value",
Effect: api.TaintEffectPreferNoSchedule,
}
By("adding another taint " + newTestTaint.ToString() + " to the node")
framework.RunKubectlOrDie("taint", "nodes", nodeName, newTestTaint.ToString())
By("verifying the node has the taint " + newTestTaint.ToString())
output = framework.RunKubectlOrDie("describe", "node", nodeName)
requiredStrings = [][]string{
{"Name:", nodeName},
{"Taints:"},
{taintName + "=" + newTaintValue + ":" + newTaintEffect},
{newTestTaint.ToString()},
}
checkOutput(output, requiredStrings)
By("removing the taint " + taintName + " of a node")
framework.RunKubectlOrDie("taint", "nodes", nodeName, taintName+"-")
By("verifying the node doesn't have the taints " + taintName)
By("removing all taints that have the same key " + testTaint.Key + " of the node")
framework.RunKubectlOrDie("taint", "nodes", nodeName, testTaint.Key+"-")
By("verifying the node doesn't have the taints that have the same key " + testTaint.Key)
output = framework.RunKubectlOrDie("describe", "node", nodeName)
if strings.Contains(output, taintName) {
framework.Failf("Failed removing taint " + taintName + " of the node " + nodeName)
if strings.Contains(output, testTaint.Key) {
framework.Failf("Failed removing taints " + testTaint.Key + " of the node " + nodeName)
}
})
})

View File

@@ -1328,12 +1328,14 @@ var _ = framework.KubeDescribe("SchedulerPredicates [Serial]", func() {
framework.ExpectNoError(err)
By("Trying to apply a random taint on the found node.")
taintName := fmt.Sprintf("kubernetes.io/e2e-taint-key-%s", string(uuid.NewUUID()))
taintValue := "testing-taint-value"
taintEffect := api.TaintEffectNoSchedule
framework.AddOrUpdateTaintOnNode(c, nodeName, api.Taint{Key: taintName, Value: taintValue, Effect: taintEffect})
framework.ExpectNodeHasTaint(c, nodeName, taintName)
defer framework.RemoveTaintOffNode(c, nodeName, taintName)
testTaint := api.Taint{
Key: fmt.Sprintf("kubernetes.io/e2e-taint-key-%s", string(uuid.NewUUID())),
Value: "testing-taint-value",
Effect: api.TaintEffectNoSchedule,
}
framework.AddOrUpdateTaintOnNode(c, nodeName, testTaint)
framework.ExpectNodeHasTaint(c, nodeName, testTaint)
defer framework.RemoveTaintOffNode(c, nodeName, testTaint)
By("Trying to apply a random label on the found node.")
labelKey := fmt.Sprintf("kubernetes.io/e2e-label-key-%s", string(uuid.NewUUID()))
@@ -1354,9 +1356,9 @@ var _ = framework.KubeDescribe("SchedulerPredicates [Serial]", func() {
"scheduler.alpha.kubernetes.io/tolerations": `
[
{
"key": "` + taintName + `",
"value": "` + taintValue + `",
"effect": "` + string(taintEffect) + `"
"key": "` + testTaint.Key + `",
"value": "` + testTaint.Value + `",
"effect": "` + string(testTaint.Effect) + `"
}
]`,
},
@@ -1423,12 +1425,14 @@ var _ = framework.KubeDescribe("SchedulerPredicates [Serial]", func() {
framework.ExpectNoError(err)
By("Trying to apply a random taint on the found node.")
taintName := fmt.Sprintf("kubernetes.io/e2e-taint-key-%s", string(uuid.NewUUID()))
taintValue := "testing-taint-value"
taintEffect := api.TaintEffectNoSchedule
framework.AddOrUpdateTaintOnNode(c, nodeName, api.Taint{Key: taintName, Value: taintValue, Effect: taintEffect})
framework.ExpectNodeHasTaint(c, nodeName, taintName)
defer framework.RemoveTaintOffNode(c, nodeName, taintName)
testTaint := api.Taint{
Key: fmt.Sprintf("kubernetes.io/e2e-taint-key-%s", string(uuid.NewUUID())),
Value: "testing-taint-value",
Effect: api.TaintEffectNoSchedule,
}
framework.AddOrUpdateTaintOnNode(c, nodeName, testTaint)
framework.ExpectNodeHasTaint(c, nodeName, testTaint)
defer framework.RemoveTaintOffNode(c, nodeName, testTaint)
By("Trying to apply a random label on the found node.")
labelKey := fmt.Sprintf("kubernetes.io/e2e-label-key-%s", string(uuid.NewUUID()))
@@ -1466,7 +1470,7 @@ var _ = framework.KubeDescribe("SchedulerPredicates [Serial]", func() {
verifyResult(c, podNameNoTolerations, 0, 1, ns)
By("Removing taint off the node")
framework.RemoveTaintOffNode(c, nodeName, taintName)
framework.RemoveTaintOffNode(c, nodeName, testTaint)
// Wait a bit to allow scheduler to do its thing
// TODO: this is brittle; there's no guarantee the scheduler will have run in 10 seconds.
framework.Logf("Sleeping 10 seconds and crossing our fingers that scheduler will run in that time.")