2019-03-20 20:07:25 -04:00
|
|
|
|
/*
|
|
|
|
|
|
Copyright 2019 The Kubernetes Authors.
|
|
|
|
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
|
|
limitations under the License.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// This file defines the scheduling framework plugin interfaces.
|
|
|
|
|
|
|
2020-10-09 10:41:44 -04:00
|
|
|
|
package framework
|
2019-03-20 20:07:25 -04:00
|
|
|
|
|
|
|
|
|
|
import (
|
2019-08-28 07:12:02 -04:00
|
|
|
|
"context"
|
2021-06-30 12:57:53 -04:00
|
|
|
|
"sync"
|
2019-03-20 20:07:25 -04:00
|
|
|
|
|
2019-07-30 23:21:26 -04:00
|
|
|
|
v1 "k8s.io/api/core/v1"
|
2022-03-10 17:48:33 -05:00
|
|
|
|
"k8s.io/apimachinery/pkg/util/sets"
|
2025-05-21 11:21:27 -04:00
|
|
|
|
fwk "k8s.io/kube-scheduler/framework"
|
2019-10-05 20:31:51 -04:00
|
|
|
|
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
2019-03-20 20:07:25 -04:00
|
|
|
|
)
|
|
|
|
|
|
|
2024-07-11 03:08:31 -04:00
|
|
|
|
// NodeToStatus contains the statuses of the Nodes where the incoming Pod was not schedulable.
|
|
|
|
|
|
type NodeToStatus struct {
|
|
|
|
|
|
// nodeToStatus contains specific statuses of the nodes.
|
2025-06-03 18:59:50 -04:00
|
|
|
|
nodeToStatus map[string]*fwk.Status
|
2024-07-11 03:08:31 -04:00
|
|
|
|
// absentNodesStatus defines a status for all nodes that are absent in nodeToStatus map.
|
|
|
|
|
|
// By default, all absent nodes are UnschedulableAndUnresolvable.
|
2025-06-03 18:59:50 -04:00
|
|
|
|
absentNodesStatus *fwk.Status
|
2024-07-11 03:08:31 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NewDefaultNodeToStatus creates NodeToStatus without any node in the map.
|
|
|
|
|
|
// The absentNodesStatus is set by default to UnschedulableAndUnresolvable.
|
|
|
|
|
|
func NewDefaultNodeToStatus() *NodeToStatus {
|
2025-06-03 18:59:50 -04:00
|
|
|
|
return NewNodeToStatus(make(map[string]*fwk.Status), fwk.NewStatus(fwk.UnschedulableAndUnresolvable))
|
2024-07-11 03:08:31 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NewNodeToStatus creates NodeToStatus initialized with given nodeToStatus and absentNodesStatus.
|
2025-06-03 18:59:50 -04:00
|
|
|
|
func NewNodeToStatus(nodeToStatus map[string]*fwk.Status, absentNodesStatus *fwk.Status) *NodeToStatus {
|
2024-07-11 03:08:31 -04:00
|
|
|
|
return &NodeToStatus{
|
|
|
|
|
|
nodeToStatus: nodeToStatus,
|
|
|
|
|
|
absentNodesStatus: absentNodesStatus,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Get returns the status for given nodeName. If the node is not in the map, the absentNodesStatus is returned.
|
2025-06-03 18:59:50 -04:00
|
|
|
|
func (m *NodeToStatus) Get(nodeName string) *fwk.Status {
|
2024-07-11 03:08:31 -04:00
|
|
|
|
if status, ok := m.nodeToStatus[nodeName]; ok {
|
|
|
|
|
|
return status
|
|
|
|
|
|
}
|
|
|
|
|
|
return m.absentNodesStatus
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set sets status for given nodeName.
|
2025-06-03 18:59:50 -04:00
|
|
|
|
func (m *NodeToStatus) Set(nodeName string, status *fwk.Status) {
|
2024-07-11 03:08:31 -04:00
|
|
|
|
m.nodeToStatus[nodeName] = status
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Len returns length of nodeToStatus map. It is not aware of number of absent nodes.
|
|
|
|
|
|
func (m *NodeToStatus) Len() int {
|
|
|
|
|
|
return len(m.nodeToStatus)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// AbsentNodesStatus returns absentNodesStatus value.
|
2025-06-03 18:59:50 -04:00
|
|
|
|
func (m *NodeToStatus) AbsentNodesStatus() *fwk.Status {
|
2024-07-11 03:08:31 -04:00
|
|
|
|
return m.absentNodesStatus
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SetAbsentNodesStatus sets absentNodesStatus value.
|
2025-06-03 18:59:50 -04:00
|
|
|
|
func (m *NodeToStatus) SetAbsentNodesStatus(status *fwk.Status) {
|
2024-07-11 03:08:31 -04:00
|
|
|
|
m.absentNodesStatus = status
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ForEachExplicitNode runs fn for each node which status is explicitly set.
|
|
|
|
|
|
// Imporatant note, it runs the fn only for nodes with a status explicitly registered,
|
|
|
|
|
|
// and hence may not run the fn for all existing nodes.
|
|
|
|
|
|
// For example, if PreFilter rejects all Nodes, the scheduler would NOT set a failure status to every Node,
|
|
|
|
|
|
// but set a failure status as AbsentNodesStatus.
|
|
|
|
|
|
// You're supposed to get a status from AbsentNodesStatus(), and consider all other nodes that are rejected by them.
|
2025-06-03 18:59:50 -04:00
|
|
|
|
func (m *NodeToStatus) ForEachExplicitNode(fn func(nodeName string, status *fwk.Status)) {
|
2024-07-11 03:08:31 -04:00
|
|
|
|
for nodeName, status := range m.nodeToStatus {
|
|
|
|
|
|
fn(nodeName, status)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NodesForStatusCode returns a list of NodeInfos for the nodes that matches a given status code.
|
|
|
|
|
|
// If the absentNodesStatus matches the code, all existing nodes are fetched using nodeLister
|
|
|
|
|
|
// and filtered using NodeToStatus.Get.
|
|
|
|
|
|
// If the absentNodesStatus doesn't match the code, nodeToStatus map is used to create a list of nodes
|
|
|
|
|
|
// and nodeLister.Get is used to obtain NodeInfo for each.
|
2025-07-24 07:48:07 -04:00
|
|
|
|
func (m *NodeToStatus) NodesForStatusCode(nodeLister fwk.NodeInfoLister, code fwk.Code) ([]fwk.NodeInfo, error) {
|
2025-06-11 05:56:18 -04:00
|
|
|
|
var resultNodes []fwk.NodeInfo
|
2024-07-11 03:08:31 -04:00
|
|
|
|
|
|
|
|
|
|
if m.AbsentNodesStatus().Code() == code {
|
|
|
|
|
|
allNodes, err := nodeLister.List()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
if m.Len() == 0 {
|
|
|
|
|
|
// All nodes are absent and status code is matching, so can return all nodes.
|
|
|
|
|
|
return allNodes, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
// Need to find all the nodes that are absent or have a matching code using the allNodes.
|
|
|
|
|
|
for _, node := range allNodes {
|
|
|
|
|
|
nodeName := node.Node().Name
|
|
|
|
|
|
if status := m.Get(nodeName); status.Code() == code {
|
|
|
|
|
|
resultNodes = append(resultNodes, node)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return resultNodes, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-03 18:59:50 -04:00
|
|
|
|
m.ForEachExplicitNode(func(nodeName string, status *fwk.Status) {
|
2024-07-11 03:08:31 -04:00
|
|
|
|
if status.Code() == code {
|
|
|
|
|
|
if nodeInfo, err := nodeLister.Get(nodeName); err == nil {
|
|
|
|
|
|
resultNodes = append(resultNodes, nodeInfo)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
return resultNodes, nil
|
|
|
|
|
|
}
|
2019-07-30 23:21:26 -04:00
|
|
|
|
|
2021-06-30 12:57:53 -04:00
|
|
|
|
// PodsToActivateKey is a reserved state key for stashing pods.
|
2022-03-24 05:38:49 -04:00
|
|
|
|
// If the stashed pods are present in unschedulablePods or backoffQ,they will be
|
2021-06-30 12:57:53 -04:00
|
|
|
|
// activated (i.e., moved to activeQ) in two phases:
|
|
|
|
|
|
// - end of a scheduling cycle if it succeeds (will be cleared from `PodsToActivate` if activated)
|
|
|
|
|
|
// - end of a binding cycle if it succeeds
|
2025-05-21 11:21:27 -04:00
|
|
|
|
var PodsToActivateKey fwk.StateKey = "kubernetes.io/pods-to-activate"
|
2021-06-30 12:57:53 -04:00
|
|
|
|
|
|
|
|
|
|
// PodsToActivate stores pods to be activated.
|
|
|
|
|
|
type PodsToActivate struct {
|
|
|
|
|
|
sync.Mutex
|
|
|
|
|
|
// Map is keyed with namespaced pod name, and valued with the pod.
|
|
|
|
|
|
Map map[string]*v1.Pod
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Clone just returns the same state.
|
2025-05-21 11:21:27 -04:00
|
|
|
|
func (s *PodsToActivate) Clone() fwk.StateData {
|
2021-06-30 12:57:53 -04:00
|
|
|
|
return s
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NewPodsToActivate instantiates a PodsToActivate object.
|
|
|
|
|
|
func NewPodsToActivate() *PodsToActivate {
|
|
|
|
|
|
return &PodsToActivate{Map: make(map[string]*v1.Pod)}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-13 00:51:37 -05:00
|
|
|
|
// SortedScoredNodes is a list of scored nodes, returned from scheduling.
|
|
|
|
|
|
type SortedScoredNodes interface {
|
|
|
|
|
|
Pop() string
|
|
|
|
|
|
Len() int
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-20 20:07:25 -04:00
|
|
|
|
// Framework manages the set of plugins in use by the scheduling framework.
|
|
|
|
|
|
// Configured plugins are called at specified points in a scheduling context.
|
|
|
|
|
|
type Framework interface {
|
2025-07-24 07:48:07 -04:00
|
|
|
|
fwk.Handle
|
2022-11-07 17:02:22 -05:00
|
|
|
|
|
|
|
|
|
|
// PreEnqueuePlugins returns the registered preEnqueue plugins.
|
2025-07-24 07:48:07 -04:00
|
|
|
|
PreEnqueuePlugins() []fwk.PreEnqueuePlugin
|
2022-11-07 17:02:22 -05:00
|
|
|
|
|
2023-06-08 00:54:30 -04:00
|
|
|
|
// EnqueueExtensions returns the registered Enqueue extensions.
|
2025-07-24 07:48:07 -04:00
|
|
|
|
EnqueueExtensions() []fwk.EnqueueExtensions
|
2023-06-08 00:54:30 -04:00
|
|
|
|
|
2019-05-06 21:03:00 -04:00
|
|
|
|
// QueueSortFunc returns the function to sort pods in scheduling queue
|
2025-07-24 07:48:07 -04:00
|
|
|
|
QueueSortFunc() fwk.LessFunc
|
2019-05-06 21:03:00 -04:00
|
|
|
|
|
2025-11-13 00:51:37 -05:00
|
|
|
|
// Create a scheduling signature for a given pod, if possible. Two pods with the same signature
|
|
|
|
|
|
// should get the same feasibility and scores for any given set of nodes even after one of them gets assigned. If some plugins
|
|
|
|
|
|
// are unable to create a signature, the pod may be "unsignable" which disables results caching
|
|
|
|
|
|
// and gang scheduling optimizations.
|
|
|
|
|
|
// See https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/5598-opportunistic-batching
|
|
|
|
|
|
SignPod(ctx context.Context, pod *v1.Pod, recordPluginStats bool) fwk.PodSignature
|
|
|
|
|
|
|
2020-08-31 18:51:42 -04:00
|
|
|
|
// RunPreFilterPlugins runs the set of configured PreFilter plugins. It returns
|
2025-06-03 18:59:50 -04:00
|
|
|
|
// *fwk.Status and its code is set to non-success if any of the plugins returns
|
2019-06-10 17:01:50 -04:00
|
|
|
|
// anything but Success. If a non-success status is returned, then the scheduling
|
|
|
|
|
|
// cycle is aborted.
|
2022-03-10 17:48:33 -05:00
|
|
|
|
// It also returns a PreFilterResult, which may influence what or how many nodes to
|
|
|
|
|
|
// evaluate downstream.
|
2024-07-01 21:26:58 -04:00
|
|
|
|
// The third returns value contains PreFilter plugin that rejected some or all Nodes with PreFilterResult.
|
|
|
|
|
|
// But, note that it doesn't contain any plugin when a plugin rejects this Pod with non-success status,
|
|
|
|
|
|
// not with PreFilterResult.
|
2025-07-24 07:48:07 -04:00
|
|
|
|
RunPreFilterPlugins(ctx context.Context, state fwk.CycleState, pod *v1.Pod) (*fwk.PreFilterResult, *fwk.Status, sets.Set[string])
|
2019-06-10 17:01:50 -04:00
|
|
|
|
|
2020-06-05 16:02:45 -04:00
|
|
|
|
// RunPostFilterPlugins runs the set of configured PostFilter plugins.
|
|
|
|
|
|
// PostFilter plugins can either be informational, in which case should be configured
|
|
|
|
|
|
// to execute first and return Unschedulable status, or ones that try to change the
|
|
|
|
|
|
// cluster state to make the pod potentially schedulable in a future scheduling cycle.
|
2025-07-24 07:48:07 -04:00
|
|
|
|
RunPostFilterPlugins(ctx context.Context, state fwk.CycleState, pod *v1.Pod, filteredNodeStatusMap fwk.NodeToStatusReader) (*fwk.PostFilterResult, *fwk.Status)
|
2020-06-05 16:02:45 -04:00
|
|
|
|
|
2025-11-13 00:51:37 -05:00
|
|
|
|
// Get a "node hint" for a given pod. A node hint is the name of a node provided by the batching code when information
|
|
|
|
|
|
// from the previous scheduling cycle can be reused for this cycle.
|
|
|
|
|
|
// If the batching code cannot provide a hint, the function returns "".
|
|
|
|
|
|
// See git.k8s.io/enhancements/keps/sig-scheduling/5598-opportunistic-batching
|
|
|
|
|
|
GetNodeHint(ctx context.Context, pod *v1.Pod, state fwk.CycleState, cycleCount int64) (hint string, signature fwk.PodSignature)
|
|
|
|
|
|
|
|
|
|
|
|
// StoreScheduleResults stores the results after we have sorted and filtered nodes.
|
|
|
|
|
|
StoreScheduleResults(ctx context.Context, signature fwk.PodSignature, hintedNode, chosenNode string, otherNodes SortedScoredNodes, cycleCount int64)
|
|
|
|
|
|
|
2020-08-31 18:51:42 -04:00
|
|
|
|
// RunPreBindPlugins runs the set of configured PreBind plugins. It returns
|
2025-06-03 18:59:50 -04:00
|
|
|
|
// *fwk.Status and its code is set to non-success if any of the plugins returns
|
2019-03-20 20:07:25 -04:00
|
|
|
|
// 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.
|
2025-06-03 18:59:50 -04:00
|
|
|
|
RunPreBindPlugins(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string) *fwk.Status
|
2019-03-20 20:07:25 -04:00
|
|
|
|
|
2025-07-17 03:30:10 -04:00
|
|
|
|
// RunPreBindPreFlights runs the set of configured PreBindPreFlight functions from PreBind plugins.
|
|
|
|
|
|
// It returns immediately if any of the plugins returns a non-skip status.
|
|
|
|
|
|
RunPreBindPreFlights(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string) *fwk.Status
|
|
|
|
|
|
|
2020-08-31 18:51:42 -04:00
|
|
|
|
// RunPostBindPlugins runs the set of configured PostBind plugins.
|
2025-05-21 11:21:27 -04:00
|
|
|
|
RunPostBindPlugins(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string)
|
2019-05-08 07:55:39 -04:00
|
|
|
|
|
2020-06-15 17:52:54 -04:00
|
|
|
|
// RunReservePluginsReserve runs the Reserve method of the set of
|
2020-08-31 18:51:42 -04:00
|
|
|
|
// configured Reserve plugins. If any of these calls returns an error, it
|
2020-06-15 17:52:54 -04:00
|
|
|
|
// does not continue running the remaining ones and returns the error. In
|
|
|
|
|
|
// such case, pod will not be scheduled.
|
2025-06-03 18:59:50 -04:00
|
|
|
|
RunReservePluginsReserve(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string) *fwk.Status
|
2019-05-04 23:16:14 -04:00
|
|
|
|
|
2020-06-15 17:52:54 -04:00
|
|
|
|
// RunReservePluginsUnreserve runs the Unreserve method of the set of
|
2020-08-31 18:51:42 -04:00
|
|
|
|
// configured Reserve plugins.
|
2025-05-21 11:21:27 -04:00
|
|
|
|
RunReservePluginsUnreserve(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string)
|
2019-05-10 09:05:59 -04:00
|
|
|
|
|
2020-08-31 18:51:42 -04:00
|
|
|
|
// RunPermitPlugins runs the set of configured Permit plugins. If any of these
|
2019-05-10 09:05:59 -04:00
|
|
|
|
// plugins returns a status other than "Success" or "Wait", it does not continue
|
|
|
|
|
|
// running the remaining plugins and returns an error. Otherwise, if any of the
|
2020-02-15 19:28:43 -05:00
|
|
|
|
// plugins returns "Wait", then this function will create and add waiting pod
|
|
|
|
|
|
// to a map of currently waiting pods and return status with "Wait" code.
|
2020-08-31 18:51:42 -04:00
|
|
|
|
// Pod will remain waiting pod for the minimum duration returned by the Permit plugins.
|
2025-06-03 18:59:50 -04:00
|
|
|
|
RunPermitPlugins(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string) *fwk.Status
|
2019-06-23 12:42:28 -04:00
|
|
|
|
|
2025-07-17 03:30:10 -04:00
|
|
|
|
// WillWaitOnPermit returns whether this pod will wait on permit by checking if the pod is a waiting pod.
|
|
|
|
|
|
WillWaitOnPermit(ctx context.Context, pod *v1.Pod) bool
|
|
|
|
|
|
|
2020-02-15 19:28:43 -05:00
|
|
|
|
// WaitOnPermit will block, if the pod is a waiting pod, until the waiting pod is rejected or allowed.
|
2025-06-03 18:59:50 -04:00
|
|
|
|
WaitOnPermit(ctx context.Context, pod *v1.Pod) *fwk.Status
|
2020-02-15 19:28:43 -05:00
|
|
|
|
|
2020-08-31 18:51:42 -04:00
|
|
|
|
// 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
|
2020-01-15 11:26:35 -05:00
|
|
|
|
// binding, it should return code=5("skip") status. Otherwise, it should return "Error"
|
2019-06-23 12:42:28 -04:00
|
|
|
|
// or "Success". If none of the plugins handled binding, RunBindPlugins returns
|
2020-01-15 11:26:35 -05:00
|
|
|
|
// code=5("skip") status.
|
2025-06-03 18:59:50 -04:00
|
|
|
|
RunBindPlugins(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string) *fwk.Status
|
2019-10-04 17:40:21 -04:00
|
|
|
|
|
2020-08-31 18:51:42 -04:00
|
|
|
|
// HasFilterPlugins returns true if at least one Filter plugin is defined.
|
2019-10-16 21:24:33 -04:00
|
|
|
|
HasFilterPlugins() bool
|
|
|
|
|
|
|
2020-08-31 18:51:42 -04:00
|
|
|
|
// HasPostFilterPlugins returns true if at least one PostFilter plugin is defined.
|
2020-06-22 20:22:27 -04:00
|
|
|
|
HasPostFilterPlugins() bool
|
|
|
|
|
|
|
2020-08-31 18:51:42 -04:00
|
|
|
|
// HasScorePlugins returns true if at least one Score plugin is defined.
|
2019-10-29 05:25:35 -04:00
|
|
|
|
HasScorePlugins() bool
|
|
|
|
|
|
|
2019-10-05 20:31:51 -04:00
|
|
|
|
// ListPlugins returns a map of extension point name to list of configured Plugins.
|
2021-06-10 08:45:49 -04:00
|
|
|
|
ListPlugins() *config.Plugins
|
2020-10-18 22:43:50 -04:00
|
|
|
|
|
2022-09-16 16:18:12 -04:00
|
|
|
|
// PercentageOfNodesToScore returns percentageOfNodesToScore associated to a profile.
|
|
|
|
|
|
PercentageOfNodesToScore() *int32
|
2023-03-08 16:18:36 -05:00
|
|
|
|
|
|
|
|
|
|
// SetPodNominator sets the PodNominator
|
2025-07-24 07:48:07 -04:00
|
|
|
|
SetPodNominator(nominator fwk.PodNominator)
|
2024-11-04 10:14:54 -05:00
|
|
|
|
// SetPodActivator sets the PodActivator
|
2025-07-24 07:48:07 -04:00
|
|
|
|
SetPodActivator(activator fwk.PodActivator)
|
2025-07-25 05:21:22 -04:00
|
|
|
|
// SetAPICacher sets the APICacher
|
2025-07-24 07:48:07 -04:00
|
|
|
|
SetAPICacher(apiCacher fwk.APICacher)
|
2023-12-27 10:18:29 -05:00
|
|
|
|
|
|
|
|
|
|
// Close calls Close method of each plugin.
|
|
|
|
|
|
Close() error
|
2019-03-20 20:07:25 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-24 07:48:07 -04:00
|
|
|
|
func NewPostFilterResultWithNominatedNode(name string) *fwk.PostFilterResult {
|
|
|
|
|
|
return &fwk.PostFilterResult{
|
|
|
|
|
|
NominatingInfo: &fwk.NominatingInfo{
|
2021-12-16 13:54:58 -05:00
|
|
|
|
NominatedNodeName: name,
|
2025-07-24 07:48:07 -04:00
|
|
|
|
NominatingMode: fwk.ModeOverride,
|
2021-12-16 13:54:58 -05:00
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|