Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c91dd31

Browse files
Add additional volumes to pgbackrest pods.
Change the API to allow users to specify preexisting PVCs to attach to specified containers in the various pgbackrest related pods: backup jobs, repo hosts, and restore jobs. The spec allos users to specify whether to add the volume to: * all containers (by omitting the containers list) * no containers (by specifying an empty containers list) * a list of named containers If any of the named containers isnt present, we continue to reconcile, but issue a warning event with the names of the missing containers. Issues: [PGO-2564]
1 parent 8d323cc commit c91dd31

File tree

8 files changed

+719
-7
lines changed

8 files changed

+719
-7
lines changed

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

Lines changed: 510 additions & 0 deletions
Large diffs are not rendered by default.

‎internal/controller/postgrescluster/pgbackrest.go‎

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,8 @@ func (r *Reconciler) generateRepoHostIntent(ctx context.Context, postgresCluster
608608
},
609609
}
610610

611-
if repoHost := postgresCluster.Spec.Backups.PGBackRest.RepoHost; repoHost != nil {
611+
repoHost := postgresCluster.Spec.Backups.PGBackRest.RepoHost
612+
if repoHost != nil {
612613
repo.Spec.Template.Spec.Affinity = repoHost.Affinity
613614
repo.Spec.Template.Spec.Tolerations = repoHost.Tolerations
614615
repo.Spec.Template.Spec.TopologySpreadConstraints = repoHost.TopologySpreadConstraints
@@ -718,6 +719,16 @@ func (r *Reconciler) generateRepoHostIntent(ctx context.Context, postgresCluster
718719

719720
AddTMPEmptyDir(&repo.Spec.Template)
720721

722+
// mount additional volumes to the repo host containers
723+
if repoHost != nil && repoHost.Volumes != nil && len(repoHost.Volumes.Additional) > 0 {
724+
missingContainers := addAdditionalVolumesToSpecifiedContainers(&repo.Spec.Template, repoHost.Volumes.Additional)
725+
726+
if len(missingContainers) > 0 {
727+
r.Recorder.Eventf(postgresCluster, corev1.EventTypeWarning, "SpecifiedContainerNotFound",
728+
"The following Repo Host Pod containers were specified for additional volumes but cannot be found: %s.", missingContainers)
729+
}
730+
}
731+
721732
// set ownership references
722733
if err := r.setControllerReference(postgresCluster, repo); err != nil {
723734
return nil, err
@@ -814,7 +825,8 @@ func (r *Reconciler) generateBackupJobSpecIntent(ctx context.Context, postgresCl
814825
container.Command = append(container.Command, cmdOpts...)
815826
}
816827

817-
if postgresCluster.Spec.Backups.PGBackRest.Jobs != nil {
828+
jobs := postgresCluster.Spec.Backups.PGBackRest.Jobs
829+
if jobs != nil {
818830
container.Resources = postgresCluster.Spec.Backups.PGBackRest.Jobs.Resources
819831
}
820832

@@ -848,12 +860,9 @@ func (r *Reconciler) generateBackupJobSpecIntent(ctx context.Context, postgresCl
848860
},
849861
}
850862

851-
if jobs := postgresCluster.Spec.Backups.PGBackRest.Jobs; jobs != nil {
863+
// set the job lifetime, priority class name, tolerations, and affinity, if they exist
864+
if jobs != nil {
852865
jobSpec.TTLSecondsAfterFinished = jobs.TTLSecondsAfterFinished
853-
}
854-
855-
// set the priority class name, tolerations, and affinity, if they exist
856-
if postgresCluster.Spec.Backups.PGBackRest.Jobs != nil {
857866
jobSpec.Template.Spec.Tolerations = postgresCluster.Spec.Backups.PGBackRest.Jobs.Tolerations
858867
jobSpec.Template.Spec.Affinity = postgresCluster.Spec.Backups.PGBackRest.Jobs.Affinity
859868
jobSpec.Template.Spec.PriorityClassName =
@@ -897,6 +906,16 @@ func (r *Reconciler) generateBackupJobSpecIntent(ctx context.Context, postgresCl
897906
}
898907
}
899908

909+
// mount additional volumes to the job containers
910+
if jobs != nil && jobs.Volumes != nil && len(jobs.Volumes.Additional) > 0 {
911+
missingContainers := addAdditionalVolumesToSpecifiedContainers(&jobSpec.Template, jobs.Volumes.Additional)
912+
913+
if len(missingContainers) > 0 {
914+
r.Recorder.Eventf(postgresCluster, corev1.EventTypeWarning, "SpecifiedContainerNotFound",
915+
"The following Backup Job Pod containers were specified for additional volumes but cannot be found: %s.", missingContainers)
916+
}
917+
}
918+
900919
return jobSpec
901920
}
902921

@@ -1388,6 +1407,15 @@ func (r *Reconciler) generateRestoreJobIntent(cluster *v1beta1.PostgresCluster,
13881407
// set the priority class name, if it exists
13891408
job.Spec.Template.Spec.PriorityClassName = initialize.FromPointer(dataSource.PriorityClassName)
13901409

1410+
if dataSource.Volumes != nil && len(dataSource.Volumes.Additional) > 0 {
1411+
missingContainers := addAdditionalVolumesToSpecifiedContainers(&job.Spec.Template, dataSource.Volumes.Additional)
1412+
1413+
if len(missingContainers) > 0 {
1414+
r.Recorder.Eventf(cluster, corev1.EventTypeWarning, "SpecifiedContainerNotFound",
1415+
"The following Restore Pod containers were specified for additional volumes but cannot be found: %s.", missingContainers)
1416+
}
1417+
}
1418+
13911419
job.SetGroupVersionKind(batchv1.SchemeGroupVersion.WithKind("Job"))
13921420
if err := errors.WithStack(r.setControllerReference(cluster, job)); err != nil {
13931421
return err
@@ -1821,6 +1849,7 @@ func (r *Reconciler) reconcileCloudBasedDataSource(ctx context.Context,
18211849
Affinity: dataSource.Affinity,
18221850
Tolerations: dataSource.Tolerations,
18231851
PriorityClassName: dataSource.PriorityClassName,
1852+
Volumes: dataSource.Volumes,
18241853
}
18251854

18261855
// reconcile the pgBackRest restore Job to populate the cluster's data directory

‎internal/controller/postgrescluster/pgbackrest_test.go‎

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3070,6 +3070,46 @@ volumes:
30703070
// No events created
30713071
assert.Equal(t, len(recorder.Events), 0)
30723072
})
3073+
3074+
t.Run("AdditionalVolumes", func(t *testing.T) {
3075+
recorder := events.NewRecorder(t, runtime.Scheme)
3076+
r.Recorder = recorder
3077+
3078+
cluster := cluster.DeepCopy()
3079+
cluster.Namespace = ns.Name
3080+
cluster.Spec.Backups.PGBackRest.Jobs = &v1beta1.BackupJobs{
3081+
Volumes: &v1beta1.PGBackRestVolumesSpec{
3082+
Additional: []v1beta1.AdditionalVolume{
3083+
{
3084+
ClaimName: "additional-pvc",
3085+
Name: "stuff",
3086+
},
3087+
},
3088+
},
3089+
}
3090+
3091+
spec := r.generateBackupJobSpecIntent(ctx,
3092+
cluster, v1beta1.PGBackRestRepo{},
3093+
"",
3094+
nil, nil,
3095+
)
3096+
3097+
for _, container := range spec.Template.Spec.Containers {
3098+
assert.Assert(t, cmp.MarshalContains(container.VolumeMounts,
3099+
`
3100+
- mountPath: /volumes/stuff
3101+
name: volumes-stuff`))
3102+
}
3103+
3104+
assert.Assert(t, cmp.MarshalContains(spec.Template.Spec.Volumes,
3105+
`
3106+
- name: volumes-stuff
3107+
persistentVolumeClaim:
3108+
claimName: additional-pvc`))
3109+
3110+
// No events created
3111+
assert.Equal(t, len(recorder.Events), 0)
3112+
})
30733113
}
30743114

30753115
func TestGenerateRepoHostIntent(t *testing.T) {
@@ -3123,6 +3163,43 @@ func TestGenerateRepoHostIntent(t *testing.T) {
31233163
assert.NilError(t, err)
31243164
assert.Equal(t, *sts.Spec.Replicas, int32(0))
31253165
})
3166+
3167+
t.Run("AdditionalVolumes", func(t *testing.T) {
3168+
cluster := &v1beta1.PostgresCluster{
3169+
Spec: v1beta1.PostgresClusterSpec{
3170+
Backups: v1beta1.Backups{
3171+
PGBackRest: v1beta1.PGBackRestArchive{
3172+
RepoHost: &v1beta1.PGBackRestRepoHost{
3173+
Volumes: &v1beta1.PGBackRestVolumesSpec{
3174+
Additional: []v1beta1.AdditionalVolume{
3175+
{
3176+
ClaimName: "additional-pvc",
3177+
Name: "stuff",
3178+
},
3179+
},
3180+
},
3181+
},
3182+
},
3183+
},
3184+
},
3185+
}
3186+
observed := &observedInstances{forCluster: []*Instance{{}}}
3187+
sts, err := r.generateRepoHostIntent(ctx, cluster, "", &RepoResources{}, observed, "")
3188+
assert.NilError(t, err)
3189+
3190+
for _, container := range sts.Spec.Template.Spec.Containers {
3191+
assert.Assert(t, cmp.MarshalContains(container.VolumeMounts,
3192+
`
3193+
- mountPath: /volumes/stuff
3194+
name: volumes-stuff`))
3195+
}
3196+
3197+
assert.Assert(t, cmp.MarshalContains(sts.Spec.Template.Spec.Volumes,
3198+
`
3199+
- name: volumes-stuff
3200+
persistentVolumeClaim:
3201+
claimName: additional-pvc`))
3202+
})
31263203
}
31273204

31283205
func TestGenerateRestoreJobIntent(t *testing.T) {
@@ -3174,6 +3251,14 @@ func TestGenerateRestoreJobIntent(t *testing.T) {
31743251
Operator: "Exist",
31753252
}},
31763253
PriorityClassName: initialize.String("some-priority-class"),
3254+
Volumes: &v1beta1.PGBackRestVolumesSpec{
3255+
Additional: []v1beta1.AdditionalVolume{
3256+
{
3257+
ClaimName: "additional-pvc",
3258+
Name: "stuff",
3259+
},
3260+
},
3261+
},
31773262
}
31783263
cluster := &v1beta1.PostgresCluster{
31793264
ObjectMeta: metav1.ObjectMeta{
@@ -3266,6 +3351,9 @@ func TestGenerateRestoreJobIntent(t *testing.T) {
32663351
assert.DeepEqual(t, job.Spec.Template.Spec.Containers[0].VolumeMounts,
32673352
[]corev1.VolumeMount{{
32683353
Name: "mount",
3354+
}, {
3355+
Name: "volumes-stuff",
3356+
MountPath: "/volumes/stuff",
32693357
}})
32703358
})
32713359
t.Run("Env", func(t *testing.T) {
@@ -3289,6 +3377,13 @@ func TestGenerateRestoreJobIntent(t *testing.T) {
32893377
assert.DeepEqual(t, job.Spec.Template.Spec.Volumes,
32903378
[]corev1.Volume{{
32913379
Name: "volume",
3380+
}, {
3381+
Name: "volumes-stuff",
3382+
VolumeSource: corev1.VolumeSource{
3383+
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
3384+
ClaimName: "additional-pvc",
3385+
},
3386+
},
32923387
}})
32933388
})
32943389
t.Run("Affinity", func(t *testing.T) {

‎pkg/apis/postgres-operator.crunchydata.com/v1/postgrescluster_types.go‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,10 @@ type PostgresClusterDataSource struct {
311311
// More info: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration
312312
// +optional
313313
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
314+
315+
// Volumes to add to Restore Job Pods
316+
// +optional
317+
Volumes *v1beta1.PGBackRestVolumesSpec `json:"volumes,omitempty"`
314318
}
315319

316320
// Default defines several key default values for a Postgres cluster.

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,21 @@ type BackupJobs struct {
175175
// +optional
176176
// +kubebuilder:validation:Minimum=60
177177
TTLSecondsAfterFinished *int32 `json:"ttlSecondsAfterFinished,omitempty"`
178+
179+
// Volumes to add to Backup Job Pods
180+
// +optional
181+
Volumes *PGBackRestVolumesSpec `json:"volumes,omitempty"`
182+
}
183+
184+
// PGBackRestVolumesSpec defines the configuration for pgBackRest additional volumes
185+
type PGBackRestVolumesSpec struct {
186+
// Additional pre-existing volumes to add to the pod.
187+
// ---
188+
// +optional
189+
// +listType=map
190+
// +listMapKey=name
191+
// +kubebuilder:validation:MaxItems=10
192+
Additional []AdditionalVolume `json:"additional,omitempty"`
178193
}
179194

180195
// PGBackRestManualBackup contains information that is used for creating a
@@ -230,6 +245,10 @@ type PGBackRestRepoHost struct {
230245
// Deprecated: Repository hosts use mTLS for encryption, authentication, and authorization.
231246
// +optional
232247
SSHSecret *corev1.SecretProjection `json:"sshSecret,omitempty"`
248+
249+
// Volumes to add to the Repo Host Pod
250+
// +optional
251+
Volumes *PGBackRestVolumesSpec `json:"volumes,omitempty"`
233252
}
234253

235254
// PGBackRestRestore defines an in-place restore for the PostgresCluster.
@@ -459,4 +478,8 @@ type PGBackRestDataSource struct {
459478
// More info: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration
460479
// +optional
461480
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
481+
482+
// Volumes to add to Restore Job Pods
483+
// +optional
484+
Volumes *PGBackRestVolumesSpec `json:"volumes,omitempty"`
462485
}

‎pkg/apis/postgres-operator.crunchydata.com/v1beta1/postgrescluster_types.go‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,10 @@ type PostgresClusterDataSource struct {
308308
// More info: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration
309309
// +optional
310310
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
311+
312+
// Volumes to add to Restore Job Pods
313+
// +optional
314+
Volumes *PGBackRestVolumesSpec `json:"volumes,omitempty"`
311315
}
312316

313317
// Default defines several key default values for a Postgres cluster.

‎pkg/apis/postgres-operator.crunchydata.com/v1beta1/zz_generated.deepcopy.go‎

Lines changed: 42 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)

AltStyle によって変換されたページ (->オリジナル) /