in pkg/capacityscheduling/capacity_scheduling.go [304:348]
func (c *CapacityScheduling) preempt(ctx context.Context, state *framework.CycleState, pod *v1.Pod, m framework.NodeToStatusMap) (string, *framework.Status) {
client := c.fh.ClientSet()
nodeLister := c.fh.SnapshotSharedLister().NodeInfos()
// Fetch the latest version of <pod>.
// It's safe to directly fetch pod here. Because the informer cache has already been
// initialized when creating the Scheduler obj, i.e., factory.go#MakeDefaultErrorFunc().
// However, tests may need to manually initialize the shared pod informer.
pod, err := c.podLister.Pods(pod.Namespace).Get(pod.Name)
if err != nil {
klog.Errorf("Error getting the updated preemptor pod object: %v", err)
return "", framework.AsStatus(err)
}
// 1) Ensure the preemptor is eligible to preempt other pods.
if !defaultpreemption.PodEligibleToPreemptOthers(pod, nodeLister, m[pod.Status.NominatedNodeName]) {
klog.V(5).Infof("Pod %v/%v is not eligible for more preemption.", pod.Namespace, pod.Name)
return "", nil
}
// 2) Find all preemption candidates.
candidates, status := c.FindCandidates(ctx, client, state, pod, m)
if !status.IsSuccess() {
return "", status
}
// 3) Interact with registered Extenders to filter out some candidates if needed.
candidates, status = defaultpreemption.CallExtenders(c.fh.Extenders(), pod, nodeLister, candidates)
if !status.IsSuccess() {
return "", status
}
// 4) Find the best candidate.
bestCandidate := defaultpreemption.SelectCandidate(candidates)
if bestCandidate == nil || len(bestCandidate.Name()) == 0 {
return "", nil
}
// 5) Perform preparation work before nominating the selected candidate.
if status := defaultpreemption.PrepareCandidate(bestCandidate, c.fh, client, pod, c.Name()); !status.IsSuccess() {
return "", status
}
return bestCandidate.Name(), nil
}