mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Remove FailedResourceType and return custom error
This commit is contained in:
		
							
								
								
									
										40
									
								
								plugin/pkg/scheduler/algorithm/predicates/error.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								plugin/pkg/scheduler/algorithm/predicates/error.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes Authors All rights reserved.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package predicates
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	ErrExceededMaxPodNumber   = newInsufficientResourceError("PodCount")
 | 
			
		||||
	ErrInsufficientFreeCPU    = newInsufficientResourceError("CPU")
 | 
			
		||||
	ErrInsufficientFreeMemory = newInsufficientResourceError("Memory")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// InsufficientResourceError is an error type that indicates what kind of resource limit is
 | 
			
		||||
// hit and caused the unfitting failure.
 | 
			
		||||
type InsufficientResourceError struct {
 | 
			
		||||
	// ResourceName tells the name of the resource that is insufficient
 | 
			
		||||
	ResourceName string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newInsufficientResourceError(resourceName string) *InsufficientResourceError {
 | 
			
		||||
	return &InsufficientResourceError{resourceName}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *InsufficientResourceError) Error() string {
 | 
			
		||||
	return fmt.Sprintf("Node didn't have enough resource: %s", e.ResourceName)
 | 
			
		||||
}
 | 
			
		||||
@@ -256,8 +256,6 @@ type resourceRequest struct {
 | 
			
		||||
	memory   int64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var FailedResourceType string
 | 
			
		||||
 | 
			
		||||
func getResourceRequest(pod *api.Pod) resourceRequest {
 | 
			
		||||
	result := resourceRequest{}
 | 
			
		||||
	for _, container := range pod.Spec.Containers {
 | 
			
		||||
@@ -308,8 +306,7 @@ func (r *ResourceFit) PodFitsResources(pod *api.Pod, existingPods []*api.Pod, no
 | 
			
		||||
 | 
			
		||||
	if int64(len(existingPods))+1 > info.Status.Capacity.Pods().Value() {
 | 
			
		||||
		glog.V(10).Infof("Cannot schedule Pod %+v, because Node %+v is full, running %v out of %v Pods.", podName(pod), node, len(existingPods), info.Status.Capacity.Pods().Value())
 | 
			
		||||
		FailedResourceType = "PodExceedsMaxPodNumber"
 | 
			
		||||
		return false, nil
 | 
			
		||||
		return false, ErrExceededMaxPodNumber
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	podRequest := getResourceRequest(pod)
 | 
			
		||||
@@ -321,13 +318,11 @@ func (r *ResourceFit) PodFitsResources(pod *api.Pod, existingPods []*api.Pod, no
 | 
			
		||||
	_, exceedingCPU, exceedingMemory := CheckPodsExceedingFreeResources(pods, info.Status.Capacity)
 | 
			
		||||
	if len(exceedingCPU) > 0 {
 | 
			
		||||
		glog.V(10).Infof("Cannot schedule Pod %+v, because Node %v does not have sufficient CPU", podName(pod), node)
 | 
			
		||||
		FailedResourceType = "PodExceedsFreeCPU"
 | 
			
		||||
		return false, nil
 | 
			
		||||
		return false, ErrInsufficientFreeCPU
 | 
			
		||||
	}
 | 
			
		||||
	if len(exceedingMemory) > 0 {
 | 
			
		||||
		glog.V(10).Infof("Cannot schedule Pod %+v, because Node %v does not have sufficient Memory", podName(pod), node)
 | 
			
		||||
		FailedResourceType = "PodExceedsFreeMemory"
 | 
			
		||||
		return false, nil
 | 
			
		||||
		return false, ErrInsufficientFreeMemory
 | 
			
		||||
	}
 | 
			
		||||
	glog.V(10).Infof("Schedule Pod %+v on Node %+v is allowed, Node is running only %v out of %v Pods.", podName(pod), node, len(pods)-1, info.Status.Capacity.Pods().Value())
 | 
			
		||||
	return true, nil
 | 
			
		||||
 
 | 
			
		||||
@@ -80,6 +80,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
			
		||||
		existingPods []*api.Pod
 | 
			
		||||
		fits         bool
 | 
			
		||||
		test         string
 | 
			
		||||
		wErr         error
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			pod: &api.Pod{},
 | 
			
		||||
@@ -88,6 +89,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			fits: true,
 | 
			
		||||
			test: "no resources requested always fits",
 | 
			
		||||
			wErr: nil,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pod: newResourcePod(resourceRequest{milliCPU: 1, memory: 1}),
 | 
			
		||||
@@ -96,6 +98,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			fits: false,
 | 
			
		||||
			test: "too many resources fails",
 | 
			
		||||
			wErr: ErrInsufficientFreeCPU,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pod: newResourcePod(resourceRequest{milliCPU: 1, memory: 1}),
 | 
			
		||||
@@ -104,6 +107,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			fits: true,
 | 
			
		||||
			test: "both resources fit",
 | 
			
		||||
			wErr: nil,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pod: newResourcePod(resourceRequest{milliCPU: 1, memory: 2}),
 | 
			
		||||
@@ -112,6 +116,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			fits: false,
 | 
			
		||||
			test: "one resources fits",
 | 
			
		||||
			wErr: ErrInsufficientFreeMemory,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pod: newResourcePod(resourceRequest{milliCPU: 5, memory: 1}),
 | 
			
		||||
@@ -120,6 +125,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			fits: true,
 | 
			
		||||
			test: "equal edge case",
 | 
			
		||||
			wErr: nil,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -128,8 +134,8 @@ func TestPodFitsResources(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
		fit := ResourceFit{FakeNodeInfo(node)}
 | 
			
		||||
		fits, err := fit.PodFitsResources(test.pod, test.existingPods, "machine")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			t.Errorf("unexpected error: %v", err)
 | 
			
		||||
		if !reflect.DeepEqual(err, test.wErr) {
 | 
			
		||||
			t.Errorf("%s: unexpected error: %v, want: %v", test.test, err, test.wErr)
 | 
			
		||||
		}
 | 
			
		||||
		if fits != test.fits {
 | 
			
		||||
			t.Errorf("%s: expected: %v got %v", test.test, test.fits, fits)
 | 
			
		||||
@@ -141,6 +147,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
			
		||||
		existingPods []*api.Pod
 | 
			
		||||
		fits         bool
 | 
			
		||||
		test         string
 | 
			
		||||
		wErr         error
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			pod: &api.Pod{},
 | 
			
		||||
@@ -149,6 +156,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			fits: false,
 | 
			
		||||
			test: "even without specified resources predicate fails when there's no available ips",
 | 
			
		||||
			wErr: ErrExceededMaxPodNumber,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pod: newResourcePod(resourceRequest{milliCPU: 1, memory: 1}),
 | 
			
		||||
@@ -157,6 +165,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			fits: false,
 | 
			
		||||
			test: "even if both resources fit predicate fails when there's no available ips",
 | 
			
		||||
			wErr: ErrExceededMaxPodNumber,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pod: newResourcePod(resourceRequest{milliCPU: 5, memory: 1}),
 | 
			
		||||
@@ -165,6 +174,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			fits: false,
 | 
			
		||||
			test: "even for equal edge case predicate fails when there's no available ips",
 | 
			
		||||
			wErr: ErrExceededMaxPodNumber,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, test := range notEnoughPodsTests {
 | 
			
		||||
@@ -172,8 +182,8 @@ func TestPodFitsResources(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
		fit := ResourceFit{FakeNodeInfo(node)}
 | 
			
		||||
		fits, err := fit.PodFitsResources(test.pod, test.existingPods, "machine")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			t.Errorf("unexpected error: %v", err)
 | 
			
		||||
		if !reflect.DeepEqual(err, test.wErr) {
 | 
			
		||||
			t.Errorf("%s: unexpected error: %v, want: %v", test.test, err, test.wErr)
 | 
			
		||||
		}
 | 
			
		||||
		if fits != test.fits {
 | 
			
		||||
			t.Errorf("%s: expected: %v got %v", test.test, test.fits, fits)
 | 
			
		||||
 
 | 
			
		||||
@@ -127,18 +127,21 @@ func findNodesThatFit(pod *api.Pod, machineToPods map[string][]*api.Pod, predica
 | 
			
		||||
	for _, node := range nodes.Items {
 | 
			
		||||
		fits := true
 | 
			
		||||
		for name, predicate := range predicateFuncs {
 | 
			
		||||
			predicates.FailedResourceType = ""
 | 
			
		||||
			fit, err := predicate(pod, machineToPods[node.Name], node.Name)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return api.NodeList{}, FailedPredicateMap{}, err
 | 
			
		||||
				switch err.(type) {
 | 
			
		||||
				case *predicates.InsufficientResourceError:
 | 
			
		||||
				default:
 | 
			
		||||
					return api.NodeList{}, FailedPredicateMap{}, err
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if !fit {
 | 
			
		||||
				fits = false
 | 
			
		||||
				if _, found := failedPredicateMap[node.Name]; !found {
 | 
			
		||||
					failedPredicateMap[node.Name] = sets.String{}
 | 
			
		||||
				}
 | 
			
		||||
				if predicates.FailedResourceType != "" {
 | 
			
		||||
					failedPredicateMap[node.Name].Insert(predicates.FailedResourceType)
 | 
			
		||||
				if re, ok := err.(*predicates.InsufficientResourceError); ok {
 | 
			
		||||
					failedPredicateMap[node.Name].Insert(re.ResourceName)
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
				failedPredicateMap[node.Name].Insert(name)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user