| 857 | } |
| 858 | |
| 859 | func removeTaint(node *corev1.Node, client kubernetes.Interface, taintKey string) (bool, error) { |
| 860 | retryDeadline := time.Now().Add(maxRetryDeadline) |
| 861 | freshNode := node.DeepCopy() |
| 862 | var err error |
| 863 | refresh := false |
| 864 | for { |
| 865 | if refresh { |
| 866 | // Get the newest version of the node. |
| 867 | freshNode, err = client.CoreV1().Nodes().Get(context.TODO(), node.Name, metav1.GetOptions{}) |
| 868 | if err != nil || freshNode == nil { |
| 869 | return false, fmt.Errorf("failed to get node %v: %v", node.Name, err) |
| 870 | } |
| 871 | } |
| 872 | newTaints := make([]corev1.Taint, 0) |
| 873 | for _, taint := range freshNode.Spec.Taints { |
| 874 | if taint.Key == taintKey { |
| 875 | log.Info(). |
| 876 | Interface("taint", taint). |
| 877 | Str("node_name", node.Name). |
| 878 | Msg("Releasing taint on node") |
| 879 | } else { |
| 880 | newTaints = append(newTaints, taint) |
| 881 | } |
| 882 | } |
| 883 | if len(newTaints) == len(freshNode.Spec.Taints) { |
| 884 | if !refresh { |
| 885 | // Make sure we have the latest version before skipping update. |
| 886 | refresh = true |
| 887 | continue |
| 888 | } |
| 889 | return false, nil |
| 890 | } |
| 891 | |
| 892 | freshNode.Spec.Taints = newTaints |
| 893 | _, err = client.CoreV1().Nodes().Update(context.TODO(), freshNode, metav1.UpdateOptions{}) |
| 894 | |
| 895 | if err != nil && errors.IsConflict(err) && time.Now().Before(retryDeadline) { |
| 896 | refresh = true |
| 897 | time.Sleep(conflictRetryInterval) |
| 898 | continue |
| 899 | } |
| 900 | |
| 901 | if err != nil { |
| 902 | log.Err(err). |
| 903 | Str("taint_key", taintKey). |
| 904 | Str("node_name", node.Name). |
| 905 | Msg("Error while releasing taint on node") |
| 906 | return false, err |
| 907 | } |
| 908 | log.Info(). |
| 909 | Str("taint_key", taintKey). |
| 910 | Str("node_name", node.Name). |
| 911 | Msg("Successfully released taint on node") |
| 912 | return true, nil |
| 913 | } |
| 914 | } |
| 915 | |
| 916 | func getUptimeFunc(uptimeFile string) uptime.UptimeFuncType { |