Merge pull request #82072 from draveness/feature/use-context-instead-of-channel
feat(scheduler): use context in scheduler package
This commit is contained in:
@@ -22,7 +22,7 @@ import (
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
@@ -246,11 +246,11 @@ func (f *framework) QueueSortFunc() LessFunc {
|
||||
// anything but Success. If a non-success status is returned, then the scheduling
|
||||
// cycle is aborted.
|
||||
func (f *framework) RunPreFilterPlugins(
|
||||
state *CycleState, pod *v1.Pod) (status *Status) {
|
||||
ctx context.Context, state *CycleState, pod *v1.Pod) (status *Status) {
|
||||
startTime := time.Now()
|
||||
defer func() { recordExtensionPointDuration(startTime, preFilter, status) }()
|
||||
for _, pl := range f.preFilterPlugins {
|
||||
status := pl.PreFilter(state, pod)
|
||||
status := pl.PreFilter(ctx, state, pod)
|
||||
if !status.IsSuccess() {
|
||||
if status.IsUnschedulable() {
|
||||
msg := fmt.Sprintf("rejected by %q at prefilter: %v", pl.Name(), status.Message())
|
||||
@@ -269,15 +269,20 @@ func (f *framework) RunPreFilterPlugins(
|
||||
// RunPreFilterExtensionAddPod calls the AddPod interface for the set of configured
|
||||
// PreFilter plugins. It returns directly if any of the plugins return any
|
||||
// status other than Success.
|
||||
func (f *framework) RunPreFilterExtensionAddPod(state *CycleState, podToSchedule *v1.Pod,
|
||||
podToAdd *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) (status *Status) {
|
||||
func (f *framework) RunPreFilterExtensionAddPod(
|
||||
ctx context.Context,
|
||||
state *CycleState,
|
||||
podToSchedule *v1.Pod,
|
||||
podToAdd *v1.Pod,
|
||||
nodeInfo *schedulernodeinfo.NodeInfo,
|
||||
) (status *Status) {
|
||||
startTime := time.Now()
|
||||
defer func() { recordExtensionPointDuration(startTime, preFilterExtensionAddPod, status) }()
|
||||
for _, pl := range f.preFilterPlugins {
|
||||
if pl.PreFilterExtensions() == nil {
|
||||
continue
|
||||
}
|
||||
if status := pl.PreFilterExtensions().AddPod(state, podToSchedule, podToAdd, nodeInfo); !status.IsSuccess() {
|
||||
if status := pl.PreFilterExtensions().AddPod(ctx, state, podToSchedule, podToAdd, nodeInfo); !status.IsSuccess() {
|
||||
msg := fmt.Sprintf("error while running AddPod for plugin %q while scheduling pod %q: %v",
|
||||
pl.Name(), podToSchedule.Name, status.Message())
|
||||
klog.Error(msg)
|
||||
@@ -291,15 +296,20 @@ func (f *framework) RunPreFilterExtensionAddPod(state *CycleState, podToSchedule
|
||||
// RunPreFilterExtensionRemovePod calls the RemovePod interface for the set of configured
|
||||
// PreFilter plugins. It returns directly if any of the plugins return any
|
||||
// status other than Success.
|
||||
func (f *framework) RunPreFilterExtensionRemovePod(state *CycleState, podToSchedule *v1.Pod,
|
||||
podToRemove *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) (status *Status) {
|
||||
func (f *framework) RunPreFilterExtensionRemovePod(
|
||||
ctx context.Context,
|
||||
state *CycleState,
|
||||
podToSchedule *v1.Pod,
|
||||
podToRemove *v1.Pod,
|
||||
nodeInfo *schedulernodeinfo.NodeInfo,
|
||||
) (status *Status) {
|
||||
startTime := time.Now()
|
||||
defer func() { recordExtensionPointDuration(startTime, preFilterExtensionRemovePod, status) }()
|
||||
for _, pl := range f.preFilterPlugins {
|
||||
if pl.PreFilterExtensions() == nil {
|
||||
continue
|
||||
}
|
||||
if status := pl.PreFilterExtensions().RemovePod(state, podToSchedule, podToRemove, nodeInfo); !status.IsSuccess() {
|
||||
if status := pl.PreFilterExtensions().RemovePod(ctx, state, podToSchedule, podToRemove, nodeInfo); !status.IsSuccess() {
|
||||
msg := fmt.Sprintf("error while running RemovePod for plugin %q while scheduling pod %q: %v",
|
||||
pl.Name(), podToSchedule.Name, status.Message())
|
||||
klog.Error(msg)
|
||||
@@ -314,12 +324,16 @@ func (f *framework) RunPreFilterExtensionRemovePod(state *CycleState, podToSched
|
||||
// the given node. If any of these plugins doesn't return "Success", the
|
||||
// given node is not suitable for running pod.
|
||||
// Meanwhile, the failure message and status are set for the given node.
|
||||
func (f *framework) RunFilterPlugins(state *CycleState,
|
||||
pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) (status *Status) {
|
||||
func (f *framework) RunFilterPlugins(
|
||||
ctx context.Context,
|
||||
state *CycleState,
|
||||
pod *v1.Pod,
|
||||
nodeInfo *schedulernodeinfo.NodeInfo,
|
||||
) (status *Status) {
|
||||
startTime := time.Now()
|
||||
defer func() { recordExtensionPointDuration(startTime, filter, status) }()
|
||||
for _, pl := range f.filterPlugins {
|
||||
status := pl.Filter(state, pod, nodeInfo)
|
||||
status := pl.Filter(ctx, state, pod, nodeInfo)
|
||||
if !status.IsSuccess() {
|
||||
if !status.IsUnschedulable() {
|
||||
errMsg := fmt.Sprintf("error while running %q filter plugin for pod %q: %v",
|
||||
@@ -338,6 +352,7 @@ func (f *framework) RunFilterPlugins(state *CycleState,
|
||||
// of these plugins returns any status other than "Success", the given node is
|
||||
// rejected. The filteredNodeStatuses is the set of filtered nodes and their statuses.
|
||||
func (f *framework) RunPostFilterPlugins(
|
||||
ctx context.Context,
|
||||
state *CycleState,
|
||||
pod *v1.Pod,
|
||||
nodes []*v1.Node,
|
||||
@@ -346,7 +361,7 @@ func (f *framework) RunPostFilterPlugins(
|
||||
startTime := time.Now()
|
||||
defer func() { recordExtensionPointDuration(startTime, postFilter, status) }()
|
||||
for _, pl := range f.postFilterPlugins {
|
||||
status := pl.PostFilter(state, pod, nodes, filteredNodesStatuses)
|
||||
status := pl.PostFilter(ctx, state, pod, nodes, filteredNodesStatuses)
|
||||
if !status.IsSuccess() {
|
||||
msg := fmt.Sprintf("error while running %q postfilter plugin for pod %q: %v", pl.Name(), pod.Name, status.Message())
|
||||
klog.Error(msg)
|
||||
@@ -361,21 +376,21 @@ func (f *framework) RunPostFilterPlugins(
|
||||
// stores for each scoring plugin name the corresponding NodeScoreList(s).
|
||||
// It also returns *Status, which is set to non-success if any of the plugins returns
|
||||
// a non-success status.
|
||||
func (f *framework) RunScorePlugins(state *CycleState, pod *v1.Pod, nodes []*v1.Node) (ps PluginToNodeScores, status *Status) {
|
||||
func (f *framework) RunScorePlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodes []*v1.Node) (ps PluginToNodeScores, status *Status) {
|
||||
startTime := time.Now()
|
||||
defer func() { recordExtensionPointDuration(startTime, score, status) }()
|
||||
pluginToNodeScores := make(PluginToNodeScores, len(f.scorePlugins))
|
||||
for _, pl := range f.scorePlugins {
|
||||
pluginToNodeScores[pl.Name()] = make(NodeScoreList, len(nodes))
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
errCh := schedutil.NewErrorChannel()
|
||||
|
||||
// Run Score method for each node in parallel.
|
||||
workqueue.ParallelizeUntil(ctx, 16, len(nodes), func(index int) {
|
||||
for _, pl := range f.scorePlugins {
|
||||
nodeName := nodes[index].Name
|
||||
score, status := pl.Score(state, pod, nodeName)
|
||||
score, status := pl.Score(ctx, state, pod, nodeName)
|
||||
if !status.IsSuccess() {
|
||||
errCh.SendErrorWithCancel(fmt.Errorf(status.Message()), cancel)
|
||||
return
|
||||
@@ -399,7 +414,7 @@ func (f *framework) RunScorePlugins(state *CycleState, pod *v1.Pod, nodes []*v1.
|
||||
if pl.ScoreExtensions() == nil {
|
||||
return
|
||||
}
|
||||
status := pl.ScoreExtensions().NormalizeScore(state, pod, nodeScoreList)
|
||||
status := pl.ScoreExtensions().NormalizeScore(ctx, state, pod, nodeScoreList)
|
||||
if !status.IsSuccess() {
|
||||
err := fmt.Errorf("normalize score plugin %q failed with error %v", pl.Name(), status.Message())
|
||||
errCh.SendErrorWithCancel(err, cancel)
|
||||
@@ -442,11 +457,11 @@ func (f *framework) RunScorePlugins(state *CycleState, pod *v1.Pod, nodes []*v1.
|
||||
// failure (bool) if any of the plugins returns an error. It also returns an
|
||||
// error containing the rejection message or the error occurred in the plugin.
|
||||
func (f *framework) RunPreBindPlugins(
|
||||
state *CycleState, pod *v1.Pod, nodeName string) (status *Status) {
|
||||
ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) (status *Status) {
|
||||
startTime := time.Now()
|
||||
defer func() { recordExtensionPointDuration(startTime, preBind, status) }()
|
||||
for _, pl := range f.preBindPlugins {
|
||||
status := pl.PreBind(state, pod, nodeName)
|
||||
status := pl.PreBind(ctx, state, pod, nodeName)
|
||||
if !status.IsSuccess() {
|
||||
msg := fmt.Sprintf("error while running %q prebind plugin for pod %q: %v", pl.Name(), pod.Name, status.Message())
|
||||
klog.Error(msg)
|
||||
@@ -457,14 +472,14 @@ func (f *framework) RunPreBindPlugins(
|
||||
}
|
||||
|
||||
// RunBindPlugins runs the set of configured bind plugins until one returns a non `Skip` status.
|
||||
func (f *framework) RunBindPlugins(state *CycleState, pod *v1.Pod, nodeName string) (status *Status) {
|
||||
func (f *framework) RunBindPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) (status *Status) {
|
||||
startTime := time.Now()
|
||||
defer func() { recordExtensionPointDuration(startTime, bind, status) }()
|
||||
if len(f.bindPlugins) == 0 {
|
||||
return NewStatus(Skip, "")
|
||||
}
|
||||
for _, bp := range f.bindPlugins {
|
||||
status = bp.Bind(state, pod, nodeName)
|
||||
status = bp.Bind(ctx, state, pod, nodeName)
|
||||
if status != nil && status.Code() == Skip {
|
||||
continue
|
||||
}
|
||||
@@ -480,11 +495,11 @@ func (f *framework) RunBindPlugins(state *CycleState, pod *v1.Pod, nodeName stri
|
||||
|
||||
// RunPostBindPlugins runs the set of configured postbind plugins.
|
||||
func (f *framework) RunPostBindPlugins(
|
||||
state *CycleState, pod *v1.Pod, nodeName string) {
|
||||
ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) {
|
||||
startTime := time.Now()
|
||||
defer recordExtensionPointDuration(startTime, postBind, nil)
|
||||
for _, pl := range f.postBindPlugins {
|
||||
pl.PostBind(state, pod, nodeName)
|
||||
pl.PostBind(ctx, state, pod, nodeName)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,11 +507,11 @@ func (f *framework) RunPostBindPlugins(
|
||||
// plugins returns an error, it does not continue running the remaining ones and
|
||||
// returns the error. In such case, pod will not be scheduled.
|
||||
func (f *framework) RunReservePlugins(
|
||||
state *CycleState, pod *v1.Pod, nodeName string) (status *Status) {
|
||||
ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) (status *Status) {
|
||||
startTime := time.Now()
|
||||
defer func() { recordExtensionPointDuration(startTime, reserve, status) }()
|
||||
for _, pl := range f.reservePlugins {
|
||||
status := pl.Reserve(state, pod, nodeName)
|
||||
status := pl.Reserve(ctx, state, pod, nodeName)
|
||||
if !status.IsSuccess() {
|
||||
msg := fmt.Sprintf("error while running %q reserve plugin for pod %q: %v", pl.Name(), pod.Name, status.Message())
|
||||
klog.Error(msg)
|
||||
@@ -508,11 +523,11 @@ func (f *framework) RunReservePlugins(
|
||||
|
||||
// RunUnreservePlugins runs the set of configured unreserve plugins.
|
||||
func (f *framework) RunUnreservePlugins(
|
||||
state *CycleState, pod *v1.Pod, nodeName string) {
|
||||
ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) {
|
||||
startTime := time.Now()
|
||||
defer recordExtensionPointDuration(startTime, unreserve, nil)
|
||||
for _, pl := range f.unreservePlugins {
|
||||
pl.Unreserve(state, pod, nodeName)
|
||||
pl.Unreserve(ctx, state, pod, nodeName)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,13 +539,13 @@ func (f *framework) RunUnreservePlugins(
|
||||
// Note that if multiple plugins asked to wait, then we wait for the minimum
|
||||
// timeout duration.
|
||||
func (f *framework) RunPermitPlugins(
|
||||
state *CycleState, pod *v1.Pod, nodeName string) (status *Status) {
|
||||
ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) (status *Status) {
|
||||
startTime := time.Now()
|
||||
defer func() { recordExtensionPointDuration(startTime, permit, status) }()
|
||||
timeout := maxTimeout
|
||||
statusCode := Success
|
||||
for _, pl := range f.permitPlugins {
|
||||
status, d := pl.Permit(state, pod, nodeName)
|
||||
status, d := pl.Permit(ctx, state, pod, nodeName)
|
||||
if !status.IsSuccess() {
|
||||
if status.IsUnschedulable() {
|
||||
msg := fmt.Sprintf("rejected by %q at permit: %v", pl.Name(), status.Message())
|
||||
|
||||
@@ -17,19 +17,20 @@ limitations under the License.
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"k8s.io/kubernetes/pkg/scheduler/metrics"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||
"k8s.io/kubernetes/pkg/scheduler/metrics"
|
||||
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
||||
)
|
||||
|
||||
@@ -86,11 +87,11 @@ func (pl *TestScoreWithNormalizePlugin) Name() string {
|
||||
return pl.name
|
||||
}
|
||||
|
||||
func (pl *TestScoreWithNormalizePlugin) NormalizeScore(state *CycleState, pod *v1.Pod, scores NodeScoreList) *Status {
|
||||
func (pl *TestScoreWithNormalizePlugin) NormalizeScore(ctx context.Context, state *CycleState, pod *v1.Pod, scores NodeScoreList) *Status {
|
||||
return injectNormalizeRes(pl.inj, scores)
|
||||
}
|
||||
|
||||
func (pl *TestScoreWithNormalizePlugin) Score(state *CycleState, p *v1.Pod, nodeName string) (int64, *Status) {
|
||||
func (pl *TestScoreWithNormalizePlugin) Score(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) (int64, *Status) {
|
||||
return setScoreRes(pl.inj)
|
||||
}
|
||||
|
||||
@@ -108,7 +109,7 @@ func (pl *TestScorePlugin) Name() string {
|
||||
return pl.name
|
||||
}
|
||||
|
||||
func (pl *TestScorePlugin) Score(state *CycleState, p *v1.Pod, nodeName string) (int64, *Status) {
|
||||
func (pl *TestScorePlugin) Score(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) (int64, *Status) {
|
||||
return setScoreRes(pl.inj)
|
||||
}
|
||||
|
||||
@@ -133,7 +134,7 @@ func (pl *TestPlugin) Name() string {
|
||||
return pl.name
|
||||
}
|
||||
|
||||
func (pl *TestPlugin) Score(state *CycleState, p *v1.Pod, nodeName string) (int64, *Status) {
|
||||
func (pl *TestPlugin) Score(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) (int64, *Status) {
|
||||
return 0, NewStatus(Code(pl.inj.ScoreStatus), "injected status")
|
||||
}
|
||||
|
||||
@@ -141,30 +142,39 @@ func (pl *TestPlugin) ScoreExtensions() ScoreExtensions {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pl *TestPlugin) PreFilter(state *CycleState, p *v1.Pod) *Status {
|
||||
func (pl *TestPlugin) PreFilter(ctx context.Context, state *CycleState, p *v1.Pod) *Status {
|
||||
return NewStatus(Code(pl.inj.PreFilterStatus), "injected status")
|
||||
}
|
||||
|
||||
func (pl *TestPlugin) PreFilterExtensions() PreFilterExtensions {
|
||||
return nil
|
||||
}
|
||||
func (pl *TestPlugin) Filter(state *CycleState, pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status {
|
||||
|
||||
func (pl *TestPlugin) Filter(ctx context.Context, state *CycleState, pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status {
|
||||
return NewStatus(Code(pl.inj.FilterStatus), "injected status")
|
||||
}
|
||||
func (pl *TestPlugin) PostFilter(state *CycleState, pod *v1.Pod, nodes []*v1.Node, filteredNodesStatuses NodeToStatusMap) *Status {
|
||||
|
||||
func (pl *TestPlugin) PostFilter(ctx context.Context, state *CycleState, pod *v1.Pod, nodes []*v1.Node, filteredNodesStatuses NodeToStatusMap) *Status {
|
||||
return NewStatus(Code(pl.inj.PostFilterStatus), "injected status")
|
||||
}
|
||||
func (pl *TestPlugin) Reserve(state *CycleState, p *v1.Pod, nodeName string) *Status {
|
||||
|
||||
func (pl *TestPlugin) Reserve(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) *Status {
|
||||
return NewStatus(Code(pl.inj.ReserveStatus), "injected status")
|
||||
}
|
||||
func (pl *TestPlugin) PreBind(state *CycleState, p *v1.Pod, nodeName string) *Status {
|
||||
|
||||
func (pl *TestPlugin) PreBind(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) *Status {
|
||||
return NewStatus(Code(pl.inj.PreBindStatus), "injected status")
|
||||
}
|
||||
func (pl *TestPlugin) PostBind(state *CycleState, p *v1.Pod, nodeName string) {}
|
||||
func (pl *TestPlugin) Unreserve(state *CycleState, p *v1.Pod, nodeName string) {}
|
||||
func (pl *TestPlugin) Permit(state *CycleState, p *v1.Pod, nodeName string) (*Status, time.Duration) {
|
||||
|
||||
func (pl *TestPlugin) PostBind(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) {}
|
||||
|
||||
func (pl *TestPlugin) Unreserve(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) {}
|
||||
|
||||
func (pl *TestPlugin) Permit(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) (*Status, time.Duration) {
|
||||
return NewStatus(Code(pl.inj.PermitStatus), "injected status"), time.Duration(0)
|
||||
}
|
||||
func (pl *TestPlugin) Bind(state *CycleState, p *v1.Pod, nodeName string) *Status {
|
||||
|
||||
func (pl *TestPlugin) Bind(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) *Status {
|
||||
return NewStatus(Code(pl.inj.BindStatus), "injected status")
|
||||
}
|
||||
|
||||
@@ -177,7 +187,7 @@ func (pl *TestPreFilterPlugin) Name() string {
|
||||
return preFilterPluginName
|
||||
}
|
||||
|
||||
func (pl *TestPreFilterPlugin) PreFilter(state *CycleState, p *v1.Pod) *Status {
|
||||
func (pl *TestPreFilterPlugin) PreFilter(ctx context.Context, state *CycleState, p *v1.Pod) *Status {
|
||||
pl.PreFilterCalled++
|
||||
return nil
|
||||
}
|
||||
@@ -197,18 +207,18 @@ func (pl *TestPreFilterWithExtensionsPlugin) Name() string {
|
||||
return preFilterWithExtensionsPluginName
|
||||
}
|
||||
|
||||
func (pl *TestPreFilterWithExtensionsPlugin) PreFilter(state *CycleState, p *v1.Pod) *Status {
|
||||
func (pl *TestPreFilterWithExtensionsPlugin) PreFilter(ctx context.Context, state *CycleState, p *v1.Pod) *Status {
|
||||
pl.PreFilterCalled++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pl *TestPreFilterWithExtensionsPlugin) AddPod(state *CycleState, podToSchedule *v1.Pod,
|
||||
func (pl *TestPreFilterWithExtensionsPlugin) AddPod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod,
|
||||
podToAdd *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status {
|
||||
pl.AddCalled++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pl *TestPreFilterWithExtensionsPlugin) RemovePod(state *CycleState, podToSchedule *v1.Pod,
|
||||
func (pl *TestPreFilterWithExtensionsPlugin) RemovePod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod,
|
||||
podToRemove *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status {
|
||||
pl.RemoveCalled++
|
||||
return nil
|
||||
@@ -225,7 +235,7 @@ func (dp *TestDuplicatePlugin) Name() string {
|
||||
return duplicatePluginName
|
||||
}
|
||||
|
||||
func (dp *TestDuplicatePlugin) PreFilter(state *CycleState, p *v1.Pod) *Status {
|
||||
func (dp *TestDuplicatePlugin) PreFilter(ctx context.Context, state *CycleState, p *v1.Pod) *Status {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -503,7 +513,7 @@ func TestRunScorePlugins(t *testing.T) {
|
||||
t.Fatalf("Failed to create framework for testing: %v", err)
|
||||
}
|
||||
|
||||
res, status := f.RunScorePlugins(state, pod, nodes)
|
||||
res, status := f.RunScorePlugins(context.Background(), state, pod, nodes)
|
||||
|
||||
if tt.err {
|
||||
if status.IsSuccess() {
|
||||
@@ -540,9 +550,9 @@ func TestPreFilterPlugins(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create framework for testing: %v", err)
|
||||
}
|
||||
f.RunPreFilterPlugins(nil, nil)
|
||||
f.RunPreFilterExtensionAddPod(nil, nil, nil, nil)
|
||||
f.RunPreFilterExtensionRemovePod(nil, nil, nil, nil)
|
||||
f.RunPreFilterPlugins(context.Background(), nil, nil)
|
||||
f.RunPreFilterExtensionAddPod(context.Background(), nil, nil, nil, nil)
|
||||
f.RunPreFilterExtensionRemovePod(context.Background(), nil, nil, nil, nil)
|
||||
|
||||
if preFilter1.PreFilterCalled != 1 {
|
||||
t.Errorf("preFilter1 called %v, expected: 1", preFilter1.PreFilterCalled)
|
||||
@@ -570,117 +580,117 @@ func TestRecordingMetrics(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "PreFilter - Success",
|
||||
action: func(f Framework) { f.RunPreFilterPlugins(nil, pod) },
|
||||
action: func(f Framework) { f.RunPreFilterPlugins(context.Background(), nil, pod) },
|
||||
wantExtensionPoint: "PreFilter",
|
||||
wantStatus: Success,
|
||||
},
|
||||
{
|
||||
name: "Filter - Success",
|
||||
action: func(f Framework) { f.RunFilterPlugins(nil, pod, nil) },
|
||||
action: func(f Framework) { f.RunFilterPlugins(context.Background(), nil, pod, nil) },
|
||||
wantExtensionPoint: "Filter",
|
||||
wantStatus: Success,
|
||||
},
|
||||
{
|
||||
name: "PostFilter - Success",
|
||||
action: func(f Framework) { f.RunPostFilterPlugins(nil, pod, nil, nil) },
|
||||
action: func(f Framework) { f.RunPostFilterPlugins(context.Background(), nil, pod, nil, nil) },
|
||||
wantExtensionPoint: "PostFilter",
|
||||
wantStatus: Success,
|
||||
},
|
||||
{
|
||||
name: "Score - Success",
|
||||
action: func(f Framework) { f.RunScorePlugins(nil, pod, nodes) },
|
||||
action: func(f Framework) { f.RunScorePlugins(context.Background(), nil, pod, nodes) },
|
||||
wantExtensionPoint: "Score",
|
||||
wantStatus: Success,
|
||||
},
|
||||
{
|
||||
name: "Reserve - Success",
|
||||
action: func(f Framework) { f.RunReservePlugins(nil, pod, "") },
|
||||
action: func(f Framework) { f.RunReservePlugins(context.Background(), nil, pod, "") },
|
||||
wantExtensionPoint: "Reserve",
|
||||
wantStatus: Success,
|
||||
},
|
||||
{
|
||||
name: "Unreserve - Success",
|
||||
action: func(f Framework) { f.RunUnreservePlugins(nil, pod, "") },
|
||||
action: func(f Framework) { f.RunUnreservePlugins(context.Background(), nil, pod, "") },
|
||||
wantExtensionPoint: "Unreserve",
|
||||
wantStatus: Success,
|
||||
},
|
||||
{
|
||||
name: "PreBind - Success",
|
||||
action: func(f Framework) { f.RunPreBindPlugins(nil, pod, "") },
|
||||
action: func(f Framework) { f.RunPreBindPlugins(context.Background(), nil, pod, "") },
|
||||
wantExtensionPoint: "PreBind",
|
||||
wantStatus: Success,
|
||||
},
|
||||
{
|
||||
name: "Bind - Success",
|
||||
action: func(f Framework) { f.RunBindPlugins(nil, pod, "") },
|
||||
action: func(f Framework) { f.RunBindPlugins(context.Background(), nil, pod, "") },
|
||||
wantExtensionPoint: "Bind",
|
||||
wantStatus: Success,
|
||||
},
|
||||
{
|
||||
name: "PostBind - Success",
|
||||
action: func(f Framework) { f.RunPostBindPlugins(nil, pod, "") },
|
||||
action: func(f Framework) { f.RunPostBindPlugins(context.Background(), nil, pod, "") },
|
||||
wantExtensionPoint: "PostBind",
|
||||
wantStatus: Success,
|
||||
},
|
||||
{
|
||||
name: "Permit - Success",
|
||||
action: func(f Framework) { f.RunPermitPlugins(nil, pod, "") },
|
||||
action: func(f Framework) { f.RunPermitPlugins(context.Background(), nil, pod, "") },
|
||||
wantExtensionPoint: "Permit",
|
||||
wantStatus: Success,
|
||||
},
|
||||
|
||||
{
|
||||
name: "PreFilter - Error",
|
||||
action: func(f Framework) { f.RunPreFilterPlugins(nil, pod) },
|
||||
action: func(f Framework) { f.RunPreFilterPlugins(context.Background(), nil, pod) },
|
||||
inject: injectedResult{PreFilterStatus: int(Error)},
|
||||
wantExtensionPoint: "PreFilter",
|
||||
wantStatus: Error,
|
||||
},
|
||||
{
|
||||
name: "Filter - Error",
|
||||
action: func(f Framework) { f.RunFilterPlugins(nil, pod, nil) },
|
||||
action: func(f Framework) { f.RunFilterPlugins(context.Background(), nil, pod, nil) },
|
||||
inject: injectedResult{FilterStatus: int(Error)},
|
||||
wantExtensionPoint: "Filter",
|
||||
wantStatus: Error,
|
||||
},
|
||||
{
|
||||
name: "PostFilter - Error",
|
||||
action: func(f Framework) { f.RunPostFilterPlugins(nil, pod, nil, nil) },
|
||||
action: func(f Framework) { f.RunPostFilterPlugins(context.Background(), nil, pod, nil, nil) },
|
||||
inject: injectedResult{PostFilterStatus: int(Error)},
|
||||
wantExtensionPoint: "PostFilter",
|
||||
wantStatus: Error,
|
||||
},
|
||||
{
|
||||
name: "Score - Error",
|
||||
action: func(f Framework) { f.RunScorePlugins(nil, pod, nodes) },
|
||||
action: func(f Framework) { f.RunScorePlugins(context.Background(), nil, pod, nodes) },
|
||||
inject: injectedResult{ScoreStatus: int(Error)},
|
||||
wantExtensionPoint: "Score",
|
||||
wantStatus: Error,
|
||||
},
|
||||
{
|
||||
name: "Reserve - Error",
|
||||
action: func(f Framework) { f.RunReservePlugins(nil, pod, "") },
|
||||
action: func(f Framework) { f.RunReservePlugins(context.Background(), nil, pod, "") },
|
||||
inject: injectedResult{ReserveStatus: int(Error)},
|
||||
wantExtensionPoint: "Reserve",
|
||||
wantStatus: Error,
|
||||
},
|
||||
{
|
||||
name: "PreBind - Error",
|
||||
action: func(f Framework) { f.RunPreBindPlugins(nil, pod, "") },
|
||||
action: func(f Framework) { f.RunPreBindPlugins(context.Background(), nil, pod, "") },
|
||||
inject: injectedResult{PreBindStatus: int(Error)},
|
||||
wantExtensionPoint: "PreBind",
|
||||
wantStatus: Error,
|
||||
},
|
||||
{
|
||||
name: "Bind - Error",
|
||||
action: func(f Framework) { f.RunBindPlugins(nil, pod, "") },
|
||||
action: func(f Framework) { f.RunBindPlugins(context.Background(), nil, pod, "") },
|
||||
inject: injectedResult{BindStatus: int(Error)},
|
||||
wantExtensionPoint: "Bind",
|
||||
wantStatus: Error,
|
||||
},
|
||||
{
|
||||
name: "Permit - Error",
|
||||
action: func(f Framework) { f.RunPermitPlugins(nil, pod, "") },
|
||||
action: func(f Framework) { f.RunPermitPlugins(context.Background(), nil, pod, "") },
|
||||
inject: injectedResult{PermitStatus: int(Error)},
|
||||
wantExtensionPoint: "Permit",
|
||||
wantStatus: Error,
|
||||
|
||||
@@ -19,6 +19,7 @@ limitations under the License.
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"math"
|
||||
"time"
|
||||
@@ -206,10 +207,10 @@ type QueueSortPlugin interface {
|
||||
type PreFilterExtensions interface {
|
||||
// AddPod is called by the framework while trying to evaluate the impact
|
||||
// of adding podToAdd to the node while scheduling podToSchedule.
|
||||
AddPod(state *CycleState, podToSchedule *v1.Pod, podToAdd *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
|
||||
AddPod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod, podToAdd *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
|
||||
// RemovePod is called by the framework while trying to evaluate the impact
|
||||
// of removing podToRemove from the node while scheduling podToSchedule.
|
||||
RemovePod(state *CycleState, podToSchedule *v1.Pod, podToRemove *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
|
||||
RemovePod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod, podToRemove *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
|
||||
}
|
||||
|
||||
// PreFilterPlugin is an interface that must be implemented by "prefilter" plugins.
|
||||
@@ -218,7 +219,7 @@ type PreFilterPlugin interface {
|
||||
Plugin
|
||||
// PreFilter is called at the beginning of the scheduling cycle. All PreFilter
|
||||
// plugins must return success or the pod will be rejected.
|
||||
PreFilter(state *CycleState, p *v1.Pod) *Status
|
||||
PreFilter(ctx context.Context, state *CycleState, p *v1.Pod) *Status
|
||||
// PreFilterExtensions returns a PreFilterExtensions interface if the plugin implements one,
|
||||
// or nil if it does not. A Pre-filter plugin can provide extensions to incrementally
|
||||
// modify its pre-processed info. The framework guarantees that the extensions
|
||||
@@ -249,7 +250,7 @@ type FilterPlugin interface {
|
||||
// For example, during preemption, we may pass a copy of the original
|
||||
// nodeInfo object that has some pods removed from it to evaluate the
|
||||
// possibility of preempting them to schedule the target pod.
|
||||
Filter(state *CycleState, pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
|
||||
Filter(ctx context.Context, state *CycleState, pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
|
||||
}
|
||||
|
||||
// PostFilterPlugin is an interface for Post-filter plugin. Post-filter is an
|
||||
@@ -262,7 +263,7 @@ type PostFilterPlugin interface {
|
||||
// passed the filtering phase. All postfilter plugins must return success or
|
||||
// the pod will be rejected. The filteredNodesStatuses is the set of filtered nodes
|
||||
// and their filter status.
|
||||
PostFilter(state *CycleState, pod *v1.Pod, nodes []*v1.Node, filteredNodesStatuses NodeToStatusMap) *Status
|
||||
PostFilter(ctx context.Context, state *CycleState, pod *v1.Pod, nodes []*v1.Node, filteredNodesStatuses NodeToStatusMap) *Status
|
||||
}
|
||||
|
||||
// ScoreExtensions is an interface for Score extended functionality.
|
||||
@@ -270,7 +271,7 @@ type ScoreExtensions interface {
|
||||
// NormalizeScore is called for all node scores produced by the same plugin's "Score"
|
||||
// method. A successful run of NormalizeScore will update the scores list and return
|
||||
// a success status.
|
||||
NormalizeScore(state *CycleState, p *v1.Pod, scores NodeScoreList) *Status
|
||||
NormalizeScore(ctx context.Context, state *CycleState, p *v1.Pod, scores NodeScoreList) *Status
|
||||
}
|
||||
|
||||
// ScorePlugin is an interface that must be implemented by "score" plugins to rank
|
||||
@@ -280,7 +281,7 @@ type ScorePlugin interface {
|
||||
// Score is called on each filtered node. It must return success and an integer
|
||||
// indicating the rank of the node. All scoring plugins must return success or
|
||||
// the pod will be rejected.
|
||||
Score(state *CycleState, p *v1.Pod, nodeName string) (int64, *Status)
|
||||
Score(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) (int64, *Status)
|
||||
|
||||
// ScoreExtensions returns a ScoreExtensions interface if it implements one, or nil if does not.
|
||||
ScoreExtensions() ScoreExtensions
|
||||
@@ -296,7 +297,7 @@ type ReservePlugin interface {
|
||||
Plugin
|
||||
// Reserve is called by the scheduling framework when the scheduler cache is
|
||||
// updated.
|
||||
Reserve(state *CycleState, p *v1.Pod, nodeName string) *Status
|
||||
Reserve(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) *Status
|
||||
}
|
||||
|
||||
// PreBindPlugin is an interface that must be implemented by "prebind" plugins.
|
||||
@@ -305,7 +306,7 @@ type PreBindPlugin interface {
|
||||
Plugin
|
||||
// PreBind is called before binding a pod. All prebind plugins must return
|
||||
// success or the pod will be rejected and won't be sent for binding.
|
||||
PreBind(state *CycleState, p *v1.Pod, nodeName string) *Status
|
||||
PreBind(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) *Status
|
||||
}
|
||||
|
||||
// PostBindPlugin is an interface that must be implemented by "postbind" plugins.
|
||||
@@ -316,7 +317,7 @@ type PostBindPlugin interface {
|
||||
// informational. A common application of this extension point is for cleaning
|
||||
// up. If a plugin needs to clean-up its state after a pod is scheduled and
|
||||
// bound, PostBind is the extension point that it should register.
|
||||
PostBind(state *CycleState, p *v1.Pod, nodeName string)
|
||||
PostBind(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string)
|
||||
}
|
||||
|
||||
// UnreservePlugin is an interface for Unreserve plugins. This is an informational
|
||||
@@ -327,7 +328,7 @@ type UnreservePlugin interface {
|
||||
Plugin
|
||||
// Unreserve is called by the scheduling framework when a reserved pod was
|
||||
// rejected in a later phase.
|
||||
Unreserve(state *CycleState, p *v1.Pod, nodeName string)
|
||||
Unreserve(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string)
|
||||
}
|
||||
|
||||
// PermitPlugin is an interface that must be implemented by "permit" plugins.
|
||||
@@ -340,7 +341,7 @@ type PermitPlugin interface {
|
||||
// The pod will also be rejected if the wait timeout or the pod is rejected while
|
||||
// waiting. Note that if the plugin returns "wait", the framework will wait only
|
||||
// after running the remaining plugins given that no other plugin rejects the pod.
|
||||
Permit(state *CycleState, p *v1.Pod, nodeName string) (*Status, time.Duration)
|
||||
Permit(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) (*Status, time.Duration)
|
||||
}
|
||||
|
||||
// BindPlugin is an interface that must be implemented by "bind" plugins. Bind
|
||||
@@ -353,7 +354,7 @@ type BindPlugin interface {
|
||||
// remaining bind plugins are skipped. When a bind plugin does not handle a pod,
|
||||
// it must return Skip in its Status code. If a bind plugin returns an Error, the
|
||||
// pod is rejected and will not be bound.
|
||||
Bind(state *CycleState, p *v1.Pod, nodeName string) *Status
|
||||
Bind(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) *Status
|
||||
}
|
||||
|
||||
// Framework manages the set of plugins in use by the scheduling framework.
|
||||
@@ -367,7 +368,7 @@ type Framework interface {
|
||||
// *Status and its code is set to non-success if any of the plugins returns
|
||||
// anything but Success. If a non-success status is returned, then the scheduling
|
||||
// cycle is aborted.
|
||||
RunPreFilterPlugins(state *CycleState, pod *v1.Pod) *Status
|
||||
RunPreFilterPlugins(ctx context.Context, state *CycleState, pod *v1.Pod) *Status
|
||||
|
||||
// RunFilterPlugins runs the set of configured filter plugins for pod on
|
||||
// the given node. It returns directly if any of the filter plugins
|
||||
@@ -378,46 +379,46 @@ type Framework interface {
|
||||
// pass a copy of the original nodeInfo object that has some pods
|
||||
// removed from it to evaluate the possibility of preempting them to
|
||||
// schedule the target pod.
|
||||
RunFilterPlugins(state *CycleState, pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
|
||||
RunFilterPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
|
||||
|
||||
// RunPreFilterExtensionAddPod calls the AddPod interface for the set of configured
|
||||
// PreFilter plugins. It returns directly if any of the plugins return any
|
||||
// status other than Success.
|
||||
RunPreFilterExtensionAddPod(state *CycleState, podToSchedule *v1.Pod, podToAdd *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
|
||||
RunPreFilterExtensionAddPod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod, podToAdd *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
|
||||
|
||||
// RunPreFilterExtensionRemovePod calls the RemovePod interface for the set of configured
|
||||
// PreFilter plugins. It returns directly if any of the plugins return any
|
||||
// status other than Success.
|
||||
RunPreFilterExtensionRemovePod(state *CycleState, podToSchedule *v1.Pod, podToAdd *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
|
||||
RunPreFilterExtensionRemovePod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod, podToAdd *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
|
||||
|
||||
// RunPostFilterPlugins runs the set of configured post-filter plugins. If any
|
||||
// of these plugins returns any status other than "Success", the given node is
|
||||
// rejected. The filteredNodeStatuses is the set of filtered nodes and their statuses.
|
||||
RunPostFilterPlugins(state *CycleState, pod *v1.Pod, nodes []*v1.Node, filteredNodesStatuses NodeToStatusMap) *Status
|
||||
RunPostFilterPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodes []*v1.Node, filteredNodesStatuses NodeToStatusMap) *Status
|
||||
|
||||
// RunScorePlugins runs the set of configured scoring plugins. It returns a map that
|
||||
// stores for each scoring plugin name the corresponding NodeScoreList(s).
|
||||
// It also returns *Status, which is set to non-success if any of the plugins returns
|
||||
// a non-success status.
|
||||
RunScorePlugins(state *CycleState, pod *v1.Pod, nodes []*v1.Node) (PluginToNodeScores, *Status)
|
||||
RunScorePlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodes []*v1.Node) (PluginToNodeScores, *Status)
|
||||
|
||||
// RunPreBindPlugins runs the set of configured prebind plugins. It returns
|
||||
// *Status and its code is set to non-success if any of the plugins returns
|
||||
// anything but Success. If the Status code is "Unschedulable", it is
|
||||
// considered as a scheduling check failure, otherwise, it is considered as an
|
||||
// internal error. In either case the pod is not going to be bound.
|
||||
RunPreBindPlugins(state *CycleState, pod *v1.Pod, nodeName string) *Status
|
||||
RunPreBindPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) *Status
|
||||
|
||||
// RunPostBindPlugins runs the set of configured postbind plugins.
|
||||
RunPostBindPlugins(state *CycleState, pod *v1.Pod, nodeName string)
|
||||
RunPostBindPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string)
|
||||
|
||||
// RunReservePlugins runs the set of configured reserve plugins. If any of these
|
||||
// plugins returns an error, it does not continue running the remaining ones and
|
||||
// returns the error. In such case, pod will not be scheduled.
|
||||
RunReservePlugins(state *CycleState, pod *v1.Pod, nodeName string) *Status
|
||||
RunReservePlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) *Status
|
||||
|
||||
// RunUnreservePlugins runs the set of configured unreserve plugins.
|
||||
RunUnreservePlugins(state *CycleState, pod *v1.Pod, nodeName string)
|
||||
RunUnreservePlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string)
|
||||
|
||||
// RunPermitPlugins runs the set of configured permit plugins. If any of these
|
||||
// plugins returns a status other than "Success" or "Wait", it does not continue
|
||||
@@ -426,14 +427,14 @@ type Framework interface {
|
||||
// returned by the plugin, if the time expires, then it will return an error.
|
||||
// Note that if multiple plugins asked to wait, then we wait for the minimum
|
||||
// timeout duration.
|
||||
RunPermitPlugins(state *CycleState, pod *v1.Pod, nodeName string) *Status
|
||||
RunPermitPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) *Status
|
||||
|
||||
// RunBindPlugins runs the set of configured bind plugins. A bind plugin may choose
|
||||
// whether or not to handle the given Pod. If a bind plugin chooses to skip the
|
||||
// binding, it should return code=4("skip") status. Otherwise, it should return "Error"
|
||||
// or "Success". If none of the plugins handled binding, RunBindPlugins returns
|
||||
// code=4("skip") status.
|
||||
RunBindPlugins(state *CycleState, pod *v1.Pod, nodeName string) *Status
|
||||
RunBindPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) *Status
|
||||
|
||||
// HasFilterPlugins return true if at least one filter plugin is defined
|
||||
HasFilterPlugins() bool
|
||||
|
||||
Reference in New Issue
Block a user