• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubernetes-sigs / sig-storage-local-static-provisioner / 16065277026

04 Jul 2025 03:37AM UTC coverage: 50.79% (-0.4%) from 51.195%
16065277026

push

github

web-flow
Merge pull request #501 from saidjawad/support_for_karpenter_start_up_taint

Support for removing start up taint

32 of 90 new or added lines in 4 files covered. (35.56%)

1 existing line in 1 file now uncovered.

996 of 1961 relevant lines covered (50.79%)

6.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

58.18
/pkg/node-taint/node_taint.go
1
/*
2
Copyright 2025 The Kubernetes Authors.
3

4
Licensed under the Apache License, Version 2.0 (the "License");
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7

8
    http://www.apache.org/licenses/LICENSE-2.0
9

10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
*/
16

17
package nodetaint
18

19
import (
20
        "context"
21
        "math/rand"
22
        "time"
23

24
        corev1 "k8s.io/api/core/v1"
25
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26
        "k8s.io/klog/v2"
27
        "sigs.k8s.io/sig-storage-local-static-provisioner/pkg/common"
28
        "sigs.k8s.io/sig-storage-local-static-provisioner/pkg/util"
29
)
30

31
const (
32
        maxRemoveTaintRetries  = 3
33
        removeTaintRetryPeriod = 5 * time.Second
34
)
35

36
// Remover is responsible for removing the node taint that indidcates the provisioner is not ready yet.
37
type Remover struct {
38
        RuntimeConfig *common.RuntimeConfig
39
        taintRemoved  bool
40
}
41

42
// NewRemover creates an instances of RemoveNodeNotReadyTaint.
43
func NewRemover(runtimeConfig *common.RuntimeConfig) *Remover {
4✔
44
        return &Remover{
4✔
45
                RuntimeConfig: runtimeConfig,
4✔
46
                taintRemoved:  false,
4✔
47
        }
4✔
48
}
4✔
49

50
// RemoveNodeTaint searches for the provisionerNotReadyNodeTaintKey and removes it from the node.
51
// it only removes the taint once.
52
func (n *Remover) RemoveNodeTaint() error {
4✔
53
        userConfig := n.RuntimeConfig.UserConfig
4✔
54
        if !userConfig.RemoveNodeNotReadyTaint || n.taintRemoved {
6✔
55
                return nil
2✔
56
        }
2✔
57

58
        client := n.RuntimeConfig.Client.CoreV1()
2✔
59
        node := util.GetNode(client, n.RuntimeConfig.Node.Name)
2✔
60

2✔
61
        var taintExists bool
2✔
62
        currTaints := []corev1.Taint{}
2✔
63
        for _, taint := range node.Spec.Taints {
5✔
64
                if taint.Key == userConfig.ProvisionerNotReadyNodeTaintKey {
4✔
65
                        taintExists = true
1✔
66
                } else {
3✔
67
                        currTaints = append(currTaints, taint)
2✔
68
                }
2✔
69
        }
70

71
        if !taintExists {
3✔
72
                klog.Infof("ProvisionerNotReadyNodeTaintKey %s was not found on node %s", userConfig.ProvisionerNotReadyNodeTaintKey, node.Name)
1✔
73
                return nil
1✔
74
        }
1✔
75

76
        node.Spec.Taints = currTaints
1✔
77
        _, err := client.Nodes().Update(context.Background(), node, metav1.UpdateOptions{})
1✔
78
        if err != nil {
1✔
NEW
79
                klog.Errorf("failed to remove node taint %s from node %s: %v", userConfig.ProvisionerNotReadyNodeTaintKey, node.Name, err)
×
NEW
80
                return err
×
NEW
81
        }
×
82

83
        n.taintRemoved = true
1✔
84
        klog.Infof("removed node taint %s from node %s", userConfig.ProvisionerNotReadyNodeTaintKey, node.Name)
1✔
85
        return nil
1✔
86
}
87

88
// ShouldRemoveTaint returns true if the taint is not removed already and the user config is set to remove the taint.
NEW
89
func (n *Remover) ShouldRemoveTaint() bool {
×
NEW
90
        return !n.taintRemoved && n.RuntimeConfig.UserConfig.RemoveNodeNotReadyTaint
×
NEW
91
}
×
92

93
// RemoveTaintWithBackoff removes the taint if the taint is not removed already, it performs linear randomized backoff upon failure.
NEW
94
func (n *Remover) RemoveTaintWithBackoff() {
×
NEW
95
        retries := 0
×
NEW
96
        retryPeriod := time.Duration(0 * time.Second)
×
NEW
97
        for n.ShouldRemoveTaint() && retries < maxRemoveTaintRetries {
×
NEW
98
                err := n.RemoveNodeTaint()
×
NEW
99
                if err == nil {
×
NEW
100
                        return
×
NEW
101
                }
×
NEW
102
                retries++
×
NEW
103
                // randomized retry period
×
NEW
104
                retryPeriodInSeconds := int(removeTaintRetryPeriod / time.Second)
×
NEW
105
                randomSeconds := rand.Intn(retryPeriodInSeconds)
×
NEW
106
                retryPeriod += time.Duration(randomSeconds) * time.Second
×
NEW
107
                time.Sleep(retryPeriod)
×
108
        }
NEW
109
        if retries == maxRemoveTaintRetries {
×
NEW
110
                klog.Errorf("failed to remove node taint %s from node %s after %d retries", n.RuntimeConfig.UserConfig.ProvisionerNotReadyNodeTaintKey, n.RuntimeConfig.Node.Name, maxRemoveTaintRetries)
×
NEW
111
        }
×
112
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc