in pkg/capacityscheduling/capacity_scheduling.go [401:474]
func (p *preemptor) PodEligibleToPreemptOthers(pod *v1.Pod, nominatedNodeStatus *framework.Status) (bool, string) {
if pod.Spec.PreemptionPolicy != nil && *pod.Spec.PreemptionPolicy == v1.PreemptNever {
klog.V(5).InfoS("Pod is not eligible for preemption because of its preemptionPolicy", "pod", klog.KObj(pod), "preemptionPolicy", v1.PreemptNever)
return false, "not eligible due to preemptionPolicy=Never."
}
preFilterState, err := getPreFilterState(p.state)
if err != nil {
klog.V(5).InfoS("Failed to read preFilterState from cycleState, err: %s", err, "preFilterStateKey", preFilterStateKey)
return false, "not eligible due to failed to read from cycleState"
}
nomNodeName := pod.Status.NominatedNodeName
nodeLister := p.fh.SnapshotSharedLister().NodeInfos()
if len(nomNodeName) > 0 {
// If the pod's nominated node is considered as UnschedulableAndUnresolvable by the filters,
// then the pod should be considered for preempting again.
if nominatedNodeStatus.Code() == framework.UnschedulableAndUnresolvable {
return true, ""
}
elasticQuotaSnapshotState, err := getElasticQuotaSnapshotState(p.state)
if err != nil {
klog.ErrorS(err, "Failed to read elasticQuotaSnapshot from cycleState", "elasticQuotaSnapshotKey", ElasticQuotaSnapshotKey)
return true, ""
}
nodeInfo, _ := nodeLister.Get(nomNodeName)
if nodeInfo == nil {
return true, ""
}
podPriority := corev1helpers.PodPriority(pod)
preemptorEQInfo, preemptorWithEQ := elasticQuotaSnapshotState.elasticQuotaInfos[pod.Namespace]
if preemptorWithEQ {
moreThanMinWithPreemptor := preemptorEQInfo.usedOverMinWith(&preFilterState.nominatedPodsReqInEQWithPodReq)
for _, p := range nodeInfo.Pods {
// Checking terminating pods
if p.Pod.DeletionTimestamp != nil {
eqInfo, withEQ := elasticQuotaSnapshotState.elasticQuotaInfos[p.Pod.Namespace]
if !withEQ {
continue
}
if p.Pod.Namespace == pod.Namespace && corev1helpers.PodPriority(p.Pod) < podPriority {
// There is a terminating pod on the nominated node.
// If the terminating pod is in the same namespace with preemptor
// and it is less important than preemptor,
// return false to avoid preempting more pods.
return false, "not eligible due to a terminating pod on the nominated node."
} else if p.Pod.Namespace != pod.Namespace && !moreThanMinWithPreemptor && eqInfo.usedOverMin() {
// There is a terminating pod on the nominated node.
// The terminating pod isn't in the same namespace with preemptor.
// If moreThanMinWithPreemptor is false, it indicates that preemptor can preempt the pods in other EQs whose used is over min.
// And if the used of terminating pod's quota is over min, so the room released by terminating pod on the nominated node can be used by the preemptor.
// return false to avoid preempting more pods.
return false, "not eligible due to a terminating pod on the nominated node."
}
}
}
} else {
for _, p := range nodeInfo.Pods {
_, withEQ := elasticQuotaSnapshotState.elasticQuotaInfos[p.Pod.Namespace]
if withEQ {
continue
}
if p.Pod.DeletionTimestamp != nil && corev1helpers.PodPriority(p.Pod) < podPriority {
// There is a terminating pod on the nominated node.
return false, "not eligible due to a terminating pod on the nominated node."
}
}
}
}
return true, ""
}