@@ -108,16 +108,16 @@ func (r *CronJobReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
108
108
log := r .Log .WithValues ("cronjob" , req .NamespacedName )
109
109
110
110
/*
111
- ### 1: Load the CronJob by name
111
+ ### 1: Load the CronJob by name
112
112
113
- We'll fetch the CronJob using our client. All client methods take a
114
- context (to allow for cancellation) as their first argument, and the object
115
- in question as their last. Get is a bit special, in that it takes a
116
- [`NamespacedName`](https://godoc.org/sigs.k8s.io/controller-runtime/pkg/client#ObjectKey)
117
- as the middle argument (most don't have a middle argument, as we'll see
118
- below).
113
+ We'll fetch the CronJob using our client. All client methods take a
114
+ context (to allow for cancellation) as their first argument, and the object
115
+ in question as their last. Get is a bit special, in that it takes a
116
+ [`NamespacedName`](https://godoc.org/sigs.k8s.io/controller-runtime/pkg/client#ObjectKey)
117
+ as the middle argument (most don't have a middle argument, as we'll see
118
+ below).
119
119
120
- Many client methods also take variadic options at the end.
120
+ Many client methods also take variadic options at the end.
121
121
*/
122
122
var cronJob batch.CronJob
123
123
if err := r .Get (ctx , req .NamespacedName , & cronJob ); err != nil {
@@ -129,11 +129,11 @@ func (r *CronJobReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
129
129
}
130
130
131
131
/*
132
- ### 2: List all active jobs, and update the status
132
+ ### 2: List all active jobs, and update the status
133
133
134
- To fully update our status, we'll need to list all child jobs in this namespace that belong to this CronJob.
135
- Similarly to Get, we can use the List method to list the child jobs. Notice that we use variadic options to
136
- set the namespace and field match (which is actually an index lookup that we set up below).
134
+ To fully update our status, we'll need to list all child jobs in this namespace that belong to this CronJob.
135
+ Similarly to Get, we can use the List method to list the child jobs. Notice that we use variadic options to
136
+ set the namespace and field match (which is actually an index lookup that we set up below).
137
137
*/
138
138
var childJobs kbatch.JobList
139
139
if err := r .List (ctx , & childJobs , client .InNamespace (req .Namespace ), client .MatchingField (jobOwnerKey , req .Name )); err != nil {
@@ -142,15 +142,15 @@ func (r *CronJobReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
142
142
}
143
143
144
144
/*
145
- Once we have all the jobs we own, we'll split them into active, successful,
146
- and failed jobs, keeping track of the most recent run so that we can record it
147
- in status. Remember, status should be able to be reconstituted from the state
148
- of the world, so it's generally not a good idea to read from the status of the
149
- root object. Instead, you should reconstruct it every run. That's what we'll
150
- do here.
151
-
152
- We can check if a job is "finished" and whether it succeeded or failed using status
153
- conditions. We'll put that logic in a helper to make our code cleaner.
145
+ Once we have all the jobs we own, we'll split them into active, successful,
146
+ and failed jobs, keeping track of the most recent run so that we can record it
147
+ in status. Remember, status should be able to be reconstituted from the state
148
+ of the world, so it's generally not a good idea to read from the status of the
149
+ root object. Instead, you should reconstruct it every run. That's what we'll
150
+ do here.
151
+
152
+ We can check if a job is "finished" and whether it succeeded or failed using status
153
+ conditions. We'll put that logic in a helper to make our code cleaner.
154
154
*/
155
155
156
156
// find the active list of jobs
@@ -160,9 +160,9 @@ func (r *CronJobReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
160
160
var mostRecentTime * time.Time // find the last run so we can update the status
161
161
162
162
/*
163
- We consider a job "finished" if it has a "succeeded" or "failed" condition marked as true.
164
- Status conditions allow us to add extensible status information to our objects that other
165
- humans and controllers can examine to check things like completion and health.
163
+ We consider a job "finished" if it has a "succeeded" or "failed" condition marked as true.
164
+ Status conditions allow us to add extensible status information to our objects that other
165
+ humans and controllers can examine to check things like completion and health.
166
166
*/
167
167
isJobFinished := func (job * kbatch.Job ) (bool , kbatch.JobConditionType ) {
168
168
for _ , c := range job .Status .Conditions {
@@ -176,8 +176,8 @@ func (r *CronJobReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
176
176
// +kubebuilder:docs-gen:collapse=isJobFinished
177
177
178
178
/*
179
- We'll use a helper to extract the scheduled time from the annotation that
180
- we added during job creation.
179
+ We'll use a helper to extract the scheduled time from the annotation that
180
+ we added during job creation.
181
181
*/
182
182
getScheduledTimeForJob := func (job * kbatch.Job ) (* time.Time , error ) {
183
183
timeRaw := job .Annotations [scheduledTimeAnnotation ]
@@ -236,35 +236,35 @@ func (r *CronJobReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
236
236
}
237
237
238
238
/*
239
- Here, we'll log how many jobs we observed at a slightly higher logging level,
240
- for debugging. Notice how instead of using a format string, we use a fixed message,
241
- and attach key-value pairs with the extra information. This makes it easier to
242
- filter and query log lines.
239
+ Here, we'll log how many jobs we observed at a slightly higher logging level,
240
+ for debugging. Notice how instead of using a format string, we use a fixed message,
241
+ and attach key-value pairs with the extra information. This makes it easier to
242
+ filter and query log lines.
243
243
*/
244
244
log .V (1 ).Info ("job count" , "active jobs" , len (activeJobs ), "successful jobs" , len (successfulJobs ), "failed jobs" , len (failedJobs ))
245
245
246
246
/*
247
- Using the date we've gathered, we'll update the status of our CRD.
248
- Just like before, we use our client. To specifically update the status
249
- subresource, we'll use the `Status` part of the client, with the `Update`
250
- method.
247
+ Using the date we've gathered, we'll update the status of our CRD.
248
+ Just like before, we use our client. To specifically update the status
249
+ subresource, we'll use the `Status` part of the client, with the `Update`
250
+ method.
251
251
252
- The status subresource ignores changes to spec, so it's less likely to conflict
253
- with any other updates, and can have separate permissions.
252
+ The status subresource ignores changes to spec, so it's less likely to conflict
253
+ with any other updates, and can have separate permissions.
254
254
*/
255
255
if err := r .Status ().Update (ctx , & cronJob ); err != nil {
256
256
log .Error (err , "unable to update CronJob status" )
257
257
return ctrl.Result {}, err
258
258
}
259
259
260
260
/*
261
- Once we've updated our status, we can move on to ensuring that the status of
262
- the world matches what we want in our spec.
261
+ Once we've updated our status, we can move on to ensuring that the status of
262
+ the world matches what we want in our spec.
263
263
264
- ### 3: Clean up old jobs according to the history limit
264
+ ### 3: Clean up old jobs according to the history limit
265
265
266
- First, we'll try to clean up old jobs, so that we don't leave too many lying
267
- around.
266
+ First, we'll try to clean up old jobs, so that we don't leave too many lying
267
+ around.
268
268
*/
269
269
270
270
// NB: deleting these is "best effort" -- if we fail on a particular one,
@@ -316,22 +316,22 @@ func (r *CronJobReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
316
316
}
317
317
318
318
/*
319
- ### 5: Get the next scheduled run
319
+ ### 5: Get the next scheduled run
320
320
321
- If we're not paused, we'll need to calculate the next scheduled run, and whether
322
- or not we've got a run that we haven't processed yet.
321
+ If we're not paused, we'll need to calculate the next scheduled run, and whether
322
+ or not we've got a run that we haven't processed yet.
323
323
*/
324
324
325
325
/*
326
- We'll calculate the next scheduled time using our helpful cron library.
327
- We'll start calculating appropriate times from our last run, or the creation
328
- of the CronJob if we can't find a last run.
326
+ We'll calculate the next scheduled time using our helpful cron library.
327
+ We'll start calculating appropriate times from our last run, or the creation
328
+ of the CronJob if we can't find a last run.
329
329
330
- If there are too many missed runs and we don't have any deadlines set, we'll
331
- bail so that we don't cause issues on controller restarts or wedges.
330
+ If there are too many missed runs and we don't have any deadlines set, we'll
331
+ bail so that we don't cause issues on controller restarts or wedges.
332
332
333
- Otherwise, we'll just return the missed runs (of which we'll just use the latest),
334
- and the next run, so that we can know when it's time to reconcile again.
333
+ Otherwise, we'll just return the missed runs (of which we'll just use the latest),
334
+ and the next run, so that we can know when it's time to reconcile again.
335
335
*/
336
336
getNextSchedule := func (cronJob * batch.CronJob , now time.Time ) (lastMissed * time.Time , next time.Time , err error ) {
337
337
sched , err := cron .ParseStandard (cronJob .Spec .Schedule )
@@ -398,16 +398,16 @@ func (r *CronJobReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
398
398
}
399
399
400
400
/*
401
- We'll prep our eventual request to requeue until the next job, and then figure
402
- out if we actually need to run.
401
+ We'll prep our eventual request to requeue until the next job, and then figure
402
+ out if we actually need to run.
403
403
*/
404
404
scheduledResult := ctrl.Result {RequeueAfter : nextRun .Sub (r .Now ())} // save this so we can re-use it elsewhere
405
405
log = log .WithValues ("now" , r .Now (), "next run" , nextRun )
406
406
407
407
/*
408
- ### 6: Run a new job if it's on schedule, not past the deadline, and not blocked by our concurrency policy
408
+ ### 6: Run a new job if it's on schedule, not past the deadline, and not blocked by our concurrency policy
409
409
410
- If we've missed a run, and we're still within the deadline to start it, we'll need to run a job.
410
+ If we've missed a run, and we're still within the deadline to start it, we'll need to run a job.
411
411
*/
412
412
if missedRun == nil {
413
413
log .V (1 ).Info ("no upcoming scheduled times, sleeping until next" )
@@ -427,9 +427,9 @@ func (r *CronJobReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
427
427
}
428
428
429
429
/*
430
- If we actually have to run a job, we'll need to either wait till existing ones finish,
431
- replace the existing ones, or just add new ones. If our information is out of date due
432
- to cache delay, we'll get a requeue when we get up-to-date information.
430
+ If we actually have to run a job, we'll need to either wait till existing ones finish,
431
+ replace the existing ones, or just add new ones. If our information is out of date due
432
+ to cache delay, we'll get a requeue when we get up-to-date information.
433
433
*/
434
434
// figure out how to run this job -- concurrency policy might forbid us from running
435
435
// multiple at the same time...
@@ -450,19 +450,19 @@ func (r *CronJobReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
450
450
}
451
451
452
452
/*
453
- Once we've figured out what to do with existing jobs, we'll actually create our desired job
453
+ Once we've figured out what to do with existing jobs, we'll actually create our desired job
454
454
*/
455
455
456
456
/*
457
- We need to construct a job based on our CronJob's template. We'll copy over the spec
458
- from the template and copy some basic object meta.
457
+ We need to construct a job based on our CronJob's template. We'll copy over the spec
458
+ from the template and copy some basic object meta.
459
459
460
- Then, we'll set the "scheduled time" annotation so that we can reconstitute our
461
- `LastScheduleTime` field each reconcile.
460
+ Then, we'll set the "scheduled time" annotation so that we can reconstitute our
461
+ `LastScheduleTime` field each reconcile.
462
462
463
- Finally, we'll need to set an owner reference. This allows the Kubernetes garbage collector
464
- to clean up jobs when we delete the CronJob, and allows controller-runtime to figure out
465
- which cronjob needs to be reconciled when a given job changes (is added, deleted, completes, etc).
463
+ Finally, we'll need to set an owner reference. This allows the Kubernetes garbage collector
464
+ to clean up jobs when we delete the CronJob, and allows controller-runtime to figure out
465
+ which cronjob needs to be reconciled when a given job changes (is added, deleted, completes, etc).
466
466
*/
467
467
constructJobForCronJob := func (cronJob * batch.CronJob , scheduledTime time.Time ) (* kbatch.Job , error ) {
468
468
// We want job names for a given nominal start time to have a deterministic name to avoid the same job being created twice
@@ -509,12 +509,12 @@ func (r *CronJobReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
509
509
log .V (1 ).Info ("created Job for CronJob run" , "job" , job )
510
510
511
511
/*
512
- ### 7: Requeue when we either see a running job or it's time for the next scheduled run
512
+ ### 7: Requeue when we either see a running job or it's time for the next scheduled run
513
513
514
- Finally, we'll return the result that we prepped above, that says we want to requeue
515
- when our next run would need to occur. This is taken as a maximum deadline -- if something
516
- else changes in between, like our job starts or finishes, we get modified, etc, we might
517
- reconcile again sooner.
514
+ Finally, we'll return the result that we prepped above, that says we want to requeue
515
+ when our next run would need to occur. This is taken as a maximum deadline -- if something
516
+ else changes in between, like our job starts or finishes, we get modified, etc, we might
517
+ reconcile again sooner.
518
518
*/
519
519
// we'll requeue once we see the running job, and update our status
520
520
return scheduledResult , nil
0 commit comments