Skip to content

Commit

Permalink
*: Support make S3 and NFS backup schedule together radondb#689
Browse files Browse the repository at this point in the history
  • Loading branch information
acekingke committed Oct 26, 2022
1 parent e7a7c52 commit 08214e2
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 10 deletions.
5 changes: 5 additions & 0 deletions api/v1alpha1/mysqlcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ type MysqlClusterSpec struct {
// +optional
BackupSchedule string `json:"backupSchedule,omitempty"`

// Specify that crontab job backup both on NFS and S3 storage.
// +optional
// +kubebuilder:default:=false
BothS3NFS bool `json:"bothS3NFS,omitempty"`

// If set keeps last BackupScheduleJobsHistoryLimit Backups
// +optional
// +kubebuilder:default:=6
Expand Down
20 changes: 20 additions & 0 deletions api/v1alpha1/mysqlcluster_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ func (r *MysqlCluster) ValidateCreate() error {
if err := r.validateNFSServerAddress(r); err != nil {
return err
}

if err := r.validBothS3NFS(); err != nil {
return err
}

if err := r.validateMysqlVersionAndImage(); err != nil {
return err
}
Expand All @@ -74,6 +79,11 @@ func (r *MysqlCluster) ValidateUpdate(old runtime.Object) error {
if err := r.validateLowTableCase(oldCluster); err != nil {
return err
}

if err := r.validBothS3NFS(); err != nil {
return err
}

if err := r.validateMysqlVersionAndImage(); err != nil {
return err
}
Expand Down Expand Up @@ -145,3 +155,13 @@ func (r *MysqlCluster) validateMysqlVersionAndImage() error {
}
return nil
}

// Validate BothS3NFS
func (r *MysqlCluster) validBothS3NFS() error {
if r.Spec.BothS3NFS &&
(len(r.Spec.NFSServerAddress) == 0 || len(r.Spec.BackupSchedule) == 0 ||
len(r.Spec.BackupSecretName) == 0) {
return apierrors.NewForbidden(schema.GroupResource{}, "", fmt.Errorf("if BothS3NFS is set, backupSchedule/backupSecret/nfsAddress should not empty"))
}
return nil
}
42 changes: 33 additions & 9 deletions backup/cronbackup.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type CronJob struct {
BackupScheduleJobsHistoryLimit *int
Image string
NFSServerAddress string
BothS3NFS bool
Log logr.Logger
}

Expand All @@ -45,9 +46,9 @@ func (j *CronJob) Run() {
log.Info("at least a backup is running", "running_backups_count", j.scheduledBackupsRunningCount())
return
}

//TODO: if BothS3NFS, it need create backup without nfs address.
// create the backup
if _, err := j.createBackup(); err != nil {
if err := j.createBackups(); err != nil {
log.Error(err, "failed to create backup")
}
}
Expand Down Expand Up @@ -117,8 +118,32 @@ func (j *CronJob) backupGC() {
}
}

func (j *CronJob) createBackup() (*apiv1alpha1.Backup, error) {
backupName := fmt.Sprintf("%s-auto-%s", j.ClusterName, time.Now().Format("2006-01-02t15-04-05"))
func (j *CronJob) createBackups() error {
// Cannot use uppcase, because RFC 1123 subdomain must consist of lower case alphanumeric characters
const nfstype string = "nfs"
const s3type string = "s3"
if j.BothS3NFS { // create both.
if err := j.createOneBackup(nfstype, j.NFSServerAddress); err != nil {
return err
}
if err := j.createOneBackup(s3type, ""); err != nil {
return err
}
} else {
if len(j.NFSServerAddress) > 0 {
if err := j.createOneBackup(nfstype, j.NFSServerAddress); err != nil {
return err
}
} else {
if err := j.createOneBackup(s3type, ""); err != nil {
return err
}
}
}
return nil
}
func (j *CronJob) createOneBackup(BackupType, NFSAddress string) error {
backupName := fmt.Sprintf("%s-%s-%s", j.ClusterName, BackupType, time.Now().Format("2006-01-02t15-04-05"))

backup := &apiv1alpha1.Backup{
ObjectMeta: metav1.ObjectMeta{
Expand All @@ -131,13 +156,12 @@ func (j *CronJob) createBackup() (*apiv1alpha1.Backup, error) {
//TODO modify to cluster sidecar image
Image: j.Image,
//RemoteDeletePolicy: j.BackupRemoteDeletePolicy,
HostName: fmt.Sprintf("%s-mysql-0", j.ClusterName),
HostName: fmt.Sprintf("%s-mysql-0", j.ClusterName),
NFSServerAddress: NFSAddress,
},
}
if len(j.NFSServerAddress) > 0 {
backup.Spec.NFSServerAddress = j.NFSServerAddress
}
return backup, j.Client.Create(context.TODO(), backup)

return j.Client.Create(context.TODO(), backup)
}

type byTimestamp []apiv1alpha1.Backup
Expand Down
4 changes: 4 additions & 0 deletions config/crd/bases/mysql.radondb.com_mysqlclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ spec:
description: Represents the name of the secret that contains credentials
to connect to the storage provider to store backups.
type: string
bothS3NFS:
default: false
description: Specify that crontab job backup both on NFS and S3 storage.
type: boolean
metricsOpts:
default:
enabled: false
Expand Down
3 changes: 2 additions & 1 deletion controllers/backupcron_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ func (r *BackupCronReconciler) updateClusterSchedule(ctx context.Context, cluste
Image: cluster.Spec.PodPolicy.SidecarImage,
BackupScheduleJobsHistoryLimit: cluster.Spec.BackupScheduleJobsHistoryLimit,
//BackupRemoteDeletePolicy: cluster.Spec.BackupRemoteDeletePolicy,

// add both S3 and NFS flag.
BothS3NFS: cluster.Spec.BothS3NFS,
NFSServerAddress: cluster.Spec.NFSServerAddress,
Log: log,
}, cluster.Name)
Expand Down

0 comments on commit 08214e2

Please sign in to comment.