Merge pull request #19296 from hongchaodeng/pred
Auto commit by PR queue bot
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
 | 
						memory   int64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var FailedResourceType string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func getResourceRequest(pod *api.Pod) resourceRequest {
 | 
					func getResourceRequest(pod *api.Pod) resourceRequest {
 | 
				
			||||||
	result := resourceRequest{}
 | 
						result := resourceRequest{}
 | 
				
			||||||
	for _, container := range pod.Spec.Containers {
 | 
						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() {
 | 
						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())
 | 
							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, ErrExceededMaxPodNumber
 | 
				
			||||||
		return false, nil
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	podRequest := getResourceRequest(pod)
 | 
						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)
 | 
						_, exceedingCPU, exceedingMemory := CheckPodsExceedingFreeResources(pods, info.Status.Capacity)
 | 
				
			||||||
	if len(exceedingCPU) > 0 {
 | 
						if len(exceedingCPU) > 0 {
 | 
				
			||||||
		glog.V(10).Infof("Cannot schedule Pod %+v, because Node %v does not have sufficient CPU", podName(pod), node)
 | 
							glog.V(10).Infof("Cannot schedule Pod %+v, because Node %v does not have sufficient CPU", podName(pod), node)
 | 
				
			||||||
		FailedResourceType = "PodExceedsFreeCPU"
 | 
							return false, ErrInsufficientFreeCPU
 | 
				
			||||||
		return false, nil
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(exceedingMemory) > 0 {
 | 
						if len(exceedingMemory) > 0 {
 | 
				
			||||||
		glog.V(10).Infof("Cannot schedule Pod %+v, because Node %v does not have sufficient Memory", podName(pod), node)
 | 
							glog.V(10).Infof("Cannot schedule Pod %+v, because Node %v does not have sufficient Memory", podName(pod), node)
 | 
				
			||||||
		FailedResourceType = "PodExceedsFreeMemory"
 | 
							return false, ErrInsufficientFreeMemory
 | 
				
			||||||
		return false, nil
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	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())
 | 
						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
 | 
						return true, nil
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,6 +80,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
				
			|||||||
		existingPods []*api.Pod
 | 
							existingPods []*api.Pod
 | 
				
			||||||
		fits         bool
 | 
							fits         bool
 | 
				
			||||||
		test         string
 | 
							test         string
 | 
				
			||||||
 | 
							wErr         error
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			pod: &api.Pod{},
 | 
								pod: &api.Pod{},
 | 
				
			||||||
@@ -88,6 +89,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			fits: true,
 | 
								fits: true,
 | 
				
			||||||
			test: "no resources requested always fits",
 | 
								test: "no resources requested always fits",
 | 
				
			||||||
 | 
								wErr: nil,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			pod: newResourcePod(resourceRequest{milliCPU: 1, memory: 1}),
 | 
								pod: newResourcePod(resourceRequest{milliCPU: 1, memory: 1}),
 | 
				
			||||||
@@ -96,6 +98,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			fits: false,
 | 
								fits: false,
 | 
				
			||||||
			test: "too many resources fails",
 | 
								test: "too many resources fails",
 | 
				
			||||||
 | 
								wErr: ErrInsufficientFreeCPU,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			pod: newResourcePod(resourceRequest{milliCPU: 1, memory: 1}),
 | 
								pod: newResourcePod(resourceRequest{milliCPU: 1, memory: 1}),
 | 
				
			||||||
@@ -104,6 +107,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			fits: true,
 | 
								fits: true,
 | 
				
			||||||
			test: "both resources fit",
 | 
								test: "both resources fit",
 | 
				
			||||||
 | 
								wErr: nil,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			pod: newResourcePod(resourceRequest{milliCPU: 1, memory: 2}),
 | 
								pod: newResourcePod(resourceRequest{milliCPU: 1, memory: 2}),
 | 
				
			||||||
@@ -112,6 +116,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			fits: false,
 | 
								fits: false,
 | 
				
			||||||
			test: "one resources fits",
 | 
								test: "one resources fits",
 | 
				
			||||||
 | 
								wErr: ErrInsufficientFreeMemory,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			pod: newResourcePod(resourceRequest{milliCPU: 5, memory: 1}),
 | 
								pod: newResourcePod(resourceRequest{milliCPU: 5, memory: 1}),
 | 
				
			||||||
@@ -120,6 +125,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			fits: true,
 | 
								fits: true,
 | 
				
			||||||
			test: "equal edge case",
 | 
								test: "equal edge case",
 | 
				
			||||||
 | 
								wErr: nil,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -128,8 +134,8 @@ func TestPodFitsResources(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		fit := ResourceFit{FakeNodeInfo(node)}
 | 
							fit := ResourceFit{FakeNodeInfo(node)}
 | 
				
			||||||
		fits, err := fit.PodFitsResources(test.pod, test.existingPods, "machine")
 | 
							fits, err := fit.PodFitsResources(test.pod, test.existingPods, "machine")
 | 
				
			||||||
		if err != nil {
 | 
							if !reflect.DeepEqual(err, test.wErr) {
 | 
				
			||||||
			t.Errorf("unexpected error: %v", err)
 | 
								t.Errorf("%s: unexpected error: %v, want: %v", test.test, err, test.wErr)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if fits != test.fits {
 | 
							if fits != test.fits {
 | 
				
			||||||
			t.Errorf("%s: expected: %v got %v", test.test, test.fits, 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
 | 
							existingPods []*api.Pod
 | 
				
			||||||
		fits         bool
 | 
							fits         bool
 | 
				
			||||||
		test         string
 | 
							test         string
 | 
				
			||||||
 | 
							wErr         error
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			pod: &api.Pod{},
 | 
								pod: &api.Pod{},
 | 
				
			||||||
@@ -149,6 +156,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			fits: false,
 | 
								fits: false,
 | 
				
			||||||
			test: "even without specified resources predicate fails when there's no available ips",
 | 
								test: "even without specified resources predicate fails when there's no available ips",
 | 
				
			||||||
 | 
								wErr: ErrExceededMaxPodNumber,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			pod: newResourcePod(resourceRequest{milliCPU: 1, memory: 1}),
 | 
								pod: newResourcePod(resourceRequest{milliCPU: 1, memory: 1}),
 | 
				
			||||||
@@ -157,6 +165,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			fits: false,
 | 
								fits: false,
 | 
				
			||||||
			test: "even if both resources fit predicate fails when there's no available ips",
 | 
								test: "even if both resources fit predicate fails when there's no available ips",
 | 
				
			||||||
 | 
								wErr: ErrExceededMaxPodNumber,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			pod: newResourcePod(resourceRequest{milliCPU: 5, memory: 1}),
 | 
								pod: newResourcePod(resourceRequest{milliCPU: 5, memory: 1}),
 | 
				
			||||||
@@ -165,6 +174,7 @@ func TestPodFitsResources(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			fits: false,
 | 
								fits: false,
 | 
				
			||||||
			test: "even for equal edge case predicate fails when there's no available ips",
 | 
								test: "even for equal edge case predicate fails when there's no available ips",
 | 
				
			||||||
 | 
								wErr: ErrExceededMaxPodNumber,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, test := range notEnoughPodsTests {
 | 
						for _, test := range notEnoughPodsTests {
 | 
				
			||||||
@@ -172,8 +182,8 @@ func TestPodFitsResources(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		fit := ResourceFit{FakeNodeInfo(node)}
 | 
							fit := ResourceFit{FakeNodeInfo(node)}
 | 
				
			||||||
		fits, err := fit.PodFitsResources(test.pod, test.existingPods, "machine")
 | 
							fits, err := fit.PodFitsResources(test.pod, test.existingPods, "machine")
 | 
				
			||||||
		if err != nil {
 | 
							if !reflect.DeepEqual(err, test.wErr) {
 | 
				
			||||||
			t.Errorf("unexpected error: %v", err)
 | 
								t.Errorf("%s: unexpected error: %v, want: %v", test.test, err, test.wErr)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if fits != test.fits {
 | 
							if fits != test.fits {
 | 
				
			||||||
			t.Errorf("%s: expected: %v got %v", test.test, test.fits, fits)
 | 
								t.Errorf("%s: expected: %v got %v", test.test, test.fits, fits)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -127,7 +127,6 @@ func findNodesThatFit(pod *api.Pod, machineToPods map[string][]*api.Pod, predica
 | 
				
			|||||||
	for _, node := range nodes.Items {
 | 
						for _, node := range nodes.Items {
 | 
				
			||||||
		fits := true
 | 
							fits := true
 | 
				
			||||||
		for name, predicate := range predicateFuncs {
 | 
							for name, predicate := range predicateFuncs {
 | 
				
			||||||
			predicates.FailedResourceType = ""
 | 
					 | 
				
			||||||
			fit, err := predicate(pod, machineToPods[node.Name], node.Name)
 | 
								fit, err := predicate(pod, machineToPods[node.Name], node.Name)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return api.NodeList{}, FailedPredicateMap{}, err
 | 
									return api.NodeList{}, FailedPredicateMap{}, err
 | 
				
			||||||
@@ -137,8 +136,8 @@ func findNodesThatFit(pod *api.Pod, machineToPods map[string][]*api.Pod, predica
 | 
				
			|||||||
				if _, found := failedPredicateMap[node.Name]; !found {
 | 
									if _, found := failedPredicateMap[node.Name]; !found {
 | 
				
			||||||
					failedPredicateMap[node.Name] = sets.String{}
 | 
										failedPredicateMap[node.Name] = sets.String{}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if predicates.FailedResourceType != "" {
 | 
									if re, ok := err.(*predicates.InsufficientResourceError); ok {
 | 
				
			||||||
					failedPredicateMap[node.Name].Insert(predicates.FailedResourceType)
 | 
										failedPredicateMap[node.Name].Insert(re.ResourceName)
 | 
				
			||||||
					break
 | 
										break
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				failedPredicateMap[node.Name].Insert(name)
 | 
									failedPredicateMap[node.Name].Insert(name)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user