Skip to content

Commit

Permalink
feat: cherry-pick #5794 in Kubeblocks
Browse files Browse the repository at this point in the history
  • Loading branch information
fengluodb authored and 1aal committed Nov 12, 2023
1 parent 9c172d8 commit dfad6cf
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 72 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/Masterminds/semver/v3 v3.2.1
github.com/StudioSol/set v1.0.0
github.com/apecloud/kubebench v0.0.0-20230807061913-16124b86637f
github.com/apecloud/kubeblocks v0.8.0-alpha.1.0.20231107070923-46722a4c7d68
github.com/apecloud/kubeblocks v0.8.0-alpha.2
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
github.com/benbjohnson/clock v1.3.5
github.com/briandowns/spinner v1.23.0
Expand Down
7 changes: 3 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,8 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuW
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/apecloud/kubebench v0.0.0-20230807061913-16124b86637f h1:cQz3dMsNSlEBPl9WFxxAhPP+VAOmaWruQlEdaWwZeZY=
github.com/apecloud/kubebench v0.0.0-20230807061913-16124b86637f/go.mod h1:pk7XhTJO9+AVE0mGUGb0WfU8ME9o4s3nClyuWATMQAQ=
github.com/apecloud/kubeblocks v0.8.0-alpha.1.0.20231107070923-46722a4c7d68 h1:m6ZcHA5vBFx/mMnQe4z2wgOWcsoykPGr/A/+ilps3N8=
github.com/apecloud/kubeblocks v0.8.0-alpha.1.0.20231107070923-46722a4c7d68/go.mod h1:Ud3C32cAYI9Wqe43hebF8KrpUS45cIkiwljOG8u2Hk8=
github.com/apecloud/kubeblocks v0.8.0-alpha.2 h1:fSSP1mk2t3WiTYZe1zKAtkmwO2LEgC2Z0DF7mHELQD0=
github.com/apecloud/kubeblocks v0.8.0-alpha.2/go.mod h1:zOsApGlAbJbz12XxrZ9pHmYi+qDT85RLq5WieJLDiIs=
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
Expand Down Expand Up @@ -1372,9 +1372,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0=
github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8=
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
Expand Down
55 changes: 3 additions & 52 deletions pkg/cmd/cluster/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"regexp"
"strconv"
"strings"
"time"

"github.com/ghodss/yaml"
"github.com/robfig/cron/v3"
Expand All @@ -57,6 +56,7 @@ import (

"github.com/apecloud/kubeblocks/pkg/class"
"github.com/apecloud/kubeblocks/pkg/constant"
"github.com/apecloud/kubeblocks/pkg/dataprotection/restore"
dptypes "github.com/apecloud/kubeblocks/pkg/dataprotection/types"
"github.com/apecloud/kubeblocks/pkg/dataprotection/utils/boolptr"
viper "github.com/apecloud/kubeblocks/pkg/viperx"
Expand Down Expand Up @@ -326,32 +326,6 @@ func setMonitor(monitoringInterval uint8, components []map[string]interface{}) {
}
}

func getRestoreFromBackupAnnotation(backup *dpv1alpha1.Backup, volumeRestorePolicy string, compSpecsCount int, firstCompName string, restoreTime string) (string, error) {
componentName := backup.Labels[constant.KBAppComponentLabelKey]
if len(componentName) == 0 {
if compSpecsCount != 1 {
return "", fmt.Errorf("unable to obtain the name of the component to be recovered, please ensure that Backup.status.componentName exists")
}
componentName = firstCompName
}
backupNameString := fmt.Sprintf(`"%s":"%s"`, constant.BackupNameKeyForRestore, backup.Name)
backupNamespaceString := fmt.Sprintf(`"%s":"%s"`, constant.BackupNamespaceKeyForRestore, backup.Namespace)
volumeRestorePolicyString := fmt.Sprintf(`"%s":"%s"`, constant.VolumeRestorePolicyKeyForRestore, volumeRestorePolicy)
var restoreTimeString string
if restoreTime != "" {
restoreTimeString = fmt.Sprintf(`,"%s":"%s"`, constant.RestoreTimeKeyForRestore, restoreTime)
}

var passwordString string
connectionPassword := backup.Annotations[dptypes.ConnectionPasswordKey]
if connectionPassword != "" {
passwordString = fmt.Sprintf(`,"%s":"%s"`, constant.ConnectionPassword, connectionPassword)
}

restoreFromBackupAnnotation := fmt.Sprintf(`{"%s":{%s,%s,%s%s%s}}`, componentName, backupNameString, backupNamespaceString, volumeRestorePolicyString, restoreTimeString, passwordString)
return restoreFromBackupAnnotation, nil
}

func getSourceClusterFromBackup(backup *dpv1alpha1.Backup) (*appsv1alpha1.Cluster, error) {
sourceCluster := &appsv1alpha1.Cluster{}
sourceClusterJSON := backup.Annotations[constant.ClusterSnapshotAnnotationKey]
Expand Down Expand Up @@ -406,29 +380,6 @@ func fillClusterInfoFromBackup(o *CreateOptions, cls **appsv1alpha1.Cluster) err
return nil
}

func formatRestoreTimeAndValidate(restoreTimeStr string, continuousBackup *dpv1alpha1.Backup) (string, error) {
if restoreTimeStr == "" {
return restoreTimeStr, nil
}
restoreTime, err := util.TimeParse(restoreTimeStr, time.Second)
if err != nil {
// retry to parse time with RFC3339 format.
var errRFC error
restoreTime, errRFC = time.Parse(time.RFC3339, restoreTimeStr)
if errRFC != nil {
// if retry failure, report the error
return restoreTimeStr, err
}
}
restoreTimeStr = restoreTime.Format(time.RFC3339)
// TODO: check with Recoverable time
if !isTimeInRange(restoreTime, continuousBackup.Status.TimeRange.Start.Time, continuousBackup.Status.TimeRange.End.Time) {
return restoreTimeStr, fmt.Errorf("restore-to-time is out of time range, you can view the recoverable time: \n"+
"\tkbcli cluster describe %s -n %s", continuousBackup.Labels[constant.AppInstanceLabelKey], continuousBackup.Namespace)
}
return restoreTimeStr, nil
}

func setBackup(o *CreateOptions, components []map[string]interface{}) error {
backupName := o.Backup
if len(backupName) == 0 || len(components) == 0 {
Expand All @@ -441,11 +392,11 @@ func setBackup(o *CreateOptions, components []map[string]interface{}) error {
if backup.Status.Phase != dpv1alpha1.BackupPhaseCompleted {
return fmt.Errorf(`backup "%s" is not completed`, backup.Name)
}
restoreTimeStr, err := formatRestoreTimeAndValidate(o.RestoreTime, backup)
restoreTimeStr, err := restore.FormatRestoreTimeAndValidate(o.RestoreTime, backup)
if err != nil {
return err
}
restoreAnnotation, err := getRestoreFromBackupAnnotation(backup, o.VolumeRestorePolicy, len(components), components[0]["name"].(string), restoreTimeStr)
restoreAnnotation, err := restore.GetRestoreFromBackupAnnotation(backup, o.VolumeRestorePolicy, len(components), components[0]["name"].(string), restoreTimeStr)
if err != nil {
return err
}
Expand Down
26 changes: 11 additions & 15 deletions pkg/cmd/cluster/dataprotection.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import (
appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1"
dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1"
"github.com/apecloud/kubeblocks/pkg/constant"
"github.com/apecloud/kubeblocks/pkg/dataprotection/restore"
dptypes "github.com/apecloud/kubeblocks/pkg/dataprotection/types"

"github.com/apecloud/kbcli/pkg/cluster"
Expand Down Expand Up @@ -520,15 +521,14 @@ type CreateRestoreOptions struct {
func (o *CreateRestoreOptions) getClusterObject(backup *dpv1alpha1.Backup) (*appsv1alpha1.Cluster, error) {
// use the cluster snapshot to restore firstly
clusterString, ok := backup.Annotations[constant.ClusterSnapshotAnnotationKey]
if ok {
clusterObj := &appsv1alpha1.Cluster{}
if err := json.Unmarshal([]byte(clusterString), &clusterObj); err != nil {
return nil, err
}
return clusterObj, nil
if !ok {
return nil, fmt.Errorf("missing snapshot annotation in backup %s, %s is empty in Annotations", backup.Name, constant.ClusterSnapshotAnnotationKey)
}
clusterObj := &appsv1alpha1.Cluster{}
if err := json.Unmarshal([]byte(clusterString), &clusterObj); err != nil {
return nil, err
}
clusterName := backup.Labels[constant.AppInstanceLabelKey]
return cluster.GetClusterByName(o.Dynamic, clusterName, o.Namespace)
return clusterObj, nil
}

func (o *CreateRestoreOptions) Run() error {
Expand All @@ -551,7 +551,7 @@ func (o *CreateRestoreOptions) runRestoreFromBackup() error {
return errors.Errorf(`missing source cluster in backup "%s", "app.kubernetes.io/instance" is empty in labels.`, o.Backup)
}

restoreTimeStr, err := formatRestoreTimeAndValidate(o.RestoreTimeStr, backup)
restoreTimeStr, err := restore.FormatRestoreTimeAndValidate(o.RestoreTimeStr, backup)
if err != nil {
return err
}
Expand All @@ -560,7 +560,7 @@ func (o *CreateRestoreOptions) runRestoreFromBackup() error {
if err != nil {
return err
}
restoreAnnotation, err := getRestoreFromBackupAnnotation(backup, o.VolumeRestorePolicy, len(clusterObj.Spec.ComponentSpecs), clusterObj.Spec.ComponentSpecs[0].Name, restoreTimeStr)
restoreAnnotation, err := restore.GetRestoreFromBackupAnnotation(backup, o.VolumeRestorePolicy, len(clusterObj.Spec.ComponentSpecs), clusterObj.Spec.ComponentSpecs[0].Name, restoreTimeStr)
if err != nil {
return err
}
Expand All @@ -577,7 +577,7 @@ func (o *CreateRestoreOptions) createCluster(cluster *appsv1alpha1.Cluster) erro
cluster.Status = appsv1alpha1.ClusterStatus{}
cluster.TypeMeta = metav1.TypeMeta{
Kind: types.KindCluster,
APIVersion: clusterGVR.Group + "/" + clusterGVR.Version,
APIVersion: clusterGVR.GroupVersion().String(),
}
// convert the cluster object and create it.
unstructuredMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&cluster)
Expand All @@ -594,10 +594,6 @@ func (o *CreateRestoreOptions) createCluster(cluster *appsv1alpha1.Cluster) erro
return nil
}

func isTimeInRange(t time.Time, start time.Time, end time.Time) bool {
return !t.Before(start) && !t.After(end)
}

func (o *CreateRestoreOptions) Validate() error {
if o.Backup == "" {
return fmt.Errorf("must be specified one of the --backup ")
Expand Down

0 comments on commit dfad6cf

Please sign in to comment.