interface.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. /*
  2. Copyright 2019 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. // This file defines the scheduling framework plugin interfaces.
  14. package v1alpha1
  15. import (
  16. "context"
  17. "errors"
  18. "math"
  19. "strings"
  20. "time"
  21. v1 "k8s.io/api/core/v1"
  22. "k8s.io/apimachinery/pkg/types"
  23. "k8s.io/client-go/informers"
  24. clientset "k8s.io/client-go/kubernetes"
  25. "k8s.io/kubernetes/pkg/scheduler/apis/config"
  26. schedulerlisters "k8s.io/kubernetes/pkg/scheduler/listers"
  27. schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
  28. "k8s.io/kubernetes/pkg/scheduler/volumebinder"
  29. )
  30. // NodeScoreList declares a list of nodes and their scores.
  31. type NodeScoreList []NodeScore
  32. // NodeScore is a struct with node name and score.
  33. type NodeScore struct {
  34. Name string
  35. Score int64
  36. }
  37. // PluginToNodeScores declares a map from plugin name to its NodeScoreList.
  38. type PluginToNodeScores map[string]NodeScoreList
  39. // NodeToStatusMap declares map from node name to its status.
  40. type NodeToStatusMap map[string]*Status
  41. // Code is the Status code/type which is returned from plugins.
  42. type Code int
  43. // These are predefined codes used in a Status.
  44. const (
  45. // Success means that plugin ran correctly and found pod schedulable.
  46. // NOTE: A nil status is also considered as "Success".
  47. Success Code = iota
  48. // Error is used for internal plugin errors, unexpected input, etc.
  49. Error
  50. // Unschedulable is used when a plugin finds a pod unschedulable. The scheduler might attempt to
  51. // preempt other pods to get this pod scheduled. Use UnschedulableAndUnresolvable to make the
  52. // scheduler skip preemption.
  53. // The accompanying status message should explain why the pod is unschedulable.
  54. Unschedulable
  55. // UnschedulableAndUnresolvable is used when a (pre-)filter plugin finds a pod unschedulable and
  56. // preemption would not change anything. Plugins should return Unschedulable if it is possible
  57. // that the pod can get scheduled with preemption.
  58. // The accompanying status message should explain why the pod is unschedulable.
  59. UnschedulableAndUnresolvable
  60. // Wait is used when a permit plugin finds a pod scheduling should wait.
  61. Wait
  62. // Skip is used when a bind plugin chooses to skip binding.
  63. Skip
  64. )
  65. // This list should be exactly the same as the codes iota defined above in the same order.
  66. var codes = []string{"Success", "Error", "Unschedulable", "UnschedulableAndUnresolvable", "Wait", "Skip"}
  67. func (c Code) String() string {
  68. return codes[c]
  69. }
  70. const (
  71. // MaxNodeScore is the maximum score a Score plugin is expected to return.
  72. MaxNodeScore int64 = 100
  73. // MinNodeScore is the minimum score a Score plugin is expected to return.
  74. MinNodeScore int64 = 0
  75. // MaxTotalScore is the maximum total score.
  76. MaxTotalScore int64 = math.MaxInt64
  77. )
  78. // Status indicates the result of running a plugin. It consists of a code and a
  79. // message. When the status code is not `Success`, the reasons should explain why.
  80. // NOTE: A nil Status is also considered as Success.
  81. type Status struct {
  82. code Code
  83. reasons []string
  84. }
  85. // Code returns code of the Status.
  86. func (s *Status) Code() Code {
  87. if s == nil {
  88. return Success
  89. }
  90. return s.code
  91. }
  92. // Message returns a concatenated message on reasons of the Status.
  93. func (s *Status) Message() string {
  94. if s == nil {
  95. return ""
  96. }
  97. return strings.Join(s.reasons, ", ")
  98. }
  99. // Reasons returns reasons of the Status.
  100. func (s *Status) Reasons() []string {
  101. return s.reasons
  102. }
  103. // AppendReason appends given reason to the Status.
  104. func (s *Status) AppendReason(reason string) {
  105. s.reasons = append(s.reasons, reason)
  106. }
  107. // IsSuccess returns true if and only if "Status" is nil or Code is "Success".
  108. func (s *Status) IsSuccess() bool {
  109. return s.Code() == Success
  110. }
  111. // IsUnschedulable returns true if "Status" is Unschedulable (Unschedulable or UnschedulableAndUnresolvable).
  112. func (s *Status) IsUnschedulable() bool {
  113. code := s.Code()
  114. return code == Unschedulable || code == UnschedulableAndUnresolvable
  115. }
  116. // AsError returns nil if the status is a success; otherwise returns an "error" object
  117. // with a concatenated message on reasons of the Status.
  118. func (s *Status) AsError() error {
  119. if s.IsSuccess() {
  120. return nil
  121. }
  122. return errors.New(s.Message())
  123. }
  124. // NewStatus makes a Status out of the given arguments and returns its pointer.
  125. func NewStatus(code Code, reasons ...string) *Status {
  126. return &Status{
  127. code: code,
  128. reasons: reasons,
  129. }
  130. }
  131. // PluginToStatus maps plugin name to status. Currently used to identify which Filter plugin
  132. // returned which status.
  133. type PluginToStatus map[string]*Status
  134. // Merge merges the statuses in the map into one. The resulting status code have the following
  135. // precedence: Error, UnschedulableAndUnresolvable, Unschedulable.
  136. func (p PluginToStatus) Merge() *Status {
  137. if len(p) == 0 {
  138. return nil
  139. }
  140. finalStatus := NewStatus(Success)
  141. var hasError, hasUnschedulableAndUnresolvable, hasUnschedulable bool
  142. for _, s := range p {
  143. if s.Code() == Error {
  144. hasError = true
  145. } else if s.Code() == UnschedulableAndUnresolvable {
  146. hasUnschedulableAndUnresolvable = true
  147. } else if s.Code() == Unschedulable {
  148. hasUnschedulable = true
  149. }
  150. finalStatus.code = s.Code()
  151. for _, r := range s.reasons {
  152. finalStatus.AppendReason(r)
  153. }
  154. }
  155. if hasError {
  156. finalStatus.code = Error
  157. } else if hasUnschedulableAndUnresolvable {
  158. finalStatus.code = UnschedulableAndUnresolvable
  159. } else if hasUnschedulable {
  160. finalStatus.code = Unschedulable
  161. }
  162. return finalStatus
  163. }
  164. // WaitingPod represents a pod currently waiting in the permit phase.
  165. type WaitingPod interface {
  166. // GetPod returns a reference to the waiting pod.
  167. GetPod() *v1.Pod
  168. // GetPendingPlugins returns a list of pending permit plugin's name.
  169. GetPendingPlugins() []string
  170. // Allow declares the waiting pod is allowed to be scheduled by plugin pluginName.
  171. // If this is the last remaining plugin to allow, then a success signal is delivered
  172. // to unblock the pod.
  173. Allow(pluginName string)
  174. // Reject declares the waiting pod unschedulable.
  175. Reject(msg string)
  176. }
  177. // Plugin is the parent type for all the scheduling framework plugins.
  178. type Plugin interface {
  179. Name() string
  180. }
  181. // PodInfo is a wrapper to a Pod with additional information for purposes such as tracking
  182. // the timestamp when it's added to the queue or recording per-pod metrics.
  183. type PodInfo struct {
  184. Pod *v1.Pod
  185. // The time pod added to the scheduling queue.
  186. Timestamp time.Time
  187. // Number of schedule attempts before successfully scheduled.
  188. // It's used to record the # attempts metric.
  189. Attempts int
  190. // The time when the pod is added to the queue for the first time. The pod may be added
  191. // back to the queue multiple times before it's successfully scheduled.
  192. // It shouldn't be updated once initialized. It's used to record the e2e scheduling
  193. // latency for a pod.
  194. InitialAttemptTimestamp time.Time
  195. }
  196. // DeepCopy returns a deep copy of the PodInfo object.
  197. func (podInfo *PodInfo) DeepCopy() *PodInfo {
  198. return &PodInfo{
  199. Pod: podInfo.Pod.DeepCopy(),
  200. Timestamp: podInfo.Timestamp,
  201. Attempts: podInfo.Attempts,
  202. InitialAttemptTimestamp: podInfo.InitialAttemptTimestamp,
  203. }
  204. }
  205. // LessFunc is the function to sort pod info
  206. type LessFunc func(podInfo1, podInfo2 *PodInfo) bool
  207. // QueueSortPlugin is an interface that must be implemented by "QueueSort" plugins.
  208. // These plugins are used to sort pods in the scheduling queue. Only one queue sort
  209. // plugin may be enabled at a time.
  210. type QueueSortPlugin interface {
  211. Plugin
  212. // Less are used to sort pods in the scheduling queue.
  213. Less(*PodInfo, *PodInfo) bool
  214. }
  215. // PreFilterExtensions is an interface that is included in plugins that allow specifying
  216. // callbacks to make incremental updates to its supposedly pre-calculated
  217. // state.
  218. type PreFilterExtensions interface {
  219. // AddPod is called by the framework while trying to evaluate the impact
  220. // of adding podToAdd to the node while scheduling podToSchedule.
  221. AddPod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod, podToAdd *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
  222. // RemovePod is called by the framework while trying to evaluate the impact
  223. // of removing podToRemove from the node while scheduling podToSchedule.
  224. RemovePod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod, podToRemove *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
  225. }
  226. // PreFilterPlugin is an interface that must be implemented by "prefilter" plugins.
  227. // These plugins are called at the beginning of the scheduling cycle.
  228. type PreFilterPlugin interface {
  229. Plugin
  230. // PreFilter is called at the beginning of the scheduling cycle. All PreFilter
  231. // plugins must return success or the pod will be rejected.
  232. PreFilter(ctx context.Context, state *CycleState, p *v1.Pod) *Status
  233. // PreFilterExtensions returns a PreFilterExtensions interface if the plugin implements one,
  234. // or nil if it does not. A Pre-filter plugin can provide extensions to incrementally
  235. // modify its pre-processed info. The framework guarantees that the extensions
  236. // AddPod/RemovePod will only be called after PreFilter, possibly on a cloned
  237. // CycleState, and may call those functions more than once before calling
  238. // Filter again on a specific node.
  239. PreFilterExtensions() PreFilterExtensions
  240. }
  241. // FilterPlugin is an interface for Filter plugins. These plugins are called at the
  242. // filter extension point for filtering out hosts that cannot run a pod.
  243. // This concept used to be called 'predicate' in the original scheduler.
  244. // These plugins should return "Success", "Unschedulable" or "Error" in Status.code.
  245. // However, the scheduler accepts other valid codes as well.
  246. // Anything other than "Success" will lead to exclusion of the given host from
  247. // running the pod.
  248. type FilterPlugin interface {
  249. Plugin
  250. // Filter is called by the scheduling framework.
  251. // All FilterPlugins should return "Success" to declare that
  252. // the given node fits the pod. If Filter doesn't return "Success",
  253. // please refer scheduler/algorithm/predicates/error.go
  254. // to set error message.
  255. // For the node being evaluated, Filter plugins should look at the passed
  256. // nodeInfo reference for this particular node's information (e.g., pods
  257. // considered to be running on the node) instead of looking it up in the
  258. // NodeInfoSnapshot because we don't guarantee that they will be the same.
  259. // For example, during preemption, we may pass a copy of the original
  260. // nodeInfo object that has some pods removed from it to evaluate the
  261. // possibility of preempting them to schedule the target pod.
  262. Filter(ctx context.Context, state *CycleState, pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
  263. }
  264. // PostFilterPlugin is an interface for Post-filter plugin. Post-filter is an
  265. // informational extension point. Plugins will be called with a list of nodes
  266. // that passed the filtering phase. A plugin may use this data to update internal
  267. // state or to generate logs/metrics.
  268. type PostFilterPlugin interface {
  269. Plugin
  270. // PostFilter is called by the scheduling framework after a list of nodes
  271. // passed the filtering phase. All postfilter plugins must return success or
  272. // the pod will be rejected. The filteredNodesStatuses is the set of filtered nodes
  273. // and their filter status.
  274. PostFilter(ctx context.Context, state *CycleState, pod *v1.Pod, nodes []*v1.Node, filteredNodesStatuses NodeToStatusMap) *Status
  275. }
  276. // ScoreExtensions is an interface for Score extended functionality.
  277. type ScoreExtensions interface {
  278. // NormalizeScore is called for all node scores produced by the same plugin's "Score"
  279. // method. A successful run of NormalizeScore will update the scores list and return
  280. // a success status.
  281. NormalizeScore(ctx context.Context, state *CycleState, p *v1.Pod, scores NodeScoreList) *Status
  282. }
  283. // ScorePlugin is an interface that must be implemented by "score" plugins to rank
  284. // nodes that passed the filtering phase.
  285. type ScorePlugin interface {
  286. Plugin
  287. // Score is called on each filtered node. It must return success and an integer
  288. // indicating the rank of the node. All scoring plugins must return success or
  289. // the pod will be rejected.
  290. Score(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) (int64, *Status)
  291. // ScoreExtensions returns a ScoreExtensions interface if it implements one, or nil if does not.
  292. ScoreExtensions() ScoreExtensions
  293. }
  294. // ReservePlugin is an interface for Reserve plugins. These plugins are called
  295. // at the reservation point. These are meant to update the state of the plugin.
  296. // This concept used to be called 'assume' in the original scheduler.
  297. // These plugins should return only Success or Error in Status.code. However,
  298. // the scheduler accepts other valid codes as well. Anything other than Success
  299. // will lead to rejection of the pod.
  300. type ReservePlugin interface {
  301. Plugin
  302. // Reserve is called by the scheduling framework when the scheduler cache is
  303. // updated.
  304. Reserve(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) *Status
  305. }
  306. // PreBindPlugin is an interface that must be implemented by "prebind" plugins.
  307. // These plugins are called before a pod being scheduled.
  308. type PreBindPlugin interface {
  309. Plugin
  310. // PreBind is called before binding a pod. All prebind plugins must return
  311. // success or the pod will be rejected and won't be sent for binding.
  312. PreBind(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) *Status
  313. }
  314. // PostBindPlugin is an interface that must be implemented by "postbind" plugins.
  315. // These plugins are called after a pod is successfully bound to a node.
  316. type PostBindPlugin interface {
  317. Plugin
  318. // PostBind is called after a pod is successfully bound. These plugins are
  319. // informational. A common application of this extension point is for cleaning
  320. // up. If a plugin needs to clean-up its state after a pod is scheduled and
  321. // bound, PostBind is the extension point that it should register.
  322. PostBind(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string)
  323. }
  324. // UnreservePlugin is an interface for Unreserve plugins. This is an informational
  325. // extension point. If a pod was reserved and then rejected in a later phase, then
  326. // un-reserve plugins will be notified. Un-reserve plugins should clean up state
  327. // associated with the reserved Pod.
  328. type UnreservePlugin interface {
  329. Plugin
  330. // Unreserve is called by the scheduling framework when a reserved pod was
  331. // rejected in a later phase.
  332. Unreserve(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string)
  333. }
  334. // PermitPlugin is an interface that must be implemented by "permit" plugins.
  335. // These plugins are called before a pod is bound to a node.
  336. type PermitPlugin interface {
  337. Plugin
  338. // Permit is called before binding a pod (and before prebind plugins). Permit
  339. // plugins are used to prevent or delay the binding of a Pod. A permit plugin
  340. // must return success or wait with timeout duration, or the pod will be rejected.
  341. // The pod will also be rejected if the wait timeout or the pod is rejected while
  342. // waiting. Note that if the plugin returns "wait", the framework will wait only
  343. // after running the remaining plugins given that no other plugin rejects the pod.
  344. Permit(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) (*Status, time.Duration)
  345. }
  346. // BindPlugin is an interface that must be implemented by "bind" plugins. Bind
  347. // plugins are used to bind a pod to a Node.
  348. type BindPlugin interface {
  349. Plugin
  350. // Bind plugins will not be called until all pre-bind plugins have completed. Each
  351. // bind plugin is called in the configured order. A bind plugin may choose whether
  352. // or not to handle the given Pod. If a bind plugin chooses to handle a Pod, the
  353. // remaining bind plugins are skipped. When a bind plugin does not handle a pod,
  354. // it must return Skip in its Status code. If a bind plugin returns an Error, the
  355. // pod is rejected and will not be bound.
  356. Bind(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) *Status
  357. }
  358. // Framework manages the set of plugins in use by the scheduling framework.
  359. // Configured plugins are called at specified points in a scheduling context.
  360. type Framework interface {
  361. FrameworkHandle
  362. // QueueSortFunc returns the function to sort pods in scheduling queue
  363. QueueSortFunc() LessFunc
  364. // RunPreFilterPlugins runs the set of configured prefilter plugins. It returns
  365. // *Status and its code is set to non-success if any of the plugins returns
  366. // anything but Success. If a non-success status is returned, then the scheduling
  367. // cycle is aborted.
  368. RunPreFilterPlugins(ctx context.Context, state *CycleState, pod *v1.Pod) *Status
  369. // RunFilterPlugins runs the set of configured filter plugins for pod on
  370. // the given node. Note that for the node being evaluated, the passed nodeInfo
  371. // reference could be different from the one in NodeInfoSnapshot map (e.g., pods
  372. // considered to be running on the node could be different). For example, during
  373. // preemption, we may pass a copy of the original nodeInfo object that has some pods
  374. // removed from it to evaluate the possibility of preempting them to
  375. // schedule the target pod.
  376. RunFilterPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) PluginToStatus
  377. // RunPreFilterExtensionAddPod calls the AddPod interface for the set of configured
  378. // PreFilter plugins. It returns directly if any of the plugins return any
  379. // status other than Success.
  380. RunPreFilterExtensionAddPod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod, podToAdd *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
  381. // RunPreFilterExtensionRemovePod calls the RemovePod interface for the set of configured
  382. // PreFilter plugins. It returns directly if any of the plugins return any
  383. // status other than Success.
  384. RunPreFilterExtensionRemovePod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod, podToAdd *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
  385. // RunPostFilterPlugins runs the set of configured post-filter plugins. If any
  386. // of these plugins returns any status other than "Success", the given node is
  387. // rejected. The filteredNodeStatuses is the set of filtered nodes and their statuses.
  388. RunPostFilterPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodes []*v1.Node, filteredNodesStatuses NodeToStatusMap) *Status
  389. // RunScorePlugins runs the set of configured scoring plugins. It returns a map that
  390. // stores for each scoring plugin name the corresponding NodeScoreList(s).
  391. // It also returns *Status, which is set to non-success if any of the plugins returns
  392. // a non-success status.
  393. RunScorePlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodes []*v1.Node) (PluginToNodeScores, *Status)
  394. // RunPreBindPlugins runs the set of configured prebind plugins. It returns
  395. // *Status and its code is set to non-success if any of the plugins returns
  396. // anything but Success. If the Status code is "Unschedulable", it is
  397. // considered as a scheduling check failure, otherwise, it is considered as an
  398. // internal error. In either case the pod is not going to be bound.
  399. RunPreBindPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) *Status
  400. // RunPostBindPlugins runs the set of configured postbind plugins.
  401. RunPostBindPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string)
  402. // RunReservePlugins runs the set of configured reserve plugins. If any of these
  403. // plugins returns an error, it does not continue running the remaining ones and
  404. // returns the error. In such case, pod will not be scheduled.
  405. RunReservePlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) *Status
  406. // RunUnreservePlugins runs the set of configured unreserve plugins.
  407. RunUnreservePlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string)
  408. // RunPermitPlugins runs the set of configured permit plugins. If any of these
  409. // plugins returns a status other than "Success" or "Wait", it does not continue
  410. // running the remaining plugins and returns an error. Otherwise, if any of the
  411. // plugins returns "Wait", then this function will block for the timeout period
  412. // returned by the plugin, if the time expires, then it will return an error.
  413. // Note that if multiple plugins asked to wait, then we wait for the minimum
  414. // timeout duration.
  415. RunPermitPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) *Status
  416. // RunBindPlugins runs the set of configured bind plugins. A bind plugin may choose
  417. // whether or not to handle the given Pod. If a bind plugin chooses to skip the
  418. // binding, it should return code=5("skip") status. Otherwise, it should return "Error"
  419. // or "Success". If none of the plugins handled binding, RunBindPlugins returns
  420. // code=5("skip") status.
  421. RunBindPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) *Status
  422. // HasFilterPlugins returns true if at least one filter plugin is defined.
  423. HasFilterPlugins() bool
  424. // HasScorePlugins returns true if at least one score plugin is defined.
  425. HasScorePlugins() bool
  426. // ListPlugins returns a map of extension point name to list of configured Plugins.
  427. ListPlugins() map[string][]config.Plugin
  428. }
  429. // FrameworkHandle provides data and some tools that plugins can use. It is
  430. // passed to the plugin factories at the time of plugin initialization. Plugins
  431. // must store and use this handle to call framework functions.
  432. type FrameworkHandle interface {
  433. // SnapshotSharedLister returns listers from the latest NodeInfo Snapshot. The snapshot
  434. // is taken at the beginning of a scheduling cycle and remains unchanged until
  435. // a pod finishes "Reserve" point. There is no guarantee that the information
  436. // remains unchanged in the binding phase of scheduling, so plugins in the binding
  437. // cycle(permit/pre-bind/bind/post-bind/un-reserve plugin) should not use it,
  438. // otherwise a concurrent read/write error might occur, they should use scheduler
  439. // cache instead.
  440. SnapshotSharedLister() schedulerlisters.SharedLister
  441. // IterateOverWaitingPods acquires a read lock and iterates over the WaitingPods map.
  442. IterateOverWaitingPods(callback func(WaitingPod))
  443. // GetWaitingPod returns a waiting pod given its UID.
  444. GetWaitingPod(uid types.UID) WaitingPod
  445. // RejectWaitingPod rejects a waiting pod given its UID.
  446. RejectWaitingPod(uid types.UID)
  447. // ClientSet returns a kubernetes clientSet.
  448. ClientSet() clientset.Interface
  449. SharedInformerFactory() informers.SharedInformerFactory
  450. // VolumeBinder returns the volume binder used by scheduler.
  451. VolumeBinder() *volumebinder.VolumeBinder
  452. }