Skip to content

Commit da682a2

Browse files
committed
Make the TTL of pgBackRest backups configurable
The default retention of one failed backup Job can leave a Job and its Pods in a failed state indefinitely. The TTL setting lets someone choose how long they want Jobs, Pods, and their logs to be available. This field is functional in Kubernetes 1.21 and OpenShift 4.8 where the TTLAfterFinished feature gate is enabled by default. Issue: [sc-14014] Issue: #3444
1 parent 80fee70 commit da682a2

File tree

6 files changed

+84
-23
lines changed

6 files changed

+84
-23
lines changed

config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,12 @@ spec:
13251325
type: string
13261326
type: object
13271327
type: array
1328+
ttlSecondsAfterFinished:
1329+
description: 'Limit the lifetime of a Job that has finished.
1330+
More info: https://kubernetes.io/docs/concepts/workloads/controllers/job'
1331+
format: int32
1332+
minimum: 60
1333+
type: integer
13281334
type: object
13291335
manual:
13301336
description: Defines details for manual pgBackRest backup

docs/content/references/crd.md

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

internal/controller/postgrescluster/pgbackrest.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,10 @@ func generateBackupJobSpecIntent(postgresCluster *v1beta1.PostgresCluster,
720720
},
721721
}
722722

723+
if jobs := postgresCluster.Spec.Backups.PGBackRest.Jobs; jobs != nil {
724+
jobSpec.TTLSecondsAfterFinished = jobs.TTLSecondsAfterFinished
725+
}
726+
723727
// set the priority class name, tolerations, and affinity, if they exist
724728
if postgresCluster.Spec.Backups.PGBackRest.Jobs != nil {
725729
if postgresCluster.Spec.Backups.PGBackRest.Jobs.PriorityClassName != nil {

internal/controller/postgrescluster/pgbackrest_test.go

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2560,9 +2560,8 @@ volumes:
25602560
})
25612561

25622562
t.Run("Resources", func(t *testing.T) {
2563-
cluster := &v1beta1.PostgresCluster{
2564-
Spec: v1beta1.PostgresClusterSpec{},
2565-
}
2563+
cluster := &v1beta1.PostgresCluster{}
2564+
25662565
t.Run("Resources not defined in jobs", func(t *testing.T) {
25672566
cluster.Spec.Backups = v1beta1.Backups{
25682567
PGBackRest: v1beta1.PGBackRestArchive{},
@@ -2635,16 +2634,9 @@ volumes:
26352634
})
26362635

26372636
t.Run("PriorityClassName", func(t *testing.T) {
2638-
cluster := &v1beta1.PostgresCluster{
2639-
Spec: v1beta1.PostgresClusterSpec{
2640-
Backups: v1beta1.Backups{
2641-
PGBackRest: v1beta1.PGBackRestArchive{
2642-
Jobs: &v1beta1.BackupJobs{
2643-
PriorityClassName: initialize.String("some-priority-class"),
2644-
},
2645-
},
2646-
},
2647-
},
2637+
cluster := &v1beta1.PostgresCluster{}
2638+
cluster.Spec.Backups.PGBackRest.Jobs = &v1beta1.BackupJobs{
2639+
PriorityClassName: initialize.String("some-priority-class"),
26482640
}
26492641
job, err := generateBackupJobSpecIntent(
26502642
cluster, v1beta1.PGBackRestRepo{},
@@ -2661,16 +2653,9 @@ volumes:
26612653
Operator: "Exist",
26622654
}}
26632655

2664-
cluster := &v1beta1.PostgresCluster{
2665-
Spec: v1beta1.PostgresClusterSpec{
2666-
Backups: v1beta1.Backups{
2667-
PGBackRest: v1beta1.PGBackRestArchive{
2668-
Jobs: &v1beta1.BackupJobs{
2669-
Tolerations: tolerations,
2670-
},
2671-
},
2672-
},
2673-
},
2656+
cluster := &v1beta1.PostgresCluster{}
2657+
cluster.Spec.Backups.PGBackRest.Jobs = &v1beta1.BackupJobs{
2658+
Tolerations: tolerations,
26742659
}
26752660
job, err := generateBackupJobSpecIntent(
26762661
cluster, v1beta1.PGBackRestRepo{},
@@ -2680,6 +2665,56 @@ volumes:
26802665
assert.NilError(t, err)
26812666
assert.DeepEqual(t, job.Template.Spec.Tolerations, tolerations)
26822667
})
2668+
2669+
t.Run("TTLSecondsAfterFinished", func(t *testing.T) {
2670+
cluster := &v1beta1.PostgresCluster{}
2671+
2672+
t.Run("Undefined", func(t *testing.T) {
2673+
cluster.Spec.Backups.PGBackRest.Jobs = nil
2674+
2675+
spec, err := generateBackupJobSpecIntent(
2676+
cluster, v1beta1.PGBackRestRepo{}, "", nil, nil,
2677+
)
2678+
assert.NilError(t, err)
2679+
assert.Assert(t, spec.TTLSecondsAfterFinished == nil)
2680+
2681+
cluster.Spec.Backups.PGBackRest.Jobs = &v1beta1.BackupJobs{}
2682+
2683+
spec, err = generateBackupJobSpecIntent(
2684+
cluster, v1beta1.PGBackRestRepo{}, "", nil, nil,
2685+
)
2686+
assert.NilError(t, err)
2687+
assert.Assert(t, spec.TTLSecondsAfterFinished == nil)
2688+
})
2689+
2690+
t.Run("Zero", func(t *testing.T) {
2691+
cluster.Spec.Backups.PGBackRest.Jobs = &v1beta1.BackupJobs{
2692+
TTLSecondsAfterFinished: initialize.Int32(0),
2693+
}
2694+
2695+
spec, err := generateBackupJobSpecIntent(
2696+
cluster, v1beta1.PGBackRestRepo{}, "", nil, nil,
2697+
)
2698+
assert.NilError(t, err)
2699+
if assert.Check(t, spec.TTLSecondsAfterFinished != nil) {
2700+
assert.Equal(t, *spec.TTLSecondsAfterFinished, int32(0))
2701+
}
2702+
})
2703+
2704+
t.Run("Positive", func(t *testing.T) {
2705+
cluster.Spec.Backups.PGBackRest.Jobs = &v1beta1.BackupJobs{
2706+
TTLSecondsAfterFinished: initialize.Int32(100),
2707+
}
2708+
2709+
spec, err := generateBackupJobSpecIntent(
2710+
cluster, v1beta1.PGBackRestRepo{}, "", nil, nil,
2711+
)
2712+
assert.NilError(t, err)
2713+
if assert.Check(t, spec.TTLSecondsAfterFinished != nil) {
2714+
assert.Equal(t, *spec.TTLSecondsAfterFinished, int32(100))
2715+
}
2716+
})
2717+
})
26832718
}
26842719

26852720
func TestGenerateRepoHostIntent(t *testing.T) {

pkg/apis/postgres-operator.crunchydata.com/v1beta1/pgbackrest_types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,12 @@ type BackupJobs struct {
180180
// More info: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration
181181
// +optional
182182
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
183+
184+
// Limit the lifetime of a Job that has finished.
185+
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/job
186+
// +optional
187+
// +kubebuilder:validation:Minimum=60
188+
TTLSecondsAfterFinished *int32 `json:"ttlSecondsAfterFinished,omitempty"`
183189
}
184190

185191
// PGBackRestManualBackup contains information that is used for creating a

pkg/apis/postgres-operator.crunchydata.com/v1beta1/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.

0 commit comments

Comments
 (0)