Skip to content

Commit 6a30d72

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 23acb76 commit 6a30d72

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

@@ -771,7 +772,7 @@ func (r *Reconciler) generateRepoVolumeIntent(postgresCluster *v1beta1.PostgresC
771772
}
772773

773774
// generateBackupJobSpecIntent generates a JobSpec for a pgBackRest backup job
774-
func generateBackupJobSpecIntent(ctx context.Context, postgresCluster *v1beta1.PostgresCluster,
775+
func (r *Reconciler) generateBackupJobSpecIntent(ctx context.Context, postgresCluster *v1beta1.PostgresCluster,
775776
repo v1beta1.PGBackRestRepo, serviceAccountName string,
776777
labels, annotations map[string]string, opts ...string) *batchv1.JobSpec {
777778

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

878900
return jobSpec
@@ -2040,8 +2062,31 @@ func (r *Reconciler) reconcilePGBackRestConfig(ctx context.Context,
20402062
repoHostName, configHash, serviceName, serviceNamespace string,
20412063
instanceNames []string) error {
20422064

2065+
// If the user has specified a PVC to use as a log volume for cloud backups via the
2066+
// PGBackRestCloudLogVolume annotation, check for the PVC. If we find it, set the cloud
2067+
// log path. If the user has specified a PVC, but we can't find it, create a warning event.
2068+
cloudLogPath := ""
2069+
if logVolumeName := postgresCluster.Annotations[naming.PGBackRestCloudLogVolume]; logVolumeName != "" {
2070+
logVolume := &corev1.PersistentVolumeClaim{
2071+
ObjectMeta: metav1.ObjectMeta{
2072+
Name: logVolumeName,
2073+
Namespace: postgresCluster.GetNamespace(),
2074+
},
2075+
}
2076+
err := errors.WithStack(r.Client.Get(ctx,
2077+
client.ObjectKeyFromObject(logVolume), logVolume))
2078+
if err != nil {
2079+
// PVC not retrieved, create warning event
2080+
r.Recorder.Event(postgresCluster, corev1.EventTypeWarning,
2081+
"PGBackRestCloudLogVolumeNotFound", err.Error())
2082+
} else {
2083+
// We successfully found the specified PVC, so we will set the log path
2084+
cloudLogPath = "/volumes/" + logVolumeName
2085+
}
2086+
}
2087+
20432088
backrestConfig, err := pgbackrest.CreatePGBackRestConfigMapIntent(ctx, postgresCluster, repoHostName,
2044-
configHash, serviceName, serviceNamespace, instanceNames)
2089+
configHash, serviceName, serviceNamespace, cloudLogPath, instanceNames)
20452090
if err != nil {
20462091
return err
20472092
}
@@ -2454,7 +2499,7 @@ func (r *Reconciler) reconcileManualBackup(ctx context.Context,
24542499
backupJob.Labels = labels
24552500
backupJob.Annotations = annotations
24562501

2457-
spec := generateBackupJobSpecIntent(ctx, postgresCluster, repo,
2502+
spec := r.generateBackupJobSpecIntent(ctx, postgresCluster, repo,
24582503
serviceAccount.GetName(), labels, annotations, backupOpts...)
24592504

24602505
backupJob.Spec = *spec
@@ -2631,7 +2676,7 @@ func (r *Reconciler) reconcileReplicaCreateBackup(ctx context.Context,
26312676
backupJob.Labels = labels
26322677
backupJob.Annotations = annotations
26332678

2634-
spec := generateBackupJobSpecIntent(ctx, postgresCluster, replicaCreateRepo,
2679+
spec := r.generateBackupJobSpecIntent(ctx, postgresCluster, replicaCreateRepo,
26352680
serviceAccount.GetName(), labels, annotations)
26362681

26372682
backupJob.Spec = *spec
@@ -3058,7 +3103,7 @@ func (r *Reconciler) reconcilePGBackRestCronJob(
30583103
// set backup type (i.e. "full", "diff", "incr")
30593104
backupOpts := []string{"--type=" + backupType}
30603105

3061-
jobSpec := generateBackupJobSpecIntent(ctx, cluster, repo,
3106+
jobSpec := r.generateBackupJobSpecIntent(ctx, cluster, repo,
30623107
serviceAccount.GetName(), labels, annotations, backupOpts...)
30633108

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

0 commit comments

Comments
 (0)