Exemple #1
0
func AnnotationsHaveEqualTaints(annotationA map[string]string, annotationB map[string]string) bool {
	taintsA, err := v1.GetTaintsFromNodeAnnotations(annotationA)
	if err != nil {
		return false
	}
	taintsB, err := v1.GetTaintsFromNodeAnnotations(annotationB)
	if err != nil {
		return false
	}

	if len(taintsA) != len(taintsB) {
		return false
	}

	for _, taintA := range taintsA {
		found := false
		for _, taintB := range taintsB {
			if reflect.DeepEqual(taintA, taintB) {
				found = true
				break
			}
		}
		if !found {
			return false
		}
	}
	return true
}
Exemple #2
0
func addToBeDeletedTaint(node *apiv1.Node) (bool, error) {
	taints, err := apiv1.GetTaintsFromNodeAnnotations(node.Annotations)
	if err != nil {
		glog.Warningf("Error while getting Taints for node %v: %v", node.Name, err)
		return false, err
	}
	for _, taint := range taints {
		if taint.Key == ToBeDeletedTaint {
			glog.Infof("ToBeDeletedTaint already present on on node %v", taint, node.Name)
			return false, nil
		}
	}
	taints = append(taints, apiv1.Taint{
		Key:    ToBeDeletedTaint,
		Value:  time.Now().String(),
		Effect: apiv1.TaintEffectNoSchedule,
	})
	taintsJson, err := json.Marshal(taints)
	if err != nil {
		glog.Warningf("Error while adding taints on node %v: %v", node.Name, err)
		return false, err
	}
	if node.Annotations == nil {
		node.Annotations = make(map[string]string)
	}
	node.Annotations[apiv1.TaintsAnnotationKey] = string(taintsJson)
	return true, nil
}
Exemple #3
0
// reorganizeTaints returns the updated set of taints, taking into account old taints that were not updated,
// old taints that were updated, old taints that were deleted, and new taints.
func reorganizeTaints(accessor metav1.Object, overwrite bool, taintsToAdd []v1.Taint, taintsToRemove []v1.Taint) ([]v1.Taint, error) {
	newTaints := append([]v1.Taint{}, taintsToAdd...)

	var oldTaints []v1.Taint
	var err error
	annotations := accessor.GetAnnotations()
	if annotations != nil {
		if oldTaints, err = v1.GetTaintsFromNodeAnnotations(annotations); err != nil {
			return nil, err
		}
	}

	// add taints that already existing but not updated to newTaints
	for _, oldTaint := range oldTaints {
		existsInNew := false
		for _, taint := range newTaints {
			if taint.MatchTaint(oldTaint) {
				existsInNew = true
				break
			}
		}
		if !existsInNew {
			newTaints = append(newTaints, oldTaint)
		}
	}

	allErrs := []error{}
	for _, taintToRemove := range taintsToRemove {
		newTaints, err = deleteTaint(newTaints, taintToRemove)
		if err != nil {
			allErrs = append(allErrs, err)
		}
	}
	return newTaints, utilerrors.NewAggregate(allErrs)
}
Exemple #4
0
func PodToleratesNodeTaints(pod *v1.Pod, meta interface{}, nodeInfo *schedulercache.NodeInfo) (bool, []algorithm.PredicateFailureReason, error) {
	node := nodeInfo.Node()
	if node == nil {
		return false, nil, fmt.Errorf("node not found")
	}

	taints, err := v1.GetTaintsFromNodeAnnotations(node.Annotations)
	if err != nil {
		return false, nil, err
	}

	tolerations, err := v1.GetTolerationsFromPodAnnotations(pod.Annotations)
	if err != nil {
		return false, nil, err
	}

	if tolerationsToleratesTaints(tolerations, taints) {
		return true, nil, nil
	}
	return false, []algorithm.PredicateFailureReason{ErrTaintsTolerationsNotMatch}, nil
}
Exemple #5
0
// cleanToBeDeleted clean ToBeDeleted taints.
func cleanToBeDeleted(nodes []*apiv1.Node, client kube_client.Interface, recorder kube_record.EventRecorder) error {
	for _, node := range nodes {

		taints, err := apiv1.GetTaintsFromNodeAnnotations(node.Annotations)
		if err != nil {
			glog.Warningf("Error while getting Taints for node %v: %v", node.Name, err)
			continue
		}

		newTaints := make([]apiv1.Taint, 0)
		for _, taint := range taints {
			if taint.Key == ToBeDeletedTaint {
				glog.Infof("Releasing taint %+v on node %v", taint, node.Name)
			} else {
				newTaints = append(newTaints, taint)
			}
		}

		if len(newTaints) != len(taints) {
			taintsJson, err := json.Marshal(newTaints)
			if err != nil {
				glog.Warningf("Error while releasing taints on node %v: %v", node.Name, err)
				continue
			}
			if node.Annotations == nil {
				node.Annotations = make(map[string]string)
			}
			node.Annotations[apiv1.TaintsAnnotationKey] = string(taintsJson)
			_, err = client.Core().Nodes().Update(node)
			if err != nil {
				glog.Warningf("Error while releasing taints on node %v: %v", node.Name, err)
			} else {
				glog.V(1).Infof("Successfully released toBeDeletedTaint on node %v", node.Name)
				recorder.Eventf(node, apiv1.EventTypeNormal, "ClusterAutoscalerCleanup", "marking the node as schedulable")
			}
		}
	}
	return nil
}
Exemple #6
0
// validateNoTaintOverwrites validates that when overwrite is false, to-be-updated taints don't exist in the node taint list (yet)
func validateNoTaintOverwrites(accessor metav1.Object, taints []v1.Taint) error {
	annotations := accessor.GetAnnotations()
	if annotations == nil {
		return nil
	}

	allErrs := []error{}
	oldTaints, err := v1.GetTaintsFromNodeAnnotations(annotations)
	if err != nil {
		allErrs = append(allErrs, err)
		return utilerrors.NewAggregate(allErrs)
	}

	for _, taint := range taints {
		for _, oldTaint := range oldTaints {
			if taint.Key == oldTaint.Key && taint.Effect == oldTaint.Effect {
				allErrs = append(allErrs, fmt.Errorf("Node '%s' already has a taint with key (%s) and effect (%v), and --overwrite is false", accessor.GetName(), taint.Key, taint.Effect))
				break
			}
		}
	}
	return utilerrors.NewAggregate(allErrs)
}
Exemple #7
0
// Sets the overall node information.
func (n *NodeInfo) SetNode(node *v1.Node) error {
	n.node = node
	for rName, rQuant := range node.Status.Allocatable {
		switch rName {
		case v1.ResourceCPU:
			n.allocatableResource.MilliCPU = rQuant.MilliValue()
		case v1.ResourceMemory:
			n.allocatableResource.Memory = rQuant.Value()
		case v1.ResourceNvidiaGPU:
			n.allocatableResource.NvidiaGPU = rQuant.Value()
		case v1.ResourcePods:
			n.allowedPodNumber = int(rQuant.Value())
		default:
			if v1.IsOpaqueIntResourceName(rName) {
				// Lazily allocate opaque resource map.
				if n.allocatableResource.OpaqueIntResources == nil {
					n.allocatableResource.OpaqueIntResources = map[v1.ResourceName]int64{}
				}
				n.allocatableResource.OpaqueIntResources[rName] = rQuant.Value()
			}
		}
	}
	n.taints, n.taintsErr = v1.GetTaintsFromNodeAnnotations(node.Annotations)
	for i := range node.Status.Conditions {
		cond := &node.Status.Conditions[i]
		switch cond.Type {
		case v1.NodeMemoryPressure:
			n.memoryPressureCondition = cond.Status
		case v1.NodeDiskPressure:
			n.diskPressureCondition = cond.Status
		default:
			// We ignore other conditions.
		}
	}
	n.generation++
	return nil
}