Skip to content

Commit 73a62c8

Browse files
authored
Merge pull request #82 from utam0k/reserve-plugin
Support Reserve plugin
2 parents 1360f25 + 426e4e5 commit 73a62c8

File tree

19 files changed

+387
-9
lines changed

19 files changed

+387
-9
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ examples/advanced/main.wasm: examples/advanced/main.go
99
@(cd $(@D); tinygo build -o main.wasm -scheduler=none --no-debug -target=wasi .)
1010

1111
.PHONY: build-tinygo
12-
build-tinygo: examples/nodenumber/main.wasm examples/advanced/main.wasm guest/testdata/cyclestate/main.wasm guest/testdata/filter/main.wasm guest/testdata/score/main.wasm guest/testdata/bind/main.wasm
12+
build-tinygo: examples/nodenumber/main.wasm examples/advanced/main.wasm guest/testdata/cyclestate/main.wasm guest/testdata/filter/main.wasm guest/testdata/score/main.wasm guest/testdata/bind/main.wasm guest/testdata/reserve/main.wasm
1313

1414
%/main-debug.wasm: %/main.go
1515
@(cd $(@D); tinygo build -o main-debug.wasm -gc=custom -tags=custommalloc -scheduler=none -target=wasi .)

guest/api/types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ type ScoreExtensions interface {
114114
NormalizeScore(state CycleState, pod proto.Pod, scores NodeScore) (map[string]int, *Status)
115115
}
116116

117+
// ReservePlugin is a WebAssembly implementation of framework.ReservePlugin.
118+
type ReservePlugin interface {
119+
Plugin
120+
121+
Reserve(state CycleState, p proto.Pod, nodeName string) *Status
122+
Unreserve(state CycleState, p proto.Pod, nodeName string)
123+
}
124+
117125
// PreBindPlugin is a WebAssembly implementation of framework.PreBindPlugin.
118126
type PreBindPlugin interface {
119127
Plugin

guest/plugin/plugin.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/postfilter"
2727
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/prebind"
2828
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/prescore"
29+
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/reserve"
2930
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/score"
3031
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/scoreextensions"
3132
)
@@ -68,6 +69,9 @@ func Set(plugin api.Plugin) {
6869
if plugin, ok := plugin.(api.ScoreExtensions); ok {
6970
scoreextensions.SetPlugin(plugin)
7071
}
72+
if plugin, ok := plugin.(api.ReservePlugin); ok {
73+
reserve.SetPlugin(plugin)
74+
}
7175
if plugin, ok := plugin.(api.PreBindPlugin); ok {
7276
prebind.SetPlugin(plugin)
7377
}

guest/reserve/reserve.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package reserve exports an api.ReservePlugin to the host.
18+
package reserve
19+
20+
import (
21+
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/api"
22+
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/internal/cyclestate"
23+
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/internal/imports"
24+
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/internal/plugin"
25+
)
26+
27+
// reserve is the current plugin assigned with SetPlugin.
28+
var reserve api.ReservePlugin
29+
30+
// SetPlugin should be called in `main` to assign an api.ReservePlugin instance.
31+
//
32+
// For example:
33+
//
34+
// func main() {
35+
// plugin := reservePlugin{}
36+
// reserve.SetPlugin(plugin)
37+
// }
38+
//
39+
// type reservePlugin struct{}
40+
//
41+
// func (reservePlugin) Reserve(state api.CycleState, pod proto.Pod, nodeName string) (status *api.Status) {
42+
// // Write state you need on Reserve
43+
// }
44+
//
45+
// func (reservePlugin) Unreserve(state api.CycleState, pod proto.Pod, nodeName string) {
46+
// // Write state you need on Unreserve
47+
// }
48+
func SetPlugin(reservePlugin api.ReservePlugin) {
49+
if reservePlugin == nil {
50+
panic("nil reservePlugin")
51+
}
52+
reserve = reservePlugin
53+
plugin.MustSet(reserve)
54+
}
55+
56+
// prevent unused lint errors (lint is run with normal go).
57+
var (
58+
_ func() uint32 = _reserve
59+
_ func() = _unreserve
60+
)
61+
62+
// _reserve is only exported to the host.
63+
//
64+
//export reserve
65+
func _reserve() uint32 { //nolint
66+
if reserve == nil { // Then, the user didn't define one.
67+
// Unlike most plugins we always export reserve so that we can reset
68+
// the cycle state: return success to avoid no-op overhead.
69+
return 0
70+
}
71+
72+
nodeName := imports.NodeName()
73+
status := reserve.Reserve(cyclestate.Values, cyclestate.Pod, nodeName)
74+
75+
return imports.StatusToCode(status)
76+
}
77+
78+
// _unreserve is only exported to the host.
79+
//
80+
//export unreserve
81+
func _unreserve() { //nolint
82+
if reserve == nil { // Then, the user didn't define one.
83+
// Unlike most plugins we always export unreserve so that we can reset
84+
// the cycle state: return success to avoid no-op overhead.
85+
return
86+
}
87+
88+
nodeName := imports.NodeName()
89+
reserve.Unreserve(cyclestate.Values, cyclestate.Pod, nodeName)
90+
}

guest/testdata/cyclestate/main.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/prebind"
3333
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/prefilter"
3434
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/prescore"
35+
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/reserve"
3536
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/score"
3637
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/scoreextensions"
3738
protoapi "sigs.k8s.io/kube-scheduler-wasm-extension/kubernetes/proto/api"
@@ -65,6 +66,7 @@ func main() {
6566
prescore.SetPlugin(plugin)
6667
score.SetPlugin(plugin)
6768
scoreextensions.SetPlugin(plugin)
69+
reserve.SetPlugin(plugin)
6870
prebind.SetPlugin(plugin)
6971
bind.SetPlugin(plugin)
7072
postbind.SetPlugin(plugin)
@@ -176,6 +178,15 @@ func (statePlugin) NormalizeScore(state api.CycleState, pod proto.Pod, _ api.Nod
176178
return
177179
}
178180

181+
func (statePlugin) Reserve(state api.CycleState, pod proto.Pod, nodeName string) (status *api.Status) {
182+
// Actually, it is not called from the cycle test, but it needs for Reserve plugin.
183+
return
184+
}
185+
186+
func (statePlugin) Unreserve(state api.CycleState, pod proto.Pod, nodeName string) {
187+
mustFilterState(state)
188+
}
189+
179190
func (statePlugin) PreBind(state api.CycleState, pod proto.Pod, _ string) (status *api.Status) {
180191
if unsafe.Pointer(pod.Spec()) != unsafe.Pointer(podSpec) {
181192
panic("didn't cache pod from pre-filter")
9.83 KB
Binary file not shown.

guest/testdata/reserve/main.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/api"
21+
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/api/proto"
22+
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/reserve"
23+
)
24+
25+
type extensionPoints interface {
26+
api.ReservePlugin
27+
}
28+
29+
func main() {
30+
var plugin extensionPoints = reservePlugin{}
31+
reserve.SetPlugin(plugin)
32+
}
33+
34+
type reservePlugin struct{}
35+
36+
func (reservePlugin) Reserve(state api.CycleState, pod proto.Pod, nodeName string) *api.Status {
37+
state.Write(nodeName+pod.Spec().GetNodeName(), "ok")
38+
status := 0
39+
if nodeName == "bad" {
40+
status = 1
41+
}
42+
return &api.Status{Code: api.StatusCode(status), Reason: "name is " + nodeName}
43+
}
44+
45+
func (reservePlugin) Unreserve(state api.CycleState, pod proto.Pod, nodeName string) {
46+
val, ok := state.Read(nodeName + pod.Spec().GetNodeName())
47+
if ok && val == "ok" {
48+
state.Delete(nodeName + pod.Spec().GetNodeName())
49+
return
50+
}
51+
52+
panic("unreserve failed")
53+
}

guest/testdata/reserve/main.wasm

821 KB
Binary file not shown.

internal/e2e/e2e.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ func RunAll(ctx context.Context, t Testing, plugin framework.Plugin, pod *v1.Pod
4343
RequireSuccess(t, s)
4444
}
4545

46+
if reserveP, ok := plugin.(framework.ReservePlugin); ok {
47+
s = reserveP.Reserve(ctx, nil, pod, ni.Node().Name)
48+
RequireSuccess(t, s)
49+
reserveP.Unreserve(ctx, nil, pod, ni.Node().Name)
50+
}
51+
4652
if prebindP, ok := plugin.(framework.PreBindPlugin); ok {
4753
s = prebindP.PreBind(ctx, nil, pod, "")
4854
RequireSuccess(t, s)

internal/e2e/scheduler_perf/scheduler_perf_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ var (
9191
Metrics: map[string]*labelValues{
9292
"scheduler_framework_extension_point_duration_seconds": {
9393
label: extensionPointsLabelName,
94-
values: []string{"PreFilter", "Filter", "PostFilter", "PreScore", "Score", "PreBind", "Bind", "PostBind"},
94+
values: []string{"PreFilter", "Filter", "PostFilter", "PreScore", "Score", "Reserve", "PreBind", "Bind", "PostBind"},
9595
},
9696
"scheduler_scheduling_attempt_duration_seconds": nil,
9797
"scheduler_pod_scheduling_duration_seconds": nil,

0 commit comments

Comments
 (0)