...
1
16
17 package job
18
19 import (
20 "fmt"
21
22 batch "k8s.io/api/batch/v1"
23 v1 "k8s.io/api/core/v1"
24 "k8s.io/apiserver/pkg/util/feature"
25 "k8s.io/klog/v2"
26 "k8s.io/kubernetes/pkg/features"
27 )
28
29 func matchSuccessPolicy(logger klog.Logger, successPolicy *batch.SuccessPolicy, completions int32, succeededIndexes orderedIntervals) (string, bool) {
30 if successPolicy == nil || len(succeededIndexes) == 0 {
31 return "", false
32 }
33
34 rulesMatchedMsg := "Matched rules at index"
35 for index, rule := range successPolicy.Rules {
36 if rule.SucceededIndexes != nil {
37 requiredIndexes := parseIndexesFromString(logger, *rule.SucceededIndexes, int(completions))
38
39 if len(requiredIndexes) == 0 {
40 continue
41 }
42 if matchSucceededIndexesRule(requiredIndexes, succeededIndexes, rule.SucceededCount) {
43 return fmt.Sprintf("%s %d", rulesMatchedMsg, index), true
44 }
45 } else if rule.SucceededCount != nil && succeededIndexes.total() >= int(*rule.SucceededCount) {
46 return fmt.Sprintf("%s %d", rulesMatchedMsg, index), true
47 }
48 }
49 return "", false
50 }
51
52 func hasSuccessCriteriaMetCondition(job *batch.Job) *batch.JobCondition {
53 if feature.DefaultFeatureGate.Enabled(features.JobSuccessPolicy) {
54 successCriteriaMet := findConditionByType(job.Status.Conditions, batch.JobSuccessCriteriaMet)
55 if successCriteriaMet != nil && successCriteriaMet.Status == v1.ConditionTrue {
56 return successCriteriaMet
57 }
58 }
59 return nil
60 }
61
62 func isSuccessCriteriaMetCondition(cond *batch.JobCondition) bool {
63 return feature.DefaultFeatureGate.Enabled(features.JobSuccessPolicy) &&
64 cond != nil && cond.Type == batch.JobSuccessCriteriaMet && cond.Status == v1.ConditionTrue
65 }
66
67 func matchSucceededIndexesRule(ruleIndexes, succeededIndexes orderedIntervals, succeededCount *int32) bool {
68 var contains, succeededPointer, rulePointer int
69 for rulePointer < len(ruleIndexes) && succeededPointer < len(succeededIndexes) {
70 if overlap := min(ruleIndexes[rulePointer].Last, succeededIndexes[succeededPointer].Last) -
71 max(ruleIndexes[rulePointer].First, succeededIndexes[succeededPointer].First) + 1; overlap > 0 {
72 contains += overlap
73 }
74 if succeededIndexes[succeededPointer].Last < ruleIndexes[rulePointer].Last {
75
76 succeededPointer++
77 } else if succeededIndexes[succeededPointer].Last > ruleIndexes[rulePointer].Last {
78
79 rulePointer++
80 } else {
81
82 succeededPointer++
83 rulePointer++
84 }
85 }
86 return contains == ruleIndexes.total() || (succeededCount != nil && contains >= int(*succeededCount))
87 }
88
View as plain text