diff --git a/config/crd/bases/pxc.percona.com_perconaxtradbclusters.yaml b/config/crd/bases/pxc.percona.com_perconaxtradbclusters.yaml index c8bf4ccee9..230bdabbc7 100644 --- a/config/crd/bases/pxc.percona.com_perconaxtradbclusters.yaml +++ b/config/crd/bases/pxc.percona.com_perconaxtradbclusters.yaml @@ -1141,6 +1141,9 @@ spec: suspendedDeadlineSeconds: format: int64 type: integer + ttlSecondsAfterFinished: + format: int32 + type: integer type: object crVersion: type: string diff --git a/deploy/bundle.yaml b/deploy/bundle.yaml index 6d0e6ee75d..54243e6be9 100644 --- a/deploy/bundle.yaml +++ b/deploy/bundle.yaml @@ -2448,6 +2448,9 @@ spec: suspendedDeadlineSeconds: format: int64 type: integer + ttlSecondsAfterFinished: + format: int32 + type: integer type: object crVersion: type: string diff --git a/deploy/cr.yaml b/deploy/cr.yaml index 42c7fd226e..b1530fee3a 100644 --- a/deploy/cr.yaml +++ b/deploy/cr.yaml @@ -618,6 +618,7 @@ spec: backup: # allowParallel: true image: perconalab/percona-xtradb-cluster-operator:main-pxc8.0-backup +# ttlSecondsAfterFinished: 3600 # backoffLimit: 6 # activeDeadlineSeconds: 3600 # startingDeadlineSeconds: 300 diff --git a/deploy/crd.yaml b/deploy/crd.yaml index bece937fe6..27ab1c07f7 100644 --- a/deploy/crd.yaml +++ b/deploy/crd.yaml @@ -2448,6 +2448,9 @@ spec: suspendedDeadlineSeconds: format: int64 type: integer + ttlSecondsAfterFinished: + format: int32 + type: integer type: object crVersion: type: string diff --git a/deploy/cw-bundle.yaml b/deploy/cw-bundle.yaml index 7246088a7b..6f48329373 100644 --- a/deploy/cw-bundle.yaml +++ b/deploy/cw-bundle.yaml @@ -2448,6 +2448,9 @@ spec: suspendedDeadlineSeconds: format: int64 type: integer + ttlSecondsAfterFinished: + format: int32 + type: integer type: object crVersion: type: string diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k127-oc.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k127-oc.yml index a51d75d843..78fa81927f 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k127-oc.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k127-oc.yml @@ -119,3 +119,4 @@ spec: secretName: some-name-vault - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k127.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k127.yml index 267d517766..60abc99aa0 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k127.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k127.yml @@ -120,3 +120,4 @@ spec: secretName: some-name-vault - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k129-oc.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k129-oc.yml index e49dff1482..44c86d580d 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k129-oc.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k129-oc.yml @@ -121,3 +121,4 @@ spec: secretName: some-name-vault - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k129.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k129.yml index b65a51db18..75c4cf6bf9 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k129.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-k129.yml @@ -122,3 +122,4 @@ spec: secretName: some-name-vault - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-oc.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-oc.yml index a51d75d843..78fa81927f 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-oc.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup-oc.yml @@ -119,3 +119,4 @@ spec: secretName: some-name-vault - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup.yml index 267d517766..60abc99aa0 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-minio-demand-backup.yml @@ -120,3 +120,4 @@ spec: secretName: some-name-vault - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup-k129-oc.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup-k129-oc.yml index 9595e20186..8252ac587e 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup-k129-oc.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup-k129-oc.yml @@ -106,3 +106,4 @@ spec: secretName: demand-backup-ssl - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup-k129.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup-k129.yml index a461bec7dc..8122ba9b91 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup-k129.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup-k129.yml @@ -107,3 +107,4 @@ spec: secretName: demand-backup-ssl - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup-oc.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup-oc.yml index 91d414e7fe..f9dc9fb472 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup-oc.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup-oc.yml @@ -104,3 +104,4 @@ spec: secretName: demand-backup-ssl - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup.yml index 96686f54e7..ed5ace973c 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-bsource-demand-backup.yml @@ -105,3 +105,4 @@ spec: secretName: demand-backup-ssl - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup-k129-oc.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup-k129-oc.yml index 3eb9273cb3..216b280cad 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup-k129-oc.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup-k129-oc.yml @@ -106,3 +106,4 @@ spec: secretName: demand-backup-ssl - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup-k129.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup-k129.yml index d4f35b14a9..f7062ef804 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup-k129.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup-k129.yml @@ -107,3 +107,4 @@ spec: secretName: demand-backup-ssl - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup-oc.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup-oc.yml index 1b0f6be2ca..dc9d95e952 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup-oc.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup-oc.yml @@ -104,3 +104,4 @@ spec: secretName: demand-backup-ssl - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup.yml b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup.yml index 0aaabe50ff..c813d2c706 100644 --- a/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup.yml +++ b/e2e-tests/demand-backup/compare/job_restore-job-on-demand-backup-pvc-demand-backup.yml @@ -105,3 +105,4 @@ spec: secretName: demand-backup-ssl - emptyDir: {} name: bin + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio-k129-oc.yml b/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio-k129-oc.yml index 8c06989dbc..98d9fea212 100644 --- a/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio-k129-oc.yml +++ b/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio-k129-oc.yml @@ -142,3 +142,4 @@ spec: defaultMode: 420 optional: true secretName: some-name-vault + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio-k129.yml b/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio-k129.yml index c6321a65fd..c4d1c6e99f 100644 --- a/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio-k129.yml +++ b/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio-k129.yml @@ -143,3 +143,4 @@ spec: defaultMode: 420 optional: true secretName: some-name-vault + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio-oc.yml b/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio-oc.yml index 7c03640e0c..bcabba5f1b 100644 --- a/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio-oc.yml +++ b/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio-oc.yml @@ -141,3 +141,4 @@ spec: defaultMode: 420 optional: true secretName: some-name-vault + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio.yml b/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio.yml index 1321d8dc77..b9f666e553 100644 --- a/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio.yml +++ b/e2e-tests/demand-backup/compare/job_xb-on-demand-backup-minio.yml @@ -142,3 +142,4 @@ spec: defaultMode: 420 optional: true secretName: some-name-vault + ttlSecondsAfterFinished: 3600 diff --git a/e2e-tests/demand-backup/conf/demand-backup.yml b/e2e-tests/demand-backup/conf/demand-backup.yml index 93a4f7c1d4..c967d33b02 100644 --- a/e2e-tests/demand-backup/conf/demand-backup.yml +++ b/e2e-tests/demand-backup/conf/demand-backup.yml @@ -63,6 +63,7 @@ spec: serverHost: monitoring-service serverUser: pmm backup: + ttlSecondsAfterFinished: 3600 activeDeadlineSeconds: 3600 allowParallel: false backoffLimit: 3 diff --git a/pkg/apis/pxc/v1/pxc_types.go b/pkg/apis/pxc/v1/pxc_types.go index 75c3c1c8bd..95e04e2c18 100644 --- a/pkg/apis/pxc/v1/pxc_types.go +++ b/pkg/apis/pxc/v1/pxc_types.go @@ -46,7 +46,7 @@ type PerconaXtraDBClusterSpec struct { HAProxy *HAProxySpec `json:"haproxy,omitempty"` PMM *PMMSpec `json:"pmm,omitempty"` LogCollector *LogCollectorSpec `json:"logcollector,omitempty"` - Backup *PXCScheduledBackup `json:"backup,omitempty"` + Backup *BackupSpec `json:"backup,omitempty"` UpdateStrategy appsv1.StatefulSetUpdateStrategyType `json:"updateStrategy,omitempty"` UpgradeOptions UpgradeOptions `json:"upgradeOptions,omitempty"` AllowUnsafeConfig bool `json:"allowUnsafeConfigurations,omitempty"` @@ -219,7 +219,7 @@ const ( SmartUpdateStatefulSetStrategyType appsv1.StatefulSetUpdateStrategyType = "SmartUpdate" ) -type PXCScheduledBackup struct { +type BackupSpec struct { AllowParallel *bool `json:"allowParallel,omitempty"` Image string `json:"image,omitempty"` ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"` @@ -233,13 +233,14 @@ type PXCScheduledBackup struct { ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"` StartingDeadlineSeconds *int64 `json:"startingDeadlineSeconds,omitempty"` SuspendedDeadlineSeconds *int64 `json:"suspendedDeadlineSeconds,omitempty"` + TTLSecondsAfterFinished *int32 `json:"ttlSecondsAfterFinished,omitempty"` // RunningDeadlineSeconds is the number of seconds to wait for the backup to transition to the 'Running' state. // Once this threshold is reached, the backup will be marked as failed. Default is 300 seconds (5m). // +kubebuilder:default:=300 RunningDeadlineSeconds *int64 `json:"runningDeadlineSeconds,omitempty"` } -func (b *PXCScheduledBackup) GetAllowParallel() bool { +func (b *BackupSpec) GetAllowParallel() bool { if b.AllowParallel == nil { return true } diff --git a/pkg/apis/pxc/v1/zz_generated.deepcopy.go b/pkg/apis/pxc/v1/zz_generated.deepcopy.go index ff13629659..71a71f144b 100644 --- a/pkg/apis/pxc/v1/zz_generated.deepcopy.go +++ b/pkg/apis/pxc/v1/zz_generated.deepcopy.go @@ -81,6 +81,92 @@ func (in *BackupContainerOptions) DeepCopy() *BackupContainerOptions { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackupSpec) DeepCopyInto(out *BackupSpec) { + *out = *in + if in.AllowParallel != nil { + in, out := &in.AllowParallel, &out.AllowParallel + *out = new(bool) + **out = **in + } + if in.ImagePullSecrets != nil { + in, out := &in.ImagePullSecrets, &out.ImagePullSecrets + *out = make([]corev1.LocalObjectReference, len(*in)) + copy(*out, *in) + } + if in.Schedule != nil { + in, out := &in.Schedule, &out.Schedule + *out = make([]PXCScheduledBackupSchedule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Storages != nil { + in, out := &in.Storages, &out.Storages + *out = make(map[string]*BackupStorageSpec, len(*in)) + for key, val := range *in { + var outVal *BackupStorageSpec + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = new(BackupStorageSpec) + (*in).DeepCopyInto(*out) + } + (*out)[key] = outVal + } + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.PITR.DeepCopyInto(&out.PITR) + if in.BackoffLimit != nil { + in, out := &in.BackoffLimit, &out.BackoffLimit + *out = new(int32) + **out = **in + } + if in.ActiveDeadlineSeconds != nil { + in, out := &in.ActiveDeadlineSeconds, &out.ActiveDeadlineSeconds + *out = new(int64) + **out = **in + } + if in.StartingDeadlineSeconds != nil { + in, out := &in.StartingDeadlineSeconds, &out.StartingDeadlineSeconds + *out = new(int64) + **out = **in + } + if in.SuspendedDeadlineSeconds != nil { + in, out := &in.SuspendedDeadlineSeconds, &out.SuspendedDeadlineSeconds + *out = new(int64) + **out = **in + } + if in.TTLSecondsAfterFinished != nil { + in, out := &in.TTLSecondsAfterFinished, &out.TTLSecondsAfterFinished + *out = new(int32) + **out = **in + } + if in.RunningDeadlineSeconds != nil { + in, out := &in.RunningDeadlineSeconds, &out.RunningDeadlineSeconds + *out = new(int64) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupSpec. +func (in *BackupSpec) DeepCopy() *BackupSpec { + if in == nil { + return nil + } + out := new(BackupSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BackupStorageAzureSpec) DeepCopyInto(out *BackupStorageAzureSpec) { *out = *in @@ -527,87 +613,6 @@ func (in *PXCBackupStatus) DeepCopy() *PXCBackupStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PXCScheduledBackup) DeepCopyInto(out *PXCScheduledBackup) { - *out = *in - if in.AllowParallel != nil { - in, out := &in.AllowParallel, &out.AllowParallel - *out = new(bool) - **out = **in - } - if in.ImagePullSecrets != nil { - in, out := &in.ImagePullSecrets, &out.ImagePullSecrets - *out = make([]corev1.LocalObjectReference, len(*in)) - copy(*out, *in) - } - if in.Schedule != nil { - in, out := &in.Schedule, &out.Schedule - *out = make([]PXCScheduledBackupSchedule, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Storages != nil { - in, out := &in.Storages, &out.Storages - *out = make(map[string]*BackupStorageSpec, len(*in)) - for key, val := range *in { - var outVal *BackupStorageSpec - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = new(BackupStorageSpec) - (*in).DeepCopyInto(*out) - } - (*out)[key] = outVal - } - } - if in.Annotations != nil { - in, out := &in.Annotations, &out.Annotations - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - in.PITR.DeepCopyInto(&out.PITR) - if in.BackoffLimit != nil { - in, out := &in.BackoffLimit, &out.BackoffLimit - *out = new(int32) - **out = **in - } - if in.ActiveDeadlineSeconds != nil { - in, out := &in.ActiveDeadlineSeconds, &out.ActiveDeadlineSeconds - *out = new(int64) - **out = **in - } - if in.StartingDeadlineSeconds != nil { - in, out := &in.StartingDeadlineSeconds, &out.StartingDeadlineSeconds - *out = new(int64) - **out = **in - } - if in.SuspendedDeadlineSeconds != nil { - in, out := &in.SuspendedDeadlineSeconds, &out.SuspendedDeadlineSeconds - *out = new(int64) - **out = **in - } - if in.RunningDeadlineSeconds != nil { - in, out := &in.RunningDeadlineSeconds, &out.RunningDeadlineSeconds - *out = new(int64) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PXCScheduledBackup. -func (in *PXCScheduledBackup) DeepCopy() *PXCScheduledBackup { - if in == nil { - return nil - } - out := new(PXCScheduledBackup) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PXCScheduledBackupRetention) DeepCopyInto(out *PXCScheduledBackupRetention) { *out = *in @@ -963,7 +968,7 @@ func (in *PerconaXtraDBClusterSpec) DeepCopyInto(out *PerconaXtraDBClusterSpec) } if in.Backup != nil { in, out := &in.Backup, &out.Backup - *out = new(PXCScheduledBackup) + *out = new(BackupSpec) (*in).DeepCopyInto(*out) } out.UpgradeOptions = in.UpgradeOptions diff --git a/pkg/controller/pxc/controller_test.go b/pkg/controller/pxc/controller_test.go index 05745e7c48..f91161fd8b 100644 --- a/pkg/controller/pxc/controller_test.go +++ b/pkg/controller/pxc/controller_test.go @@ -1775,7 +1775,7 @@ var _ = Describe("Backup reconciliation", Ordered, func() { }) It("should create PerconaXtraDBCluster with backup configuration", func() { - cr.Spec.Backup = &api.PXCScheduledBackup{ + cr.Spec.Backup = &api.BackupSpec{ Image: "backup-image", Storages: map[string]*api.BackupStorageSpec{ "s3-us-west": { diff --git a/pkg/controller/pxcbackup/controller.go b/pkg/controller/pxcbackup/controller.go index 67d3604d10..2441f3de24 100644 --- a/pkg/controller/pxcbackup/controller.go +++ b/pkg/controller/pxcbackup/controller.go @@ -17,9 +17,11 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/retry" + k8sretry "k8s.io/client-go/util/retry" "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -134,6 +136,10 @@ func (r *ReconcilePerconaXtraDBClusterBackup) Reconcile(ctx context.Context, req } if cr.Status.State == api.BackupSucceeded || cr.Status.State == api.BackupFailed { + if err := r.runJobFinalizers(ctx, cr); err != nil { + return reconcile.Result{}, errors.Wrap(err, "run finalizers") + } + if len(cr.GetFinalizers()) > 0 { return rr, nil } @@ -223,7 +229,7 @@ func (r *ReconcilePerconaXtraDBClusterBackup) Reconcile(ctx context.Context, req } if err := r.reconcileBackupJob(ctx, cr, cluster); err != nil { - return rr, errors.Wrap(err, "reconcile backup job") + return reconcile.Result{}, errors.Wrap(err, "reconcile backup job") } if err := cluster.CanBackup(); err != nil { @@ -270,20 +276,23 @@ func (r *ReconcilePerconaXtraDBClusterBackup) Reconcile(ctx context.Context, req cr.Status.VerifyTLS = storage.VerifyTLS } - job, err := r.createBackupJob(ctx, cr, cluster, storage) + var job *batchv1.Job + job, err = r.createBackupJob(ctx, cr, cluster, storage) if err != nil { err = errors.Wrap(err, "create backup job") if err := r.setFailedStatus(ctx, cr, err); err != nil { - return rr, errors.Wrap(err, "update status") + return reconcile.Result{}, errors.Wrap(err, "update status") } return reconcile.Result{}, err } - err = r.updateJobStatus(ctx, cr, job, cr.Spec.StorageName, storage, cluster) + if err := r.updateJobStatus(ctx, cr, job, cr.Spec.StorageName, storage, cluster); err != nil { + return reconcile.Result{}, err + } - return rr, err + return rr, nil } func (r *ReconcilePerconaXtraDBClusterBackup) createBackupJob( @@ -358,12 +367,16 @@ func (r *ReconcilePerconaXtraDBClusterBackup) createBackupJob( return nil, errors.Wrap(err, "job/setControllerReference") } - err = r.client.Create(ctx, job) - if err != nil && !k8sErrors.IsAlreadyExists(err) { + if err := r.client.Create(ctx, job); err != nil { + if k8sErrors.IsAlreadyExists(err) { + if err := r.client.Get(ctx, client.ObjectKeyFromObject(job), job); err != nil { + return nil, errors.Wrap(err, "get backup job") + } + return job, nil + } return nil, errors.Wrap(err, "create backup job") - } else if err == nil { - log.Info("Created a new backup job", "namespace", job.Namespace, "name", job.Name) } + log.Info("Created a new backup job", "namespace", job.Namespace, "name", job.Name) return job, nil } @@ -542,7 +555,6 @@ func (r *ReconcilePerconaXtraDBClusterBackup) runFilesystemBackupFinalizer(ctx c backupName := cr.Status.Destination.BackupName() log.Info("Deleting backup from fs-pvc", "name", cr.Name, "backupName", backupName) err := r.deleteBackupPVC(ctx, cr.Namespace, backupName) - if err != nil { return errors.Wrapf(err, "failed to delete backup %s", cr.Name) } @@ -748,7 +760,7 @@ func (r *ReconcilePerconaXtraDBClusterBackup) suspendJobIfNeeded( log := logf.FromContext(ctx) err := retry.RetryOnConflict(retry.DefaultRetry, func() error { - job, err := r.getBackupJob(ctx, cluster, cr) + job, err := r.getBackupJob(ctx, cr) if err != nil { if k8sErrors.IsNotFound(err) { return nil @@ -802,7 +814,7 @@ func (r *ReconcilePerconaXtraDBClusterBackup) resumeJobIfNeeded( log := logf.FromContext(ctx) err := retry.RetryOnConflict(retry.DefaultRetry, func() error { - job, err := r.getBackupJob(ctx, cluster, cr) + job, err := r.getBackupJob(ctx, cr) if err != nil { if k8sErrors.IsNotFound(err) { return nil @@ -858,16 +870,13 @@ func (r *ReconcilePerconaXtraDBClusterBackup) reconcileBackupJob( func (r *ReconcilePerconaXtraDBClusterBackup) getBackupJob( ctx context.Context, - cluster *api.PerconaXtraDBCluster, cr *api.PerconaXtraDBClusterBackup, ) (*batchv1.Job, error) { - labelKeyBackupType := naming.GetLabelBackupType(cluster) - jobName := naming.BackupJobName(cr.Name, cr.Labels[labelKeyBackupType] == "cron") + jobName := naming.BackupJobName(cr.Name) job := new(batchv1.Job) - err := r.client.Get(ctx, types.NamespacedName{Namespace: cr.Namespace, Name: jobName}, job) - if err != nil { + if err := r.client.Get(ctx, types.NamespacedName{Namespace: cr.Namespace, Name: jobName}, job); err != nil { return nil, err } @@ -879,11 +888,15 @@ func (r *ReconcilePerconaXtraDBClusterBackup) cleanUpJob( cluster *api.PerconaXtraDBCluster, cr *api.PerconaXtraDBClusterBackup, ) error { - job, err := r.getBackupJob(ctx, cluster, cr) + job, err := r.getBackupJob(ctx, cr) if err != nil { return errors.Wrap(err, "get job") } + if err := r.runJobFinalizers(ctx, cr); err != nil { + return errors.Wrap(err, "run job finalizers") + } + // Set propagationPolicy=background because default deletion preserves pods. if err := r.client.Delete(ctx, job, client.PropagationPolicy(metav1.DeletePropagationBackground)); err != nil { return errors.Wrap(err, "delete job") @@ -892,6 +905,25 @@ func (r *ReconcilePerconaXtraDBClusterBackup) cleanUpJob( return nil } +func (r *ReconcilePerconaXtraDBClusterBackup) runJobFinalizers(ctx context.Context, cr *api.PerconaXtraDBClusterBackup) error { + if err := k8sretry.RetryOnConflict(k8sretry.DefaultRetry, func() error { + job, err := r.getBackupJob(ctx, cr) + if k8sErrors.IsNotFound(err) { + return nil + } else if err != nil { + return errors.Wrap(err, "failed to get job") + } + + if removed := controllerutil.RemoveFinalizer(job, naming.FinalizerKeepJob); removed { + return r.client.Update(ctx, job) + } + return nil + }); err != nil { + return errors.Wrap(err, "failed to remove keep-job finalizer") + } + return nil +} + func (r *ReconcilePerconaXtraDBClusterBackup) deleteBackupPVC(ctx context.Context, backupNamespace, backupPVCName string) error { log := logf.FromContext(ctx) log.Info("Deleting backup PVC", "namespace", backupNamespace, "pvc", backupPVCName) diff --git a/pkg/controller/pxcbackup/controller_test.go b/pkg/controller/pxcbackup/controller_test.go index e5d5317622..40ef5aab13 100644 --- a/pkg/controller/pxcbackup/controller_test.go +++ b/pkg/controller/pxcbackup/controller_test.go @@ -7,10 +7,6 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/percona/percona-xtradb-cluster-operator/clientcmd" - pxcv1 "github.com/percona/percona-xtradb-cluster-operator/pkg/apis/pxc/v1" - "github.com/percona/percona-xtradb-cluster-operator/pkg/pxc/backup" - "github.com/percona/percona-xtradb-cluster-operator/pkg/version" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -18,6 +14,11 @@ import ( "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" + + "github.com/percona/percona-xtradb-cluster-operator/clientcmd" + pxcv1 "github.com/percona/percona-xtradb-cluster-operator/pkg/apis/pxc/v1" + "github.com/percona/percona-xtradb-cluster-operator/pkg/pxc/backup" + "github.com/percona/percona-xtradb-cluster-operator/pkg/version" ) var _ = Describe("PerconaXtraDBClusterBackup", Ordered, func() { @@ -149,6 +150,10 @@ var _ = Describe("Error checking deadlines", Ordered, func() { // We will delete the job, this will cause the deadline check to fail job := backup.New(cluster).Job(pxcBackup, cluster) + Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(job), job)).To(Succeed()) + job.Finalizers = []string{} + Expect(k8sClient.Update(ctx, job)).To(Succeed()) + err = k8sClient.Delete(ctx, job, client.PropagationPolicy(metav1.DeletePropagationBackground)) Expect(err).To(Not(HaveOccurred())) diff --git a/pkg/controller/pxcbackup/deadline.go b/pkg/controller/pxcbackup/deadline.go index 3397bfd962..be97de5785 100644 --- a/pkg/controller/pxcbackup/deadline.go +++ b/pkg/controller/pxcbackup/deadline.go @@ -87,7 +87,7 @@ func (r *ReconcilePerconaXtraDBClusterBackup) checkRunningDeadline(ctx context.C return nil } - job, err := r.getBackupJob(ctx, cluster, cr) + job, err := r.getBackupJob(ctx, cr) if err != nil { return fmt.Errorf("failed to get backup job for running deadline check: %w", err) } @@ -113,7 +113,7 @@ func (r *ReconcilePerconaXtraDBClusterBackup) checkSuspendedDeadline( ) error { log := logf.FromContext(ctx) - job, err := r.getBackupJob(ctx, cluster, cr) + job, err := r.getBackupJob(ctx, cr) if err != nil { if k8sErrors.IsNotFound(err) { return nil diff --git a/pkg/controller/pxcrestore/controller.go b/pkg/controller/pxcrestore/controller.go index 5ae468fd41..8f8ce3fdf5 100644 --- a/pkg/controller/pxcrestore/controller.go +++ b/pkg/controller/pxcrestore/controller.go @@ -15,6 +15,7 @@ import ( k8sretry "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -22,6 +23,7 @@ import ( "github.com/percona/percona-xtradb-cluster-operator/clientcmd" api "github.com/percona/percona-xtradb-cluster-operator/pkg/apis/pxc/v1" "github.com/percona/percona-xtradb-cluster-operator/pkg/k8s" + "github.com/percona/percona-xtradb-cluster-operator/pkg/naming" "github.com/percona/percona-xtradb-cluster-operator/pkg/pxc/app/binlogcollector" "github.com/percona/percona-xtradb-cluster-operator/pkg/pxc/backup" "github.com/percona/percona-xtradb-cluster-operator/pkg/pxc/backup/storage" @@ -103,11 +105,14 @@ func (r *ReconcilePerconaXtraDBClusterRestore) Reconcile(ctx context.Context, re return rr, nil } // Error reading the object - requeue the request. - return rr, err + return reconcile.Result{}, err } switch cr.Status.State { case api.RestoreSucceeded, api.RestoreFailed: + if err := r.runJobFinalizers(ctx, cr); err != nil { + return reconcile.Result{}, errors.Wrap(err, "run job finalizers") + } return reconcile.Result{}, nil } @@ -125,19 +130,19 @@ func (r *ReconcilePerconaXtraDBClusterRestore) Reconcile(ctx context.Context, re otherRestore, err := isOtherRestoreInProgress(ctx, r.client, cr) if err != nil { - return rr, errors.Wrap(err, "failed to check if other restore is in progress") + return reconcile.Result{}, errors.Wrap(err, "failed to check if other restore is in progress") } if otherRestore != nil { err = errors.Errorf("unable to continue, concurrent restore job %s running now", otherRestore.Name) cr.Status.State = api.RestoreFailed cr.Status.Comments = err.Error() - return rr, err + return reconcile.Result{}, err } if err := cr.CheckNsetDefaults(); err != nil { cr.Status.State = api.RestoreFailed cr.Status.Comments = err.Error() - return rr, err + return reconcile.Result{}, err } cluster := new(api.PerconaXtraDBCluster) @@ -146,25 +151,25 @@ func (r *ReconcilePerconaXtraDBClusterRestore) Reconcile(ctx context.Context, re cr.Status.State = api.RestoreFailed cr.Status.Comments = err.Error() } - return rr, errors.Wrapf(err, "get cluster %s", cr.Spec.PXCCluster) + return reconcile.Result{}, errors.Wrapf(err, "get cluster %s", cr.Spec.PXCCluster) } if err := cluster.CheckNSetDefaults(r.serverVersion, log); err != nil { cr.Status.State = api.RestoreFailed cr.Status.Comments = err.Error() - return rr, errors.Wrap(err, "wrong PXC options") + return reconcile.Result{}, errors.Wrap(err, "wrong PXC options") } bcp, err := getBackup(ctx, r.client, cr) if err != nil { cr.Status.State = api.RestoreFailed cr.Status.Comments = err.Error() - return rr, errors.Wrap(err, "get backup") + return reconcile.Result{}, errors.Wrap(err, "get backup") } restorer, err := r.getRestorer(ctx, cr, bcp, cluster) if err != nil { - return rr, errors.Wrap(err, "failed to get restorer") + return reconcile.Result{}, errors.Wrap(err, "failed to get restorer") } switch cr.Status.State { @@ -182,7 +187,7 @@ func (r *ReconcilePerconaXtraDBClusterRestore) Reconcile(ctx context.Context, re return r.reconcileStateStartCluster(ctx, restorer, cr, cluster) } - return rr, errors.Errorf("unknown state: %s", cr.Status.State) + return reconcile.Result{}, errors.Errorf("unknown state: %s", cr.Status.State) } func (r *ReconcilePerconaXtraDBClusterRestore) reconcileStateStartCluster(ctx context.Context, restorer Restorer, cr *api.PerconaXtraDBClusterRestore, cluster *api.PerconaXtraDBCluster) (reconcile.Result, error) { @@ -521,3 +526,31 @@ func (r *ReconcilePerconaXtraDBClusterRestore) reconcileStatePrepareCluster( cr.Status.State = api.RestoreStartCluster return reconcile.Result{}, nil } + +func (r *ReconcilePerconaXtraDBClusterRestore) runJobFinalizers(ctx context.Context, cr *api.PerconaXtraDBClusterRestore) error { + for _, jobName := range []string{ + naming.RestoreJobName(cr, false), + naming.RestoreJobName(cr, true), + } { + if err := k8sretry.RetryOnConflict(k8sretry.DefaultRetry, func() error { + job := new(batchv1.Job) + if err := r.client.Get(ctx, types.NamespacedName{ + Name: jobName, + Namespace: cr.Namespace, + }, job); err != nil { + if k8serrors.IsNotFound(err) { + return nil + } + return errors.Wrap(err, "failed to get job") + } + + if removed := controllerutil.RemoveFinalizer(job, naming.FinalizerKeepJob); removed { + return r.client.Update(ctx, job) + } + return nil + }); err != nil { + return errors.Wrap(err, "failed to remove keep-job finalizer") + } + } + return nil +} diff --git a/pkg/naming/backup.go b/pkg/naming/backup.go index fb27c85eec..4ea79a0718 100644 --- a/pkg/naming/backup.go +++ b/pkg/naming/backup.go @@ -23,7 +23,7 @@ func BackupHolderId(cr *pxcv1.PerconaXtraDBClusterBackup) string { // k8s sets the `job-name` label for the created by job pod. // So we have to be sure that job name won't be longer than 63 symbols. // Yet the job name has to have some meaningful name which won't be conflicting with other jobs' names. -func BackupJobName(crName string, isCron bool) string { +func BackupJobName(crName string) string { return trimJobName("xb-" + crName) } diff --git a/pkg/naming/naming.go b/pkg/naming/naming.go index 63555e3fe1..7c823b0d7c 100644 --- a/pkg/naming/naming.go +++ b/pkg/naming/naming.go @@ -12,6 +12,7 @@ const ( FinalizerDeletePxcPvc = annotationPrefix + "delete-pxc-pvc" FinalizerDeleteBackup = annotationPrefix + "delete-backup" FinalizerReleaseLock = internalAnnotationPrefix + "release-lock" + FinalizerKeepJob = internalAnnotationPrefix + "keep-job" ) const ( diff --git a/pkg/naming/restore.go b/pkg/naming/restore.go index fa2715a49f..a0a2aba900 100644 --- a/pkg/naming/restore.go +++ b/pkg/naming/restore.go @@ -7,3 +7,11 @@ import ( func PrepareJobName(restore *pxcv1.PerconaXtraDBClusterRestore) string { return "prepare-job-" + restore.Name + "-" + restore.Spec.PXCCluster } + +func RestoreJobName(cr *pxcv1.PerconaXtraDBClusterRestore, pitr bool) string { + prefix := "restore-job-" + if pitr { + prefix = "pitr-job-" + } + return prefix + cr.Name + "-" + cr.Spec.PXCCluster +} diff --git a/pkg/pxc/app/binlogcollector/binlog_collector_test.go b/pkg/pxc/app/binlogcollector/binlog_collector_test.go index 45cf833d8f..2b6395c312 100644 --- a/pkg/pxc/app/binlogcollector/binlog_collector_test.go +++ b/pkg/pxc/app/binlogcollector/binlog_collector_test.go @@ -4,10 +4,11 @@ import ( "reflect" "testing" - api "github.com/percona/percona-xtradb-cluster-operator/pkg/apis/pxc/v1" - "github.com/percona/percona-xtradb-cluster-operator/pkg/version" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + api "github.com/percona/percona-xtradb-cluster-operator/pkg/apis/pxc/v1" + "github.com/percona/percona-xtradb-cluster-operator/pkg/version" ) func TestGetDeployment(t *testing.T) { @@ -26,7 +27,7 @@ func TestGetDeployment(t *testing.T) { ContainerSecurityContext: &corev1.SecurityContext{}, }, }, - Backup: &api.PXCScheduledBackup{ + Backup: &api.BackupSpec{ PITR: api.PITRSpec{ Enabled: true, StorageName: "test-storage", @@ -132,9 +133,7 @@ func TestGetDeployment(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - depl, err := GetDeployment(tt.cr, "perconalab/percona-xtradb-cluster-operator:main", tt.existingMatchLabels) - if err != nil { t.Errorf("GetDeployment() error = %v", err) return diff --git a/pkg/pxc/backup/job.go b/pkg/pxc/backup/job.go index 5ca33b6c9b..f38f59c1fd 100644 --- a/pkg/pxc/backup/job.go +++ b/pkg/pxc/backup/job.go @@ -19,8 +19,7 @@ import ( ) func (*Backup) Job(cr *api.PerconaXtraDBClusterBackup, cluster *api.PerconaXtraDBCluster) *batchv1.Job { - labelKeyBackupType := naming.GetLabelBackupType(cluster) - jobName := naming.BackupJobName(cr.Name, cr.Labels[labelKeyBackupType] == "cron") + jobName := naming.BackupJobName(cr.Name) return &batchv1.Job{ TypeMeta: metav1.TypeMeta{ @@ -32,6 +31,9 @@ func (*Backup) Job(cr *api.PerconaXtraDBClusterBackup, cluster *api.PerconaXtraD Namespace: cr.Namespace, Labels: naming.LabelsBackupJob(cr, cluster, jobName), Annotations: cluster.Spec.Backup.Storages[cr.Spec.StorageName].Annotations, + Finalizers: []string{ + naming.FinalizerKeepJob, + }, }, } } @@ -106,9 +108,10 @@ func (bcp *Backup) JobSpec(spec api.PXCBackupSpec, cluster *api.PerconaXtraDBClu } return batchv1.JobSpec{ - ActiveDeadlineSeconds: activeDeadlineSeconds, - BackoffLimit: &backoffLimit, - ManualSelector: &manualSelector, + ActiveDeadlineSeconds: activeDeadlineSeconds, + BackoffLimit: &backoffLimit, + ManualSelector: &manualSelector, + TTLSecondsAfterFinished: cluster.Spec.Backup.TTLSecondsAfterFinished, Selector: &metav1.LabelSelector{ MatchLabels: job.Labels, }, diff --git a/pkg/pxc/backup/restore.go b/pkg/pxc/backup/restore.go index 071f8f000f..c574a7d484 100644 --- a/pkg/pxc/backup/restore.go +++ b/pkg/pxc/backup/restore.go @@ -225,7 +225,6 @@ func RestoreJob(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBClust return nil, errors.Errorf("no storage type was specified in status, got: %s", bcp.Status.GetStorageType(cluster)) } - jobName := "restore-job-" + cr.Name + "-" + cr.Spec.PXCCluster volumeMounts := []corev1.VolumeMount{ { Name: "datadir", @@ -284,7 +283,6 @@ func RestoreJob(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBClust if cluster.Spec.Backup == nil && len(cluster.Spec.Backup.Storages) == 0 { return nil, errors.New("no storage section") } - jobName = "pitr-job-" + cr.Name + "-" + cr.Spec.PXCCluster volumeMounts = []corev1.VolumeMount{} volumes = []corev1.Volume{} command = []string{"/opt/percona/pitr", "recover"} @@ -347,6 +345,7 @@ func RestoreJob(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBClust initContainers = []corev1.Container{statefulset.BackupInitContainer(cluster, initImage, cluster.Spec.PXC.ContainerSecurityContext)} } + jobName := naming.RestoreJobName(cr, pitr) job := &batchv1.Job{ TypeMeta: metav1.TypeMeta{ APIVersion: "batch/v1", @@ -356,8 +355,12 @@ func RestoreJob(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBClust Name: jobName, Namespace: cr.Namespace, Labels: naming.LabelsRestoreJob(cluster, jobName, bcp.Status.StorageName), + Finalizers: []string{ + naming.FinalizerKeepJob, + }, }, Spec: batchv1.JobSpec{ + TTLSecondsAfterFinished: cluster.Spec.Backup.TTLSecondsAfterFinished, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Annotations: cluster.Spec.PXC.Annotations, diff --git a/pkg/pxc/backup/restore_test.go b/pkg/pxc/backup/restore_test.go index 4013309c25..20dfd2da73 100644 --- a/pkg/pxc/backup/restore_test.go +++ b/pkg/pxc/backup/restore_test.go @@ -23,7 +23,7 @@ func TestPrepareJob(t *testing.T) { }, Spec: pxcv1.PerconaXtraDBClusterSpec{ CRVersion: version.Version(), - Backup: &pxcv1.PXCScheduledBackup{ + Backup: &pxcv1.BackupSpec{ Image: "percona/percona-xtrabackup:8.0", Storages: map[string]*pxcv1.BackupStorageSpec{ "test-storage": { diff --git a/pkg/pxc/backup/storage/options_test.go b/pkg/pxc/backup/storage/options_test.go index fd2f134b0b..f9a14b7ada 100644 --- a/pkg/pxc/backup/storage/options_test.go +++ b/pkg/pxc/backup/storage/options_test.go @@ -154,7 +154,7 @@ func TestGetS3Options(t *testing.T) { if tt.storage != nil { cluster = &api.PerconaXtraDBCluster{ Spec: api.PerconaXtraDBClusterSpec{ - Backup: &api.PXCScheduledBackup{ + Backup: &api.BackupSpec{ Storages: map[string]*api.BackupStorageSpec{ storageName: tt.storage, }, diff --git a/pkg/pxc/backup/volume.go b/pkg/pxc/backup/volume.go index 33ecaf32f1..635c68220b 100644 --- a/pkg/pxc/backup/volume.go +++ b/pkg/pxc/backup/volume.go @@ -18,7 +18,7 @@ func NewPVC(cr *api.PerconaXtraDBClusterBackup, cluster *api.PerconaXtraDBCluste ls = naming.LabelsCluster(cluster) } - base := naming.BackupJobName(cr.Name, false) + base := naming.BackupJobName(cr.Name) ts := cr.CreationTimestamp.UTC().Format("20060102150405")