@@ -17,10 +17,13 @@ limitations under the License.
1717package frameworkext
1818
1919import (
20+ "context"
2021 "sync"
2122
2223 nrtinformers "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/generated/informers/externalversions"
24+ corev1 "k8s.io/api/core/v1"
2325 "k8s.io/apimachinery/pkg/runtime"
26+ "k8s.io/klog/v2"
2427 "k8s.io/kubernetes/pkg/scheduler/framework"
2528 frameworkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime"
2629
@@ -96,6 +99,96 @@ func (ext *frameworkExtendedHandleImpl) NodeResourceTopologySharedInformerFactor
9699 return ext .nrtSharedInformerFactory
97100}
98101
102+ type FrameworkExtender interface {
103+ framework.Framework
104+ }
105+
106+ type FrameworkExtenderFactory interface {
107+ New (f framework.Framework ) FrameworkExtender
108+ }
109+
110+ type SchedulingPhaseHook interface {
111+ Name () string
112+ }
113+
114+ type PreFilterPhaseHook interface {
115+ SchedulingPhaseHook
116+ PreFilterHook (handle ExtendedHandle , state * framework.CycleState , pod * corev1.Pod ) (* corev1.Pod , bool )
117+ }
118+
119+ type FilterPhaseHook interface {
120+ SchedulingPhaseHook
121+ FilterHook (handle ExtendedHandle , cycleState * framework.CycleState , pod * corev1.Pod , nodeInfo * framework.NodeInfo ) (* corev1.Pod , * framework.NodeInfo , bool )
122+ }
123+
124+ type frameworkExtenderFactoryImpl struct {
125+ handle ExtendedHandle
126+
127+ // extend framework with SchedulingPhaseHook
128+ preFilterHooks []PreFilterPhaseHook
129+ filterHooks []FilterPhaseHook
130+ }
131+
132+ func NewFrameworkExtenderFactory (handle ExtendedHandle , hooks ... SchedulingPhaseHook ) FrameworkExtenderFactory {
133+ i := & frameworkExtenderFactoryImpl {
134+ handle : handle ,
135+ }
136+ for _ , h := range hooks {
137+ // a hook may register in multiple phases
138+ preFilter , ok := h .(PreFilterPhaseHook )
139+ if ok {
140+ i .preFilterHooks = append (i .preFilterHooks , preFilter )
141+ }
142+ filter , ok := h .(FilterPhaseHook )
143+ if ok {
144+ i .filterHooks = append (i .filterHooks , filter )
145+ }
146+ }
147+ return i
148+ }
149+
150+ func (i * frameworkExtenderFactoryImpl ) New (f framework.Framework ) FrameworkExtender {
151+ return & frameworkExtenderImpl {
152+ Framework : f ,
153+ handle : i .handle ,
154+ preFilterHooks : i .preFilterHooks ,
155+ filterHooks : i .filterHooks ,
156+ }
157+ }
158+
159+ var _ framework.Framework = & frameworkExtenderImpl {}
160+
161+ type frameworkExtenderImpl struct {
162+ framework.Framework
163+ handle ExtendedHandle
164+
165+ preFilterHooks []PreFilterPhaseHook
166+ filterHooks []FilterPhaseHook
167+ }
168+
169+ func (ext * frameworkExtenderImpl ) RunPreFilterPlugins (ctx context.Context , cycleState * framework.CycleState , pod * corev1.Pod ) * framework.Status {
170+ for _ , hook := range ext .preFilterHooks {
171+ newPod , hooked := hook .PreFilterHook (ext .handle , cycleState , pod )
172+ if hooked {
173+ klog .V (5 ).InfoS ("RunPreFilterPlugins hooked" , "meet PreFilterPhaseHook" , "hook" , hook .Name (), "pod" , klog .KObj (pod ))
174+ return ext .Framework .RunPreFilterPlugins (ctx , cycleState , newPod )
175+ }
176+ }
177+ return ext .Framework .RunPreFilterPlugins (ctx , cycleState , pod )
178+ }
179+
180+ func (ext * frameworkExtenderImpl ) RunFilterPlugins (ctx context.Context , cycleState * framework.CycleState , pod * corev1.Pod , nodeInfo * framework.NodeInfo ) framework.PluginToStatus {
181+ for _ , hook := range ext .filterHooks {
182+ // hook can change the args (cycleState, pod, nodeInfo) for filter plugins
183+ newPod , newNodeInfo , hooked := hook .FilterHook (ext .handle , cycleState , pod , nodeInfo )
184+ if hooked {
185+ klog .V (5 ).InfoS ("RunFilterPlugins hooked" , "meet FilterPhaseHook" , "hook" , hook .Name (), "pod" , klog .KObj (pod ))
186+ return ext .Framework .RunFilterPlugins (ctx , cycleState , newPod , newNodeInfo )
187+ }
188+ }
189+ return ext .Framework .RunFilterPlugins (ctx , cycleState , pod , nodeInfo )
190+ }
191+
99192// PluginFactoryProxy is used to proxy the call to the PluginFactory function and pass in the ExtendedHandle for the custom plugin
100193func PluginFactoryProxy (extendHandle ExtendedHandle , factoryFn frameworkruntime.PluginFactory ) frameworkruntime.PluginFactory {
101194 return func (args runtime.Object , handle framework.Handle ) (framework.Plugin , error ) {
0 commit comments