Merge pull request #84578 from denkensk/add-event-deleteandreject-podinwaiting

Update the event handler for deleting pods to reject the waiting pod
This commit is contained in:
Kubernetes Prow Robot 2019-11-05 15:31:18 -08:00 committed by GitHub
commit 83b991a9c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 0 deletions

View File

@ -204,6 +204,7 @@ func (sched *Scheduler) deletePodFromSchedulingQueue(obj interface{}) {
// Volume binder only wants to keep unassigned pods // Volume binder only wants to keep unassigned pods
sched.VolumeBinder.DeletePodBindings(pod) sched.VolumeBinder.DeletePodBindings(pod)
} }
sched.Framework.RejectWaitingPod(pod.UID)
} }
func (sched *Scheduler) addPodToCache(obj interface{}) { func (sched *Scheduler) addPodToCache(obj interface{}) {

View File

@ -62,6 +62,7 @@ go_test(
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library", "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
"//vendor/github.com/prometheus/client_model/go:go_default_library", "//vendor/github.com/prometheus/client_model/go:go_default_library",
], ],

View File

@ -627,6 +627,14 @@ func (f *framework) GetWaitingPod(uid types.UID) WaitingPod {
return f.waitingPods.get(uid) return f.waitingPods.get(uid)
} }
// RejectWaitingPod rejects a WaitingPod given its UID.
func (f *framework) RejectWaitingPod(uid types.UID) {
waitingPod := f.waitingPods.get(uid)
if waitingPod != nil {
waitingPod.Reject("removed")
}
}
// HasFilterPlugins returns true if at least one filter plugin is defined. // HasFilterPlugins returns true if at least one filter plugin is defined.
func (f *framework) HasFilterPlugins() bool { func (f *framework) HasFilterPlugins() bool {
return len(f.filterPlugins) > 0 return len(f.filterPlugins) > 0

View File

@ -29,6 +29,7 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/scheduler/apis/config" "k8s.io/kubernetes/pkg/scheduler/apis/config"
"k8s.io/kubernetes/pkg/scheduler/metrics" "k8s.io/kubernetes/pkg/scheduler/metrics"
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo" schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
@ -43,6 +44,7 @@ const (
preFilterWithExtensionsPluginName = "prefilter-with-extensions-plugin" preFilterWithExtensionsPluginName = "prefilter-with-extensions-plugin"
duplicatePluginName = "duplicate-plugin" duplicatePluginName = "duplicate-plugin"
testPlugin = "test-plugin" testPlugin = "test-plugin"
permitPlugin = "permit-plugin"
) )
// TestScoreWithNormalizePlugin implements ScoreWithNormalizePlugin interface. // TestScoreWithNormalizePlugin implements ScoreWithNormalizePlugin interface.
@ -249,6 +251,18 @@ func newDuplicatePlugin(_ *runtime.Unknown, _ FrameworkHandle) (Plugin, error) {
return &TestDuplicatePlugin{}, nil return &TestDuplicatePlugin{}, nil
} }
// TestPermitPlugin only implements PermitPlugin interface.
type TestPermitPlugin struct {
PreFilterCalled int
}
func (pp *TestPermitPlugin) Name() string {
return permitPlugin
}
func (pp *TestPermitPlugin) Permit(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) (*Status, time.Duration) {
return NewStatus(Wait, ""), time.Duration(10 * time.Second)
}
var registry Registry = func() Registry { var registry Registry = func() Registry {
r := make(Registry) r := make(Registry)
r.Register(scoreWithNormalizePlugin1, newScoreWithNormalizePlugin1) r.Register(scoreWithNormalizePlugin1, newScoreWithNormalizePlugin1)
@ -773,6 +787,44 @@ func TestPermitWaitingMetric(t *testing.T) {
} }
} }
func TestRejectWaitingPod(t *testing.T) {
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod",
UID: types.UID("pod"),
},
}
testPermitPlugin := &TestPermitPlugin{}
r := make(Registry)
r.Register(permitPlugin,
func(_ *runtime.Unknown, fh FrameworkHandle) (Plugin, error) {
return testPermitPlugin, nil
})
plugins := &config.Plugins{
Permit: &config.PluginSet{Enabled: []config.Plugin{{Name: permitPlugin, Weight: 1}}},
}
f, err := NewFramework(r, plugins, emptyArgs)
if err != nil {
t.Fatalf("Failed to create framework for testing: %v", err)
}
go func() {
for {
waitingPod := f.GetWaitingPod(pod.UID)
if waitingPod != nil {
break
}
}
f.RejectWaitingPod(pod.UID)
}()
permitStatus := f.RunPermitPlugins(context.Background(), nil, pod, "")
if permitStatus.message != "pod \"pod\" rejected while waiting at permit: removed" {
t.Fatalf("RejectWaitingPod failed, permitStatus: %v", permitStatus)
}
}
func buildScoreConfigDefaultWeights(ps ...string) *config.Plugins { func buildScoreConfigDefaultWeights(ps ...string) *config.Plugins {
return buildScoreConfigWithWeights(defaultWeights, ps...) return buildScoreConfigWithWeights(defaultWeights, ps...)
} }

View File

@ -471,6 +471,9 @@ type FrameworkHandle interface {
// GetWaitingPod returns a waiting pod given its UID. // GetWaitingPod returns a waiting pod given its UID.
GetWaitingPod(uid types.UID) WaitingPod GetWaitingPod(uid types.UID) WaitingPod
// RejectWaitingPod rejects a waiting pod given its UID.
RejectWaitingPod(uid types.UID)
// ClientSet returns a kubernetes clientSet. // ClientSet returns a kubernetes clientSet.
ClientSet() clientset.Interface ClientSet() clientset.Interface

View File

@ -243,6 +243,9 @@ func (*fakeFramework) GetWaitingPod(uid types.UID) framework.WaitingPod {
return nil return nil
} }
func (*fakeFramework) RejectWaitingPod(uid types.UID) {
}
func (*fakeFramework) ClientSet() clientset.Interface { func (*fakeFramework) ClientSet() clientset.Interface {
return nil return nil
} }