Skip to content

Commit 225d672

Browse files
author
Rajadeepan D Ramesh
committed
Support multiple events in the lifecycle policy
1 parent 7cdd739 commit 225d672

4 files changed

Lines changed: 85 additions & 20 deletions

File tree

pkg/admission/admission_controller.go

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -115,32 +115,43 @@ func validatePolicies(policies []v1alpha1.LifecyclePolicy, fldPath *field.Path)
115115
exitCodes := map[int32]struct{}{}
116116

117117
for _, policy := range policies {
118-
if policy.Event != "" && policy.ExitCode != nil {
118+
if (policy.Event != "" || len(policy.EventList) != 0) && policy.ExitCode != nil {
119119
err = multierror.Append(err, fmt.Errorf("must not specify event and exitCode simultaneously"))
120120
break
121121
}
122122

123-
if policy.Event == "" && policy.ExitCode == nil {
123+
if policy.Event == "" && len(policy.EventList) == 0 && policy.ExitCode == nil {
124124
err = multierror.Append(err, fmt.Errorf("either event and exitCode should be specified"))
125125
break
126126
}
127127

128-
if policy.Event != "" {
129-
if allow, ok := policyEventMap[policy.Event]; !ok || !allow {
130-
err = multierror.Append(err, field.Invalid(fldPath, policy.Event, fmt.Sprintf("invalid policy event")))
131-
break
128+
if len(policy.Event) != 0 || len(policy.EventList) != 0 {
129+
bFlag := false
130+
policyEventsList := getEventlist(policy)
131+
for _, event := range policyEventsList {
132+
if allow, ok := policyEventMap[event]; !ok || !allow {
133+
err = multierror.Append(err, field.Invalid(fldPath, event, fmt.Sprintf("invalid policy event")))
134+
bFlag = true
135+
break
136+
}
137+
138+
if allow, ok := policyActionMap[policy.Action]; !ok || !allow {
139+
err = multierror.Append(err, field.Invalid(fldPath, policy.Action, fmt.Sprintf("invalid policy action")))
140+
bFlag = true
141+
break
142+
}
143+
if _, found := policyEvents[event]; found {
144+
err = multierror.Append(err, fmt.Errorf("duplicate event %v", event))
145+
bFlag = true
146+
break
147+
} else {
148+
policyEvents[event] = struct{}{}
149+
}
132150
}
133-
134-
if allow, ok := policyActionMap[policy.Action]; !ok || !allow {
135-
err = multierror.Append(err, field.Invalid(fldPath, policy.Action, fmt.Sprintf("invalid policy action")))
151+
if bFlag == true {
136152
break
137153
}
138-
if _, found := policyEvents[policy.Event]; found {
139-
err = multierror.Append(err, fmt.Errorf("duplicate event %v", policy.Event))
140-
break
141-
} else {
142-
policyEvents[policy.Event] = struct{}{}
143-
}
154+
144155
} else {
145156
if *policy.ExitCode == 0 {
146157
err = multierror.Append(err, fmt.Errorf("0 is not a valid error code"))
@@ -162,6 +173,27 @@ func validatePolicies(policies []v1alpha1.LifecyclePolicy, fldPath *field.Path)
162173
return err
163174
}
164175

176+
func getEventlist(policy v1alpha1.LifecyclePolicy) []v1alpha1.Event {
177+
policyEventsList := policy.EventList
178+
if len(policy.Event) > 0 {
179+
policyEventsList = append(policyEventsList, policy.Event)
180+
}
181+
uniquePolicyEventlist := removeDuplicates(policyEventsList)
182+
return uniquePolicyEventlist
183+
}
184+
185+
func removeDuplicates(EventList []v1alpha1.Event) []v1alpha1.Event {
186+
keys := make(map[v1alpha1.Event]bool)
187+
list := []v1alpha1.Event{}
188+
for _, val := range EventList {
189+
if _, value := keys[val]; !value {
190+
keys[val] = true
191+
list = append(list, val)
192+
}
193+
}
194+
return list
195+
}
196+
165197
func getValidEvents() []v1alpha1.Event {
166198
var events []v1alpha1.Event
167199
for e, allow := range policyEventMap {

pkg/apis/batch/v1alpha1/job.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ type LifecyclePolicy struct {
180180
// +optional
181181
Event Event `json:"event,omitempty" protobuf:"bytes,2,opt,name=event"`
182182

183+
// The EventList recorded by scheduler; the controller takes actions
184+
// according to this EventList.
185+
// +optional
186+
EventList []Event `json:"eventlist,omitempty" protobuf:"bytes,3,opt,name=eventlist"`
187+
183188
// The exit code of the pod container, controller will take action
184189
// according to this code.
185190
// Note: only one of `Event` or `ExitCode` can be specified.
@@ -189,7 +194,7 @@ type LifecyclePolicy struct {
189194
// Timeout is the grace period for controller to take actions.
190195
// Default to nil (take action immediately).
191196
// +optional
192-
Timeout *metav1.Duration `json:"timeout,omitempty" protobuf:"bytes,3,opt,name=timeout"`
197+
Timeout *metav1.Duration `json:"timeout,omitempty" protobuf:"bytes,4,opt,name=timeout"`
193198
}
194199

195200
// TaskSpec specifies the task specification of Job

pkg/apis/batch/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/controllers/job/job_controller_util.go

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
v1 "k8s.io/api/core/v1"
2626
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2727

28+
"volcano.sh/volcano/pkg/apis/batch/v1alpha1"
2829
vkv1 "volcano.sh/volcano/pkg/apis/batch/v1alpha1"
2930
"volcano.sh/volcano/pkg/apis/helpers"
3031
"volcano.sh/volcano/pkg/controllers/apis"
@@ -143,8 +144,10 @@ func applyPolicies(job *vkv1.Job, req *apis.Request) vkv1.Action {
143144
for _, task := range job.Spec.Tasks {
144145
if task.Name == req.TaskName {
145146
for _, policy := range task.Policies {
146-
if len(policy.Event) > 0 && len(req.Event) > 0 {
147-
if policy.Event == req.Event || policy.Event == vkv1.AnyEvent {
147+
policyEvents := getEventlist(policy)
148+
149+
if len(policyEvents) > 0 && len(req.Event) > 0 {
150+
if checkEventExist(policyEvents, req.Event) || checkEventExist(policyEvents, vkv1.AnyEvent) {
148151
return policy.Action
149152
}
150153
}
@@ -161,8 +164,10 @@ func applyPolicies(job *vkv1.Job, req *apis.Request) vkv1.Action {
161164

162165
// Parse Job level policies
163166
for _, policy := range job.Spec.Policies {
164-
if len(policy.Event) > 0 && len(req.Event) > 0 {
165-
if policy.Event == req.Event || policy.Event == vkv1.AnyEvent {
167+
policyEvents := getEventlist(policy)
168+
169+
if len(policyEvents) > 0 && len(req.Event) > 0 {
170+
if checkEventExist(policyEvents, req.Event) || checkEventExist(policyEvents, vkv1.AnyEvent) {
166171
return policy.Action
167172
}
168173
}
@@ -176,6 +181,24 @@ func applyPolicies(job *vkv1.Job, req *apis.Request) vkv1.Action {
176181
return vkv1.SyncJobAction
177182
}
178183

184+
func getEventlist(policy v1alpha1.LifecyclePolicy) []v1alpha1.Event {
185+
policyEventsList := policy.EventList
186+
if len(policy.Event) > 0 {
187+
policyEventsList = append(policyEventsList, policy.Event)
188+
}
189+
return policyEventsList
190+
}
191+
192+
func checkEventExist(policyEvents []v1alpha1.Event, reqEvent v1alpha1.Event) bool {
193+
for _, event := range policyEvents {
194+
if event == reqEvent {
195+
return true
196+
}
197+
}
198+
return false
199+
200+
}
201+
179202
func addResourceList(list, new v1.ResourceList) {
180203
for name, quantity := range new {
181204
if value, ok := list[name]; !ok {

0 commit comments

Comments
 (0)