From 4106eb70b0b8b729184b95c20a721fae5d333aef Mon Sep 17 00:00:00 2001 From: PingWang Date: Mon, 27 Jun 2016 17:31:46 +0800 Subject: [PATCH] modify extends.Filter Signed-off-by: PingWang Add docs Signed-off-by: PingWang add docs for ExtenderFilterResult.FailedNodes in types.go Signed-off-by: PingWang Modify the extender.Filter test. Signed-off-by: PingWang Update extender_test.go Signed-off-by: PingWang modify the comments Signed-off-by: PingWang gofmt -s scheduler_interface.go Signed-off-by: PingWang update the comments Signed-off-by: PingWang --- .../pkg/scheduler/algorithm/scheduler_interface.go | 5 +++-- plugin/pkg/scheduler/api/types.go | 5 +++++ plugin/pkg/scheduler/api/v1/types.go | 5 +++++ plugin/pkg/scheduler/extender.go | 14 ++++++++------ plugin/pkg/scheduler/extender_test.go | 9 ++++++--- plugin/pkg/scheduler/generic_scheduler.go | 6 +++++- test/integration/scheduler/extender_test.go | 12 ++++++++---- 7 files changed, 40 insertions(+), 16 deletions(-) diff --git a/plugin/pkg/scheduler/algorithm/scheduler_interface.go b/plugin/pkg/scheduler/algorithm/scheduler_interface.go index 271ff5d55a8..9b4611e397e 100644 --- a/plugin/pkg/scheduler/algorithm/scheduler_interface.go +++ b/plugin/pkg/scheduler/algorithm/scheduler_interface.go @@ -26,8 +26,9 @@ import ( // managed by Kubernetes. type SchedulerExtender interface { // Filter based on extender-implemented predicate functions. The filtered list is - // expected to be a subset of the supplied list. - Filter(pod *api.Pod, nodes []*api.Node) (filteredNodes []*api.Node, err error) + // expected to be a subset of the supplied list. failedNodesMap optionally contains + // the list of failed nodes and failure reasons. + Filter(pod *api.Pod, nodes []*api.Node) (filteredNodes []*api.Node, failedNodesMap schedulerapi.FailedNodesMap, err error) // Prioritize based on extender-implemented priority functions. The returned scores & weight // are used to compute the weighted score for an extender. The weighted scores are added to diff --git a/plugin/pkg/scheduler/api/types.go b/plugin/pkg/scheduler/api/types.go index 29d98a3b281..9e83c7802fc 100644 --- a/plugin/pkg/scheduler/api/types.go +++ b/plugin/pkg/scheduler/api/types.go @@ -139,10 +139,15 @@ type ExtenderArgs struct { Nodes api.NodeList `json:"nodes"` } +// FailedNodesMap represents the filtered out nodes, with node names and failure messages +type FailedNodesMap map[string]string + // ExtenderFilterResult represents the results of a filter call to an extender type ExtenderFilterResult struct { // Filtered set of nodes where the pod can be scheduled Nodes api.NodeList `json:"nodes,omitempty"` + // Filtered out nodes where the pod can't be scheduled and the failure messages + FailedNodes FailedNodesMap `json:"failedNodes,omitempty"` // Error message indicating failure Error string `json:"error,omitempty"` } diff --git a/plugin/pkg/scheduler/api/v1/types.go b/plugin/pkg/scheduler/api/v1/types.go index 7eef7b5a864..03401070f89 100644 --- a/plugin/pkg/scheduler/api/v1/types.go +++ b/plugin/pkg/scheduler/api/v1/types.go @@ -139,10 +139,15 @@ type ExtenderArgs struct { Nodes apiv1.NodeList `json:"nodes"` } +// FailedNodesMap represents the filtered out nodes, with node names and failure messages +type FailedNodesMap map[string]string + // ExtenderFilterResult represents the results of a filter call to an extender type ExtenderFilterResult struct { // Filtered set of nodes where the pod can be scheduled Nodes apiv1.NodeList `json:"nodes,omitempty"` + // Filtered out nodes where the pod can't be scheduled and the failure messages + FailedNodes FailedNodesMap `json:"failedNodes,omitempty"` // Error message indicating failure Error string `json:"error,omitempty"` } diff --git a/plugin/pkg/scheduler/extender.go b/plugin/pkg/scheduler/extender.go index 713e7d13c45..846e6681bc3 100644 --- a/plugin/pkg/scheduler/extender.go +++ b/plugin/pkg/scheduler/extender.go @@ -92,12 +92,13 @@ func NewHTTPExtender(config *schedulerapi.ExtenderConfig, apiVersion string) (al } // Filter based on extender implemented predicate functions. The filtered list is -// expected to be a subset of the supplied list. -func (h *HTTPExtender) Filter(pod *api.Pod, nodes []*api.Node) ([]*api.Node, error) { +// expected to be a subset of the supplied list. failedNodesMap optionally contains +// the list of failed nodes and failure reasons. +func (h *HTTPExtender) Filter(pod *api.Pod, nodes []*api.Node) ([]*api.Node, schedulerapi.FailedNodesMap, error) { var result schedulerapi.ExtenderFilterResult if h.filterVerb == "" { - return nodes, nil + return nodes, schedulerapi.FailedNodesMap{}, nil } nodeItems := make([]api.Node, 0, len(nodes)) @@ -110,16 +111,17 @@ func (h *HTTPExtender) Filter(pod *api.Pod, nodes []*api.Node) ([]*api.Node, err } if err := h.send(h.filterVerb, &args, &result); err != nil { - return nil, err + return nil, nil, err } if result.Error != "" { - return nil, fmt.Errorf(result.Error) + return nil, nil, fmt.Errorf(result.Error) } + nodeResult := make([]*api.Node, 0, len(result.Nodes.Items)) for i := range result.Nodes.Items { nodeResult = append(nodeResult, &result.Nodes.Items[i]) } - return nodeResult, nil + return nodeResult, result.FailedNodes, nil } // Prioritize based on extender implemented priority functions. Weight*priority is added diff --git a/plugin/pkg/scheduler/extender_test.go b/plugin/pkg/scheduler/extender_test.go index a8afc605546..c9feb1671b5 100644 --- a/plugin/pkg/scheduler/extender_test.go +++ b/plugin/pkg/scheduler/extender_test.go @@ -107,14 +107,15 @@ type FakeExtender struct { weight int } -func (f *FakeExtender) Filter(pod *api.Pod, nodes []*api.Node) ([]*api.Node, error) { +func (f *FakeExtender) Filter(pod *api.Pod, nodes []*api.Node) ([]*api.Node, schedulerapi.FailedNodesMap, error) { filtered := []*api.Node{} + failedNodesMap := schedulerapi.FailedNodesMap{} for _, node := range nodes { fits := true for _, predicate := range f.predicates { fit, err := predicate(pod, node) if err != nil { - return []*api.Node{}, err + return []*api.Node{}, schedulerapi.FailedNodesMap{}, err } if !fit { fits = false @@ -123,9 +124,11 @@ func (f *FakeExtender) Filter(pod *api.Pod, nodes []*api.Node) ([]*api.Node, err } if fits { filtered = append(filtered, node) + } else { + failedNodesMap[node.Name] = "FakeExtender failed" } } - return filtered, nil + return filtered, failedNodesMap, nil } func (f *FakeExtender) Prioritize(pod *api.Pod, nodes []*api.Node) (*schedulerapi.HostPriorityList, int, error) { diff --git a/plugin/pkg/scheduler/generic_scheduler.go b/plugin/pkg/scheduler/generic_scheduler.go index 4d27b63d58b..d92f0f0a3bc 100644 --- a/plugin/pkg/scheduler/generic_scheduler.go +++ b/plugin/pkg/scheduler/generic_scheduler.go @@ -183,10 +183,14 @@ func findNodesThatFit( if len(filtered) > 0 && len(extenders) != 0 { for _, extender := range extenders { - filteredList, err := extender.Filter(pod, filtered) + filteredList, failedMap, err := extender.Filter(pod, filtered) if err != nil { return []*api.Node{}, FailedPredicateMap{}, err } + + for failedNodeName, failedMsg := range failedMap { + failedPredicateMap[failedNodeName] = failedMsg + } filtered = filteredList if len(filtered) == 0 { break diff --git a/test/integration/scheduler/extender_test.go b/test/integration/scheduler/extender_test.go index 65a7abb3838..ae4c2045eec 100644 --- a/test/integration/scheduler/extender_test.go +++ b/test/integration/scheduler/extender_test.go @@ -79,11 +79,12 @@ func (e *Extender) serveHTTP(t *testing.T, w http.ResponseWriter, req *http.Requ if strings.Contains(req.URL.Path, filter) { resp := &schedulerapi.ExtenderFilterResult{} - nodes, err := e.Filter(&args.Pod, &args.Nodes) + nodes, failedNodes, err := e.Filter(&args.Pod, &args.Nodes) if err != nil { resp.Error = err.Error() } else { resp.Nodes = *nodes + resp.FailedNodes = failedNodes } if err := encoder.Encode(resp); err != nil { @@ -102,14 +103,15 @@ func (e *Extender) serveHTTP(t *testing.T, w http.ResponseWriter, req *http.Requ } } -func (e *Extender) Filter(pod *api.Pod, nodes *api.NodeList) (*api.NodeList, error) { +func (e *Extender) Filter(pod *api.Pod, nodes *api.NodeList) (*api.NodeList, schedulerapi.FailedNodesMap, error) { filtered := []api.Node{} + failedNodesMap := schedulerapi.FailedNodesMap{} for _, node := range nodes.Items { fits := true for _, predicate := range e.predicates { fit, err := predicate(pod, &node) if err != nil { - return &api.NodeList{}, err + return &api.NodeList{}, schedulerapi.FailedNodesMap{}, err } if !fit { fits = false @@ -118,9 +120,11 @@ func (e *Extender) Filter(pod *api.Pod, nodes *api.NodeList) (*api.NodeList, err } if fits { filtered = append(filtered, node) + } else { + failedNodesMap[node.Name] = fmt.Sprintf("extender failed: %s", e.name) } } - return &api.NodeList{Items: filtered}, nil + return &api.NodeList{Items: filtered}, failedNodesMap, nil } func (e *Extender) Prioritize(pod *api.Pod, nodes *api.NodeList) (*schedulerapi.HostPriorityList, error) {