mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Merge pull request #82034 from alculquicondor/feat/unschedulable_unresolvable
[Framework] Add UnschedulableAndUnresolvable status code
This commit is contained in:
		@@ -332,7 +332,7 @@ func (g *genericScheduler) Preempt(pod *v1.Pod, scheduleErr error) (*v1.Node, []
 | 
				
			|||||||
	if len(allNodes) == 0 {
 | 
						if len(allNodes) == 0 {
 | 
				
			||||||
		return nil, nil, nil, ErrNoNodesAvailable
 | 
							return nil, nil, nil, ErrNoNodesAvailable
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	potentialNodes := nodesWherePreemptionMightHelp(allNodes, fitError.FailedPredicates)
 | 
						potentialNodes := nodesWherePreemptionMightHelp(allNodes, fitError)
 | 
				
			||||||
	if len(potentialNodes) == 0 {
 | 
						if len(potentialNodes) == 0 {
 | 
				
			||||||
		klog.V(3).Infof("Preemption will not help schedule pod %v/%v on any node.", pod.Namespace, pod.Name)
 | 
							klog.V(3).Infof("Preemption will not help schedule pod %v/%v on any node.", pod.Namespace, pod.Name)
 | 
				
			||||||
		// In this case, we should clean-up any existing nominated node name of the pod.
 | 
							// In this case, we should clean-up any existing nominated node name of the pod.
 | 
				
			||||||
@@ -509,7 +509,7 @@ func (g *genericScheduler) findNodesThatFit(pluginContext *framework.PluginConte
 | 
				
			|||||||
				if !status.IsSuccess() {
 | 
									if !status.IsSuccess() {
 | 
				
			||||||
					predicateResultLock.Lock()
 | 
										predicateResultLock.Lock()
 | 
				
			||||||
					filteredNodesStatuses[nodeName] = status
 | 
										filteredNodesStatuses[nodeName] = status
 | 
				
			||||||
					if status.Code() != framework.Unschedulable {
 | 
										if !status.IsUnschedulable() {
 | 
				
			||||||
						errs[status.Message()]++
 | 
											errs[status.Message()]++
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					predicateResultLock.Unlock()
 | 
										predicateResultLock.Unlock()
 | 
				
			||||||
@@ -1168,10 +1168,13 @@ func unresolvablePredicateExists(failedPredicates []predicates.PredicateFailureR
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// nodesWherePreemptionMightHelp returns a list of nodes with failed predicates
 | 
					// nodesWherePreemptionMightHelp returns a list of nodes with failed predicates
 | 
				
			||||||
// that may be satisfied by removing pods from the node.
 | 
					// that may be satisfied by removing pods from the node.
 | 
				
			||||||
func nodesWherePreemptionMightHelp(nodes []*v1.Node, failedPredicatesMap FailedPredicateMap) []*v1.Node {
 | 
					func nodesWherePreemptionMightHelp(nodes []*v1.Node, fitErr *FitError) []*v1.Node {
 | 
				
			||||||
	potentialNodes := []*v1.Node{}
 | 
						potentialNodes := []*v1.Node{}
 | 
				
			||||||
	for _, node := range nodes {
 | 
						for _, node := range nodes {
 | 
				
			||||||
		failedPredicates, _ := failedPredicatesMap[node.Name]
 | 
							if fitErr.FilteredNodesStatuses[node.Name].Code() == framework.UnschedulableAndUnresolvable {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							failedPredicates, _ := fitErr.FailedPredicates[node.Name]
 | 
				
			||||||
		// If we assume that scheduler looks at all nodes and populates the failedPredicateMap
 | 
							// If we assume that scheduler looks at all nodes and populates the failedPredicateMap
 | 
				
			||||||
		// (which is the case today), the !found case should never happen, but we'd prefer
 | 
							// (which is the case today), the !found case should never happen, but we'd prefer
 | 
				
			||||||
		// to rely less on such assumptions in the code when checking does not impose
 | 
							// to rely less on such assumptions in the code when checking does not impose
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -144,7 +144,7 @@ var emptyFramework, _ = framework.NewFramework(EmptyPluginRegistry, nil, []sched
 | 
				
			|||||||
// FakeFilterPlugin is a test filter plugin used by default scheduler.
 | 
					// FakeFilterPlugin is a test filter plugin used by default scheduler.
 | 
				
			||||||
type FakeFilterPlugin struct {
 | 
					type FakeFilterPlugin struct {
 | 
				
			||||||
	numFilterCalled int32
 | 
						numFilterCalled int32
 | 
				
			||||||
	failFilter      bool
 | 
						returnCode      framework.Code
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var filterPlugin = &FakeFilterPlugin{}
 | 
					var filterPlugin = &FakeFilterPlugin{}
 | 
				
			||||||
@@ -157,7 +157,7 @@ func (fp *FakeFilterPlugin) Name() string {
 | 
				
			|||||||
// reset is used to reset filter plugin.
 | 
					// reset is used to reset filter plugin.
 | 
				
			||||||
func (fp *FakeFilterPlugin) reset() {
 | 
					func (fp *FakeFilterPlugin) reset() {
 | 
				
			||||||
	fp.numFilterCalled = 0
 | 
						fp.numFilterCalled = 0
 | 
				
			||||||
	fp.failFilter = false
 | 
						fp.returnCode = framework.Success
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Filter is a test function that returns an error or nil, depending on the
 | 
					// Filter is a test function that returns an error or nil, depending on the
 | 
				
			||||||
@@ -165,11 +165,11 @@ func (fp *FakeFilterPlugin) reset() {
 | 
				
			|||||||
func (fp *FakeFilterPlugin) Filter(pc *framework.PluginContext, pod *v1.Pod, nodeName string) *framework.Status {
 | 
					func (fp *FakeFilterPlugin) Filter(pc *framework.PluginContext, pod *v1.Pod, nodeName string) *framework.Status {
 | 
				
			||||||
	atomic.AddInt32(&fp.numFilterCalled, 1)
 | 
						atomic.AddInt32(&fp.numFilterCalled, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if fp.failFilter {
 | 
						if fp.returnCode == framework.Success {
 | 
				
			||||||
		return framework.NewStatus(framework.Unschedulable, fmt.Sprintf("injecting failure for pod %v", pod.Name))
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return framework.NewStatus(fp.returnCode, fmt.Sprintf("injecting failure for pod %v", pod.Name))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewFilterPlugin is the factory for filter plugin.
 | 
					// NewFilterPlugin is the factory for filter plugin.
 | 
				
			||||||
@@ -282,7 +282,7 @@ func TestGenericScheduler(t *testing.T) {
 | 
				
			|||||||
		pod                      *v1.Pod
 | 
							pod                      *v1.Pod
 | 
				
			||||||
		pods                     []*v1.Pod
 | 
							pods                     []*v1.Pod
 | 
				
			||||||
		buildPredMeta            bool // build predicates metadata or not
 | 
							buildPredMeta            bool // build predicates metadata or not
 | 
				
			||||||
		failFilter               bool
 | 
							filterReturnCode         framework.Code
 | 
				
			||||||
		expectedHosts            sets.String
 | 
							expectedHosts            sets.String
 | 
				
			||||||
		expectsErr               bool
 | 
							expectsErr               bool
 | 
				
			||||||
		wErr                     error
 | 
							wErr                     error
 | 
				
			||||||
@@ -598,13 +598,13 @@ func TestGenericScheduler(t *testing.T) {
 | 
				
			|||||||
			wErr:          nil,
 | 
								wErr:          nil,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:          "test with failed filter plugin",
 | 
								name:             "test with filter plugin returning Unschedulable status",
 | 
				
			||||||
			predicates:       map[string]algorithmpredicates.FitPredicate{"true": truePredicate},
 | 
								predicates:       map[string]algorithmpredicates.FitPredicate{"true": truePredicate},
 | 
				
			||||||
			prioritizers:     []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
 | 
								prioritizers:     []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
 | 
				
			||||||
			nodes:            []string{"3"},
 | 
								nodes:            []string{"3"},
 | 
				
			||||||
			pod:              &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
 | 
								pod:              &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
 | 
				
			||||||
			expectedHosts:    nil,
 | 
								expectedHosts:    nil,
 | 
				
			||||||
			failFilter:    true,
 | 
								filterReturnCode: framework.Unschedulable,
 | 
				
			||||||
			expectsErr:       true,
 | 
								expectsErr:       true,
 | 
				
			||||||
			wErr: &FitError{
 | 
								wErr: &FitError{
 | 
				
			||||||
				Pod:              &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
 | 
									Pod:              &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
 | 
				
			||||||
@@ -615,10 +615,28 @@ func TestGenericScheduler(t *testing.T) {
 | 
				
			|||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:             "test with filter plugin returning UnschedulableAndUnresolvable status",
 | 
				
			||||||
 | 
								predicates:       map[string]algorithmpredicates.FitPredicate{"true": truePredicate},
 | 
				
			||||||
 | 
								prioritizers:     []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
 | 
				
			||||||
 | 
								nodes:            []string{"3"},
 | 
				
			||||||
 | 
								pod:              &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
 | 
				
			||||||
 | 
								expectedHosts:    nil,
 | 
				
			||||||
 | 
								filterReturnCode: framework.UnschedulableAndUnresolvable,
 | 
				
			||||||
 | 
								expectsErr:       true,
 | 
				
			||||||
 | 
								wErr: &FitError{
 | 
				
			||||||
 | 
									Pod:              &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
 | 
				
			||||||
 | 
									NumAllNodes:      1,
 | 
				
			||||||
 | 
									FailedPredicates: FailedPredicateMap{},
 | 
				
			||||||
 | 
									FilteredNodesStatuses: framework.NodeToStatusMap{
 | 
				
			||||||
 | 
										"3": framework.NewStatus(framework.UnschedulableAndUnresolvable, "injecting failure for pod test-filter"),
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, test := range tests {
 | 
						for _, test := range tests {
 | 
				
			||||||
		t.Run(test.name, func(t *testing.T) {
 | 
							t.Run(test.name, func(t *testing.T) {
 | 
				
			||||||
			filterPlugin.failFilter = test.failFilter
 | 
								filterPlugin.returnCode = test.filterReturnCode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			cache := internalcache.New(time.Duration(0), wait.NeverStop)
 | 
								cache := internalcache.New(time.Duration(0), wait.NeverStop)
 | 
				
			||||||
			for _, pod := range test.pods {
 | 
								for _, pod := range test.pods {
 | 
				
			||||||
@@ -1561,7 +1579,7 @@ func TestPickOneNodeForPreemption(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestNodesWherePreemptionMightHelp(t *testing.T) {
 | 
					func TestNodesWherePreemptionMightHelp(t *testing.T) {
 | 
				
			||||||
	// Prepare 4 node names.
 | 
						// Prepare 4 node names.
 | 
				
			||||||
	nodeNames := []string{}
 | 
						nodeNames := make([]string, 0, 4)
 | 
				
			||||||
	for i := 1; i < 5; i++ {
 | 
						for i := 1; i < 5; i++ {
 | 
				
			||||||
		nodeNames = append(nodeNames, fmt.Sprintf("machine%d", i))
 | 
							nodeNames = append(nodeNames, fmt.Sprintf("machine%d", i))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1569,6 +1587,7 @@ func TestNodesWherePreemptionMightHelp(t *testing.T) {
 | 
				
			|||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		name          string
 | 
							name          string
 | 
				
			||||||
		failedPredMap FailedPredicateMap
 | 
							failedPredMap FailedPredicateMap
 | 
				
			||||||
 | 
							nodesStatuses framework.NodeToStatusMap
 | 
				
			||||||
		expected      map[string]bool // set of expected node names. Value is ignored.
 | 
							expected      map[string]bool // set of expected node names. Value is ignored.
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -1652,11 +1671,41 @@ func TestNodesWherePreemptionMightHelp(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			expected: map[string]bool{"machine1": true, "machine3": true, "machine4": true},
 | 
								expected: map[string]bool{"machine1": true, "machine3": true, "machine4": true},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:          "UnschedulableAndUnresolvable status should be skipped but Unschedulable should be tried",
 | 
				
			||||||
 | 
								failedPredMap: FailedPredicateMap{},
 | 
				
			||||||
 | 
								nodesStatuses: framework.NodeToStatusMap{
 | 
				
			||||||
 | 
									"machine2": framework.NewStatus(framework.UnschedulableAndUnresolvable, ""),
 | 
				
			||||||
 | 
									"machine3": framework.NewStatus(framework.Unschedulable, ""),
 | 
				
			||||||
 | 
									"machine4": framework.NewStatus(framework.UnschedulableAndUnresolvable, ""),
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expected: map[string]bool{"machine1": true, "machine3": true},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "Failed predicates and statuses should be evaluated",
 | 
				
			||||||
 | 
								failedPredMap: FailedPredicateMap{
 | 
				
			||||||
 | 
									"machine1": []algorithmpredicates.PredicateFailureReason{algorithmpredicates.ErrPodAffinityNotMatch},
 | 
				
			||||||
 | 
									"machine2": []algorithmpredicates.PredicateFailureReason{algorithmpredicates.ErrPodAffinityNotMatch},
 | 
				
			||||||
 | 
									"machine3": []algorithmpredicates.PredicateFailureReason{algorithmpredicates.ErrPodNotMatchHostName},
 | 
				
			||||||
 | 
									"machine4": []algorithmpredicates.PredicateFailureReason{algorithmpredicates.ErrPodNotMatchHostName},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								nodesStatuses: framework.NodeToStatusMap{
 | 
				
			||||||
 | 
									"machine1": framework.NewStatus(framework.Unschedulable, ""),
 | 
				
			||||||
 | 
									"machine2": framework.NewStatus(framework.UnschedulableAndUnresolvable, ""),
 | 
				
			||||||
 | 
									"machine3": framework.NewStatus(framework.Unschedulable, ""),
 | 
				
			||||||
 | 
									"machine4": framework.NewStatus(framework.UnschedulableAndUnresolvable, ""),
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expected: map[string]bool{"machine1": true},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, test := range tests {
 | 
						for _, test := range tests {
 | 
				
			||||||
		t.Run(test.name, func(t *testing.T) {
 | 
							t.Run(test.name, func(t *testing.T) {
 | 
				
			||||||
			nodes := nodesWherePreemptionMightHelp(makeNodeList(nodeNames), test.failedPredMap)
 | 
								fitErr := FitError{
 | 
				
			||||||
 | 
									FailedPredicates:      test.failedPredMap,
 | 
				
			||||||
 | 
									FilteredNodesStatuses: test.nodesStatuses,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								nodes := nodesWherePreemptionMightHelp(makeNodeList(nodeNames), &fitErr)
 | 
				
			||||||
			if len(test.expected) != len(nodes) {
 | 
								if len(test.expected) != len(nodes) {
 | 
				
			||||||
				t.Errorf("number of nodes is not the same as expected. exptectd: %d, got: %d. Nodes: %v", len(test.expected), len(nodes), nodes)
 | 
									t.Errorf("number of nodes is not the same as expected. exptectd: %d, got: %d. Nodes: %v", len(test.expected), len(nodes), nodes)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -292,7 +292,7 @@ func (f *framework) RunPreFilterPlugins(
 | 
				
			|||||||
	for _, pl := range f.preFilterPlugins {
 | 
						for _, pl := range f.preFilterPlugins {
 | 
				
			||||||
		status := pl.PreFilter(pc, pod)
 | 
							status := pl.PreFilter(pc, pod)
 | 
				
			||||||
		if !status.IsSuccess() {
 | 
							if !status.IsSuccess() {
 | 
				
			||||||
			if status.Code() == Unschedulable {
 | 
								if status.IsUnschedulable() {
 | 
				
			||||||
				msg := fmt.Sprintf("rejected by %q at prefilter: %v", pl.Name(), status.Message())
 | 
									msg := fmt.Sprintf("rejected by %q at prefilter: %v", pl.Name(), status.Message())
 | 
				
			||||||
				klog.V(4).Infof(msg)
 | 
									klog.V(4).Infof(msg)
 | 
				
			||||||
				return NewStatus(status.Code(), msg)
 | 
									return NewStatus(status.Code(), msg)
 | 
				
			||||||
@@ -315,7 +315,7 @@ func (f *framework) RunFilterPlugins(pc *PluginContext,
 | 
				
			|||||||
	for _, pl := range f.filterPlugins {
 | 
						for _, pl := range f.filterPlugins {
 | 
				
			||||||
		status := pl.Filter(pc, pod, nodeName)
 | 
							status := pl.Filter(pc, pod, nodeName)
 | 
				
			||||||
		if !status.IsSuccess() {
 | 
							if !status.IsSuccess() {
 | 
				
			||||||
			if status.Code() != Unschedulable {
 | 
								if !status.IsUnschedulable() {
 | 
				
			||||||
				errMsg := fmt.Sprintf("error while running %q filter plugin for pod %q: %v",
 | 
									errMsg := fmt.Sprintf("error while running %q filter plugin for pod %q: %v",
 | 
				
			||||||
					pl.Name(), pod.Name, status.Message())
 | 
										pl.Name(), pod.Name, status.Message())
 | 
				
			||||||
				klog.Error(errMsg)
 | 
									klog.Error(errMsg)
 | 
				
			||||||
@@ -433,7 +433,7 @@ func (f *framework) RunPreBindPlugins(
 | 
				
			|||||||
	for _, pl := range f.preBindPlugins {
 | 
						for _, pl := range f.preBindPlugins {
 | 
				
			||||||
		status := pl.PreBind(pc, pod, nodeName)
 | 
							status := pl.PreBind(pc, pod, nodeName)
 | 
				
			||||||
		if !status.IsSuccess() {
 | 
							if !status.IsSuccess() {
 | 
				
			||||||
			if status.Code() == Unschedulable {
 | 
								if status.IsUnschedulable() {
 | 
				
			||||||
				msg := fmt.Sprintf("rejected by %q at prebind: %v", pl.Name(), status.Message())
 | 
									msg := fmt.Sprintf("rejected by %q at prebind: %v", pl.Name(), status.Message())
 | 
				
			||||||
				klog.V(4).Infof(msg)
 | 
									klog.V(4).Infof(msg)
 | 
				
			||||||
				return NewStatus(status.Code(), msg)
 | 
									return NewStatus(status.Code(), msg)
 | 
				
			||||||
@@ -513,7 +513,7 @@ func (f *framework) RunPermitPlugins(
 | 
				
			|||||||
	for _, pl := range f.permitPlugins {
 | 
						for _, pl := range f.permitPlugins {
 | 
				
			||||||
		status, d := pl.Permit(pc, pod, nodeName)
 | 
							status, d := pl.Permit(pc, pod, nodeName)
 | 
				
			||||||
		if !status.IsSuccess() {
 | 
							if !status.IsSuccess() {
 | 
				
			||||||
			if status.Code() == Unschedulable {
 | 
								if status.IsUnschedulable() {
 | 
				
			||||||
				msg := fmt.Sprintf("rejected by %q at permit: %v", pl.Name(), status.Message())
 | 
									msg := fmt.Sprintf("rejected by %q at permit: %v", pl.Name(), status.Message())
 | 
				
			||||||
				klog.V(4).Infof(msg)
 | 
									klog.V(4).Infof(msg)
 | 
				
			||||||
				return NewStatus(status.Code(), msg)
 | 
									return NewStatus(status.Code(), msg)
 | 
				
			||||||
@@ -547,7 +547,7 @@ func (f *framework) RunPermitPlugins(
 | 
				
			|||||||
			return NewStatus(Unschedulable, msg)
 | 
								return NewStatus(Unschedulable, msg)
 | 
				
			||||||
		case s := <-w.s:
 | 
							case s := <-w.s:
 | 
				
			||||||
			if !s.IsSuccess() {
 | 
								if !s.IsSuccess() {
 | 
				
			||||||
				if s.Code() == Unschedulable {
 | 
									if s.IsUnschedulable() {
 | 
				
			||||||
					msg := fmt.Sprintf("rejected while waiting at permit: %v", s.Message())
 | 
										msg := fmt.Sprintf("rejected while waiting at permit: %v", s.Message())
 | 
				
			||||||
					klog.V(4).Infof(msg)
 | 
										klog.V(4).Infof(msg)
 | 
				
			||||||
					return NewStatus(s.Code(), msg)
 | 
										return NewStatus(s.Code(), msg)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,9 +53,16 @@ const (
 | 
				
			|||||||
	Success Code = iota
 | 
						Success Code = iota
 | 
				
			||||||
	// Error is used for internal plugin errors, unexpected input, etc.
 | 
						// Error is used for internal plugin errors, unexpected input, etc.
 | 
				
			||||||
	Error
 | 
						Error
 | 
				
			||||||
	// Unschedulable is used when a plugin finds a pod unschedulable.
 | 
						// Unschedulable is used when a plugin finds a pod unschedulable. The scheduler might attempt to
 | 
				
			||||||
 | 
						// preempt other pods to get this pod scheduled. Use UnschedulableAndUnresolvable to make the
 | 
				
			||||||
 | 
						// scheduler skip preemption.
 | 
				
			||||||
	// The accompanying status message should explain why the pod is unschedulable.
 | 
						// The accompanying status message should explain why the pod is unschedulable.
 | 
				
			||||||
	Unschedulable
 | 
						Unschedulable
 | 
				
			||||||
 | 
						// UnschedulableAndUnresolvable is used when a (pre-)filter plugin finds a pod unschedulable and
 | 
				
			||||||
 | 
						// preemption would not change anything. Plugins should return Unschedulable if it is possible
 | 
				
			||||||
 | 
						// that the pod can get scheduled with preemption.
 | 
				
			||||||
 | 
						// The accompanying status message should explain why the pod is unschedulable.
 | 
				
			||||||
 | 
						UnschedulableAndUnresolvable
 | 
				
			||||||
	// Wait is used when a permit plugin finds a pod scheduling should wait.
 | 
						// Wait is used when a permit plugin finds a pod scheduling should wait.
 | 
				
			||||||
	Wait
 | 
						Wait
 | 
				
			||||||
	// Skip is used when a bind plugin chooses to skip binding.
 | 
						// Skip is used when a bind plugin chooses to skip binding.
 | 
				
			||||||
@@ -100,6 +107,12 @@ func (s *Status) IsSuccess() bool {
 | 
				
			|||||||
	return s.Code() == Success
 | 
						return s.Code() == Success
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsUnschedulable returns true if "Status" is Unschedulable (Unschedulable or UnschedulableAndUnresolvable).
 | 
				
			||||||
 | 
					func (s *Status) IsUnschedulable() bool {
 | 
				
			||||||
 | 
						code := s.Code()
 | 
				
			||||||
 | 
						return code == Unschedulable || code == UnschedulableAndUnresolvable
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AsError returns an "error" object with the same message as that of the Status.
 | 
					// AsError returns an "error" object with the same message as that of the Status.
 | 
				
			||||||
func (s *Status) AsError() error {
 | 
					func (s *Status) AsError() error {
 | 
				
			||||||
	if s.IsSuccess() {
 | 
						if s.IsSuccess() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -615,7 +615,7 @@ func (sched *Scheduler) scheduleOne() {
 | 
				
			|||||||
		permitStatus := fwk.RunPermitPlugins(pluginContext, assumedPod, scheduleResult.SuggestedHost)
 | 
							permitStatus := fwk.RunPermitPlugins(pluginContext, assumedPod, scheduleResult.SuggestedHost)
 | 
				
			||||||
		if !permitStatus.IsSuccess() {
 | 
							if !permitStatus.IsSuccess() {
 | 
				
			||||||
			var reason string
 | 
								var reason string
 | 
				
			||||||
			if permitStatus.Code() == framework.Unschedulable {
 | 
								if permitStatus.IsUnschedulable() {
 | 
				
			||||||
				metrics.PodScheduleFailures.Inc()
 | 
									metrics.PodScheduleFailures.Inc()
 | 
				
			||||||
				reason = v1.PodReasonUnschedulable
 | 
									reason = v1.PodReasonUnschedulable
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
@@ -635,7 +635,7 @@ func (sched *Scheduler) scheduleOne() {
 | 
				
			|||||||
		preBindStatus := fwk.RunPreBindPlugins(pluginContext, assumedPod, scheduleResult.SuggestedHost)
 | 
							preBindStatus := fwk.RunPreBindPlugins(pluginContext, assumedPod, scheduleResult.SuggestedHost)
 | 
				
			||||||
		if !preBindStatus.IsSuccess() {
 | 
							if !preBindStatus.IsSuccess() {
 | 
				
			||||||
			var reason string
 | 
								var reason string
 | 
				
			||||||
			if preBindStatus.Code() == framework.Unschedulable {
 | 
								if preBindStatus.IsUnschedulable() {
 | 
				
			||||||
				metrics.PodScheduleFailures.Inc()
 | 
									metrics.PodScheduleFailures.Inc()
 | 
				
			||||||
				reason = v1.PodReasonUnschedulable
 | 
									reason = v1.PodReasonUnschedulable
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user