// Filters the nodes to find the ones that fit based on the given predicate functions // Each node is passed through the predicate functions to determine if it is a fit func findNodesThatFit( pod *api.Pod, nodeNameToInfo map[string]*schedulercache.NodeInfo, nodes []*api.Node, predicateFuncs map[string]algorithm.FitPredicate, extenders []algorithm.SchedulerExtender) ([]*api.Node, FailedPredicateMap, error) { var filtered []*api.Node failedPredicateMap := FailedPredicateMap{} if len(predicateFuncs) == 0 { filtered = nodes } else { // Create filtered list with enough space to avoid growing it // and allow assigning. filtered = make([]*api.Node, len(nodes)) meta := predicates.PredicateMetadata(pod, nodeNameToInfo) errs := []error{} var predicateResultLock sync.Mutex var filteredLen int32 checkNode := func(i int) { nodeName := nodes[i].Name fits, failedPredicate, err := podFitsOnNode(pod, meta, nodeNameToInfo[nodeName], predicateFuncs) if err != nil { predicateResultLock.Lock() errs = append(errs, err) predicateResultLock.Unlock() return } if fits { filtered[atomic.AddInt32(&filteredLen, 1)-1] = nodes[i] } else { predicateResultLock.Lock() failedPredicateMap[nodeName] = failedPredicate predicateResultLock.Unlock() } } workqueue.Parallelize(16, len(nodes), checkNode) filtered = filtered[:filteredLen] if len(errs) > 0 { return []*api.Node{}, FailedPredicateMap{}, errors.NewAggregate(errs) } } if len(filtered) > 0 && len(extenders) != 0 { for _, extender := range extenders { filteredList, err := extender.Filter(pod, filtered) if err != nil { return []*api.Node{}, FailedPredicateMap{}, err } filtered = filteredList if len(filtered) == 0 { break } } } return filtered, failedPredicateMap, nil }
func (dsc *DaemonSetsController) nodeShouldRunDaemonPod(node *api.Node, ds *extensions.DaemonSet) bool { // If the daemon set specifies a node name, check that it matches with node.Name. if !(ds.Spec.Template.Spec.NodeName == "" || ds.Spec.Template.Spec.NodeName == node.Name) { return false } // TODO: Move it to the predicates for _, c := range node.Status.Conditions { if c.Type == api.NodeOutOfDisk && c.Status == api.ConditionTrue { return false } } newPod := &api.Pod{Spec: ds.Spec.Template.Spec, ObjectMeta: ds.Spec.Template.ObjectMeta} newPod.Spec.NodeName = node.Name pods := []*api.Pod{} for _, m := range dsc.podStore.Indexer.List() { pod := m.(*api.Pod) if pod.Spec.NodeName != node.Name { continue } if pod.Status.Phase == api.PodSucceeded || pod.Status.Phase == api.PodFailed { continue } // ignore pods that belong to the daemonset when taking into account whether // a daemonset should bind to a node. if pds := dsc.getPodDaemonSet(pod); pds != nil && ds.Name == pds.Name { continue } pods = append(pods, pod) } nodeInfo := schedulercache.NewNodeInfo(pods...) nodeInfo.SetNode(node) fit, reasons, err := predicates.GeneralPredicates(newPod, nil, nodeInfo) if err != nil { glog.Warningf("GeneralPredicates failed on pod %s due to unexpected error: %v", newPod.Name, err) } for _, r := range reasons { glog.V(2).Infof("GeneralPredicates failed on pod %s for reason: %v", newPod.Name, r.GetReason()) } if !fit { return false } fit, reasons, err = predicates.PodToleratesNodeTaints(newPod, predicates.PredicateMetadata(newPod, nil), nodeInfo) if err != nil { glog.Warningf("PodToleratesNodeTaints failed on pod %s due to unexpected error: %v", newPod.Name, err) } for _, r := range reasons { glog.V(2).Infof("PodToleratesNodeTaints failed on pod %s for reason: %v", newPod.Name, r.GetReason()) } return fit }
// Filters the nodes to find the ones that fit based on the given predicate functions // Each node is passed through the predicate functions to determine if it is a fit func findNodesThatFit(pod *api.Pod, nodeNameToInfo map[string]*schedulercache.NodeInfo, predicateFuncs map[string]algorithm.FitPredicate, nodes api.NodeList, extenders []algorithm.SchedulerExtender) (api.NodeList, FailedPredicateMap, error) { // Create filtered list with enough space to avoid growing it. filtered := make([]api.Node, 0, len(nodes.Items)) failedPredicateMap := FailedPredicateMap{} if len(predicateFuncs) == 0 { filtered = nodes.Items } else { predicateResultLock := sync.Mutex{} errs := []error{} meta := predicates.PredicateMetadata(pod) checkNode := func(i int) { nodeName := nodes.Items[i].Name fits, failedPredicate, err := podFitsOnNode(pod, meta, nodeNameToInfo[nodeName], predicateFuncs) predicateResultLock.Lock() defer predicateResultLock.Unlock() if err != nil { errs = append(errs, err) return } if fits { filtered = append(filtered, nodes.Items[i]) } else { failedPredicateMap[nodeName] = failedPredicate } } workqueue.Parallelize(16, len(nodes.Items), checkNode) if len(errs) > 0 { return api.NodeList{}, FailedPredicateMap{}, errors.NewAggregate(errs) } } if len(filtered) > 0 && len(extenders) != 0 { for _, extender := range extenders { filteredList, err := extender.Filter(pod, &api.NodeList{Items: filtered}) if err != nil { return api.NodeList{}, FailedPredicateMap{}, err } filtered = filteredList.Items if len(filtered) == 0 { break } } } return api.NodeList{Items: filtered}, failedPredicateMap, nil }