@@ -132,9 +132,16 @@ var _ = ginkgo.Describe("JobSet controller", func() {
132132 updates []* update
133133 }
134134
135- nodeSelectors := map [string ]map [string ]string {
136- "replicated-job-a" : {"node-selector-test-a" : "node-selector-test-a" },
137- "replicated-job-b" : {"node-selector-test-b" : "node-selector-test-b" },
135+ var podTemplateUpdates = & updatePodTemplateOpts {
136+ labels : map [string ]string {"label" : "value" },
137+ annotations : map [string ]string {"annotation" : "value" },
138+ nodeSelector : map [string ]string {"node-selector-test-a" : "node-selector-test-a" },
139+ tolerations : []corev1.Toleration {
140+ {
141+ Key : "key" ,
142+ Operator : corev1 .TolerationOpExists ,
143+ },
144+ },
138145 }
139146
140147 ginkgo .DescribeTable ("jobset is created and its jobs go through a series of updates" ,
@@ -514,7 +521,7 @@ var _ = ginkgo.Describe("JobSet controller", func() {
514521 },
515522 {
516523 jobSetUpdateFn : func (js * jobset.JobSet ) {
517- updateJobSetNodeSelectors (js , nodeSelectors )
524+ updatePodTemplates (js , podTemplateUpdates )
518525 },
519526 checkJobSetState : func (js * jobset.JobSet ) {
520527 ginkgo .By ("Check ReplicatedJobStatus for suspend" )
@@ -542,7 +549,7 @@ var _ = ginkgo.Describe("JobSet controller", func() {
542549 {
543550 checkJobSetState : func (js * jobset.JobSet ) {
544551 ginkgo .By ("checking jobs have expected node selectors" )
545- gomega .Eventually (matchJobsNodeSelectors , timeout , interval ).WithArguments (js , nodeSelectors ).Should (gomega .Equal (true ))
552+ gomega .Eventually (checkPodTemplateUpdates , timeout , interval ).WithArguments (js , podTemplateUpdates ).Should (gomega .Equal (true ))
546553 },
547554 jobUpdateFn : completeAllJobs ,
548555 checkJobSetCondition : testutil .JobSetCompleted ,
@@ -1464,15 +1471,35 @@ func suspendJobSet(js *jobset.JobSet, suspend bool) {
14641471 }, timeout , interval ).Should (gomega .Succeed ())
14651472}
14661473
1467- func updateJobSetNodeSelectors (js * jobset.JobSet , nodeSelectors map [string ]map [string ]string ) {
1474+ // updatePodTemplateOpts contains pod template values
1475+ // which can be mutated on a ReplicatedJob template
1476+ // while a JobSet is suspended.
1477+ type updatePodTemplateOpts struct {
1478+ labels map [string ]string
1479+ annotations map [string ]string
1480+ nodeSelector map [string ]string
1481+ tolerations []corev1.Toleration
1482+ }
1483+
1484+ func updatePodTemplates (js * jobset.JobSet , opts * updatePodTemplateOpts ) {
14681485 gomega .Eventually (func () error {
14691486 var jsGet jobset.JobSet
14701487 if err := k8sClient .Get (ctx , types.NamespacedName {Name : js .Name , Namespace : js .Namespace }, & jsGet ); err != nil {
14711488 return err
14721489 }
14731490 for index := range jsGet .Spec .ReplicatedJobs {
1474- jsGet .Spec .ReplicatedJobs [index ].
1475- Template .Spec .Template .Spec .NodeSelector = nodeSelectors [jsGet .Spec .ReplicatedJobs [index ].Name ]
1491+ podTemplate := & jsGet .Spec .ReplicatedJobs [index ].Template .Spec .Template
1492+ // Update labels.
1493+ podTemplate .Labels = opts .labels
1494+
1495+ // Update annotations.
1496+ podTemplate .Annotations = opts .annotations
1497+
1498+ // Update node selector.
1499+ podTemplate .Spec .NodeSelector = opts .nodeSelector
1500+
1501+ // Update tolerations.
1502+ podTemplate .Spec .Tolerations = opts .tolerations
14761503 }
14771504 return k8sClient .Update (ctx , & jsGet )
14781505 }, timeout , interval ).Should (gomega .Succeed ())
@@ -1496,29 +1523,48 @@ func matchJobsSuspendState(js *jobset.JobSet, suspend bool) (bool, error) {
14961523 return true , nil
14971524}
14981525
1499- func matchJobsNodeSelectors (js * jobset.JobSet , nodeSelectors map [ string ] map [ string ] string ) (bool , error ) {
1526+ func checkPodTemplateUpdates (js * jobset.JobSet , podTemplateUpdates * updatePodTemplateOpts ) (bool , error ) {
15001527 var jobList batchv1.JobList
15011528 if err := k8sClient .List (ctx , & jobList , client .InNamespace (js .Namespace )); err != nil {
15021529 return false , err
15031530 }
15041531 // Count number of updated jobs
15051532 jobsUpdated := 0
15061533 for _ , job := range jobList .Items {
1507- rjobName , ok := job .Labels [jobset .ReplicatedJobNameKey ]
1508- if ! ok {
1509- return false , fmt .Errorf (fmt .Sprintf ("%s job missing ReplicatedJobName label" , job .Name ))
1534+ // Check label was added.
1535+ for label , value := range podTemplateUpdates .labels {
1536+ if job .Spec .Template .Labels [label ] != value {
1537+ return false , fmt .Errorf ("%s != %s" , job .Spec .Template .Labels [label ], value )
1538+ }
15101539 }
1511- if ! apiequality .Semantic .DeepEqual (job .Spec .Template .Spec .NodeSelector , nodeSelectors [rjobName ]) {
1512- return false , nil
1540+
1541+ // Check annotation was added.
1542+ for annotation , value := range podTemplateUpdates .annotations {
1543+ if job .Spec .Template .Annotations [annotation ] != value {
1544+ return false , fmt .Errorf ("%s != %s" , job .Spec .Template .Labels [annotation ], value )
1545+ }
15131546 }
1547+
1548+ // Check nodeSelector was updated.
1549+ for label , value := range podTemplateUpdates .nodeSelector {
1550+ if job .Spec .Template .Spec .NodeSelector [label ] != value {
1551+ return false , fmt .Errorf ("%s != %s" , job .Spec .Template .Spec .NodeSelector [label ], value )
1552+ }
1553+ }
1554+
1555+ // Check tolerations were updated.
1556+ for _ , toleration := range podTemplateUpdates .tolerations {
1557+ if ! collections .Contains (job .Spec .Template .Spec .Tolerations , toleration ) {
1558+ return false , fmt .Errorf ("missing toleration %v" , toleration )
1559+ }
1560+ }
1561+
15141562 jobsUpdated ++
15151563 }
15161564 // Calculate expected number of updated jobs
15171565 wantJobsUpdated := 0
15181566 for _ , rjob := range js .Spec .ReplicatedJobs {
1519- if _ , exists := nodeSelectors [rjob .Name ]; exists {
1520- wantJobsUpdated += int (rjob .Replicas )
1521- }
1567+ wantJobsUpdated += int (rjob .Replicas )
15221568 }
15231569 return wantJobsUpdated == jobsUpdated , nil
15241570}
0 commit comments