Skip to content

Commit 3947ce7

Browse files
committed
Allow user to set an annotation that will specify an existing PVC to be mounted to cloud backup jobs so that the backup logs can be persisted.
1 parent 7b0cafc commit 3947ce7

File tree

8 files changed

+416
-32
lines changed

8 files changed

+416
-32
lines changed

internal/controller/postgrescluster/pgbackrest.go

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
"github.com/crunchydata/postgres-operator/internal/pgbackrest"
3939
"github.com/crunchydata/postgres-operator/internal/pki"
4040
"github.com/crunchydata/postgres-operator/internal/postgres"
41+
"github.com/crunchydata/postgres-operator/internal/util"
4142
"github.com/crunchydata/postgres-operator/pkg/apis/postgres-operator.crunchydata.com/v1beta1"
4243
)
4344

@@ -777,7 +778,7 @@ func (r *Reconciler) generateRepoVolumeIntent(postgresCluster *v1beta1.PostgresC
777778
}
778779

779780
// generateBackupJobSpecIntent generates a JobSpec for a pgBackRest backup job
780-
func generateBackupJobSpecIntent(ctx context.Context, postgresCluster *v1beta1.PostgresCluster,
781+
func (r *Reconciler) generateBackupJobSpecIntent(ctx context.Context, postgresCluster *v1beta1.PostgresCluster,
781782
repo v1beta1.PGBackRestRepo, serviceAccountName string,
782783
labels, annotations map[string]string, opts ...string) *batchv1.JobSpec {
783784

@@ -879,6 +880,27 @@ func generateBackupJobSpecIntent(ctx context.Context, postgresCluster *v1beta1.P
879880
// to read certificate files
880881
jobSpec.Template.Spec.SecurityContext = postgres.PodSecurityContext(postgresCluster)
881882
pgbackrest.AddConfigToCloudBackupJob(postgresCluster, &jobSpec.Template)
883+
884+
// If the user has specified a PVC to use as a log volume via the PGBackRestCloudLogVolume
885+
// annotation, check for the PVC. If we find it, mount it to the backup job.
886+
// Otherwise, create a warning event.
887+
if logVolumeName := postgresCluster.Annotations[naming.PGBackRestCloudLogVolume]; logVolumeName != "" {
888+
logVolume := &corev1.PersistentVolumeClaim{
889+
ObjectMeta: metav1.ObjectMeta{
890+
Name: logVolumeName,
891+
Namespace: postgresCluster.GetNamespace(),
892+
},
893+
}
894+
err := errors.WithStack(r.Client.Get(ctx,
895+
client.ObjectKeyFromObject(logVolume), logVolume))
896+
if err != nil {
897+
// PVC not retrieved, create warning event
898+
r.Recorder.Event(postgresCluster, corev1.EventTypeWarning, "PGBackRestCloudLogVolumeNotFound", err.Error())
899+
} else {
900+
// We successfully found the specified PVC, so we will add it to the backup job
901+
util.AddVolumeAndMountsToPod(&jobSpec.Template.Spec, logVolume)
902+
}
903+
}
882904
}
883905

884906
return jobSpec
@@ -2046,8 +2068,31 @@ func (r *Reconciler) reconcilePGBackRestConfig(ctx context.Context,
20462068
repoHostName, configHash, serviceName, serviceNamespace string,
20472069
instanceNames []string) error {
20482070

2071+
// If the user has specified a PVC to use as a log volume for cloud backups via the
2072+
// PGBackRestCloudLogVolume annotation, check for the PVC. If we find it, set the cloud
2073+
// log path. If the user has specified a PVC, but we can't find it, create a warning event.
2074+
cloudLogPath := ""
2075+
if logVolumeName := postgresCluster.Annotations[naming.PGBackRestCloudLogVolume]; logVolumeName != "" {
2076+
logVolume := &corev1.PersistentVolumeClaim{
2077+
ObjectMeta: metav1.ObjectMeta{
2078+
Name: logVolumeName,
2079+
Namespace: postgresCluster.GetNamespace(),
2080+
},
2081+
}
2082+
err := errors.WithStack(r.Client.Get(ctx,
2083+
client.ObjectKeyFromObject(logVolume), logVolume))
2084+
if err != nil {
2085+
// PVC not retrieved, create warning event
2086+
r.Recorder.Event(postgresCluster, corev1.EventTypeWarning,
2087+
"PGBackRestCloudLogVolumeNotFound", err.Error())
2088+
} else {
2089+
// We successfully found the specified PVC, so we will set the log path
2090+
cloudLogPath = "/volumes/" + logVolumeName
2091+
}
2092+
}
2093+
20492094
backrestConfig, err := pgbackrest.CreatePGBackRestConfigMapIntent(ctx, postgresCluster, repoHostName,
2050-
configHash, serviceName, serviceNamespace, instanceNames)
2095+
configHash, serviceName, serviceNamespace, cloudLogPath, instanceNames)
20512096
if err != nil {
20522097
return err
20532098
}
@@ -2460,7 +2505,7 @@ func (r *Reconciler) reconcileManualBackup(ctx context.Context,
24602505
backupJob.ObjectMeta.Labels = labels
24612506
backupJob.ObjectMeta.Annotations = annotations
24622507

2463-
spec := generateBackupJobSpecIntent(ctx, postgresCluster, repo,
2508+
spec := r.generateBackupJobSpecIntent(ctx, postgresCluster, repo,
24642509
serviceAccount.GetName(), labels, annotations, backupOpts...)
24652510

24662511
backupJob.Spec = *spec
@@ -2637,7 +2682,7 @@ func (r *Reconciler) reconcileReplicaCreateBackup(ctx context.Context,
26372682
backupJob.ObjectMeta.Labels = labels
26382683
backupJob.ObjectMeta.Annotations = annotations
26392684

2640-
spec := generateBackupJobSpecIntent(ctx, postgresCluster, replicaCreateRepo,
2685+
spec := r.generateBackupJobSpecIntent(ctx, postgresCluster, replicaCreateRepo,
26412686
serviceAccount.GetName(), labels, annotations)
26422687

26432688
backupJob.Spec = *spec
@@ -3064,7 +3109,7 @@ func (r *Reconciler) reconcilePGBackRestCronJob(
30643109
// set backup type (i.e. "full", "diff", "incr")
30653110
backupOpts := []string{"--type=" + backupType}
30663111

3067-
jobSpec := generateBackupJobSpecIntent(ctx, cluster, repo,
3112+
jobSpec := r.generateBackupJobSpecIntent(ctx, cluster, repo,
30683113
serviceAccount.GetName(), labels, annotations, backupOpts...)
30693114

30703115
// Suspend cronjobs when shutdown or read-only. Any jobs that have already

0 commit comments

Comments
 (0)