From ec03a6eebda60505303d5bb377cc60691efbb597 Mon Sep 17 00:00:00 2001
From: wency <57141858+chiwency@users.noreply.github.com>
Date: Thu, 19 Sep 2024 11:37:15 +0800
Subject: [PATCH] feat: redis-restore-by-keys (#8129)
---
apis/apps/v1alpha1/opsrequest_types.go | 6 +
apis/apps/v1alpha1/zz_generated.deepcopy.go | 11 +-
.../bases/apps.kubeblocks.io_opsrequests.yaml | 232 ++++++++++++++++++
controllers/apps/operations/restore.go | 2 +-
.../crds/apps.kubeblocks.io_opsrequests.yaml | 232 ++++++++++++++++++
docs/developer_docs/api-reference/cluster.md | 14 ++
pkg/controller/plan/restore.go | 8 +
pkg/dataprotection/restore/utils.go | 10 +-
8 files changed, 511 insertions(+), 4 deletions(-)
diff --git a/apis/apps/v1alpha1/opsrequest_types.go b/apis/apps/v1alpha1/opsrequest_types.go
index 97298c98e59..dd9dcc9ad55 100644
--- a/apis/apps/v1alpha1/opsrequest_types.go
+++ b/apis/apps/v1alpha1/opsrequest_types.go
@@ -931,6 +931,12 @@ type Restore struct {
//
RestorePointInTime string `json:"restorePointInTime,omitempty"`
+ // Specifies a list of environment variables to be set in the container.
+ //
+ // +kubebuilder:pruning:PreserveUnknownFields
+ // +optional
+ Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
+
// Specifies the policy for restoring volume claims of a Component's Pods.
// It determines whether the volume claims should be restored sequentially (one by one) or in parallel (all at once).
// Support values:
diff --git a/apis/apps/v1alpha1/zz_generated.deepcopy.go b/apis/apps/v1alpha1/zz_generated.deepcopy.go
index 626ac3e012a..3fdaf51cae4 100644
--- a/apis/apps/v1alpha1/zz_generated.deepcopy.go
+++ b/apis/apps/v1alpha1/zz_generated.deepcopy.go
@@ -5047,6 +5047,13 @@ func (in *ResourceMeta) DeepCopy() *ResourceMeta {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Restore) DeepCopyInto(out *Restore) {
*out = *in
+ if in.Env != nil {
+ in, out := &in.Env, &out.Env
+ *out = make([]v1.EnvVar, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Restore.
@@ -5719,12 +5726,12 @@ func (in *SpecificOpsRequest) DeepCopyInto(out *SpecificOpsRequest) {
if in.Restore != nil {
in, out := &in.Restore, &out.Restore
*out = new(Restore)
- **out = **in
+ (*in).DeepCopyInto(*out)
}
if in.RestoreSpec != nil {
in, out := &in.RestoreSpec, &out.RestoreSpec
*out = new(Restore)
- **out = **in
+ (*in).DeepCopyInto(*out)
}
if in.RebuildFrom != nil {
in, out := &in.RebuildFrom, &out.RebuildFrom
diff --git a/config/crd/bases/apps.kubeblocks.io_opsrequests.yaml b/config/crd/bases/apps.kubeblocks.io_opsrequests.yaml
index e1dc71b8afa..4c51f5d712a 100644
--- a/config/crd/bases/apps.kubeblocks.io_opsrequests.yaml
+++ b/config/crd/bases/apps.kubeblocks.io_opsrequests.yaml
@@ -4402,6 +4402,122 @@ spec:
This setting is useful for coordinating PostReady operations across the Cluster for optimal cluster conditions.
type: boolean
+ env:
+ description: Specifies a list of environment variables to be set
+ in the container.
+ items:
+ description: EnvVar represents an environment variable present
+ in a Container.
+ properties:
+ name:
+ description: Name of the environment variable. Must be a
+ C_IDENTIFIER.
+ type: string
+ value:
+ description: |-
+ Variable references $(VAR_NAME) are expanded
+ using the previously defined environment variables in the container and
+ any service environment variables. If a variable cannot be resolved,
+ the reference in the input string will be unchanged. Double $$ are reduced
+ to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
+ "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
+ Escaped references will never be expanded, regardless of whether the variable
+ exists or not.
+ Defaults to "".
+ type: string
+ valueFrom:
+ description: Source for the environment variable's value.
+ Cannot be used if value is not empty.
+ properties:
+ configMapKeyRef:
+ description: Selects a key of a ConfigMap.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: |-
+ Name of the referent.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ fieldRef:
+ description: |-
+ Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`,
+ spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
+ properties:
+ apiVersion:
+ description: Version of the schema the FieldPath
+ is written in terms of, defaults to "v1".
+ type: string
+ fieldPath:
+ description: Path of the field to select in the
+ specified API version.
+ type: string
+ required:
+ - fieldPath
+ type: object
+ x-kubernetes-map-type: atomic
+ resourceFieldRef:
+ description: |-
+ Selects a resource of the container: only resources limits and requests
+ (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
+ properties:
+ containerName:
+ description: 'Container name: required for volumes,
+ optional for env vars'
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Specifies the output format of the
+ exposed resources, defaults to "1"
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ description: 'Required: resource to select'
+ type: string
+ required:
+ - resource
+ type: object
+ x-kubernetes-map-type: atomic
+ secretKeyRef:
+ description: Selects a key of a secret in the pod's
+ namespace
+ properties:
+ key:
+ description: The key of the secret to select from. Must
+ be a valid secret key.
+ type: string
+ name:
+ description: |-
+ Name of the referent.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ type: object
+ required:
+ - name
+ type: object
+ type: array
+ x-kubernetes-preserve-unknown-fields: true
restorePointInTime:
description: |-
Specifies the point in time to which the restore should be performed.
@@ -4449,6 +4565,122 @@ spec:
This setting is useful for coordinating PostReady operations across the Cluster for optimal cluster conditions.
type: boolean
+ env:
+ description: Specifies a list of environment variables to be set
+ in the container.
+ items:
+ description: EnvVar represents an environment variable present
+ in a Container.
+ properties:
+ name:
+ description: Name of the environment variable. Must be a
+ C_IDENTIFIER.
+ type: string
+ value:
+ description: |-
+ Variable references $(VAR_NAME) are expanded
+ using the previously defined environment variables in the container and
+ any service environment variables. If a variable cannot be resolved,
+ the reference in the input string will be unchanged. Double $$ are reduced
+ to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
+ "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
+ Escaped references will never be expanded, regardless of whether the variable
+ exists or not.
+ Defaults to "".
+ type: string
+ valueFrom:
+ description: Source for the environment variable's value.
+ Cannot be used if value is not empty.
+ properties:
+ configMapKeyRef:
+ description: Selects a key of a ConfigMap.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: |-
+ Name of the referent.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ fieldRef:
+ description: |-
+ Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`,
+ spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
+ properties:
+ apiVersion:
+ description: Version of the schema the FieldPath
+ is written in terms of, defaults to "v1".
+ type: string
+ fieldPath:
+ description: Path of the field to select in the
+ specified API version.
+ type: string
+ required:
+ - fieldPath
+ type: object
+ x-kubernetes-map-type: atomic
+ resourceFieldRef:
+ description: |-
+ Selects a resource of the container: only resources limits and requests
+ (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
+ properties:
+ containerName:
+ description: 'Container name: required for volumes,
+ optional for env vars'
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Specifies the output format of the
+ exposed resources, defaults to "1"
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ description: 'Required: resource to select'
+ type: string
+ required:
+ - resource
+ type: object
+ x-kubernetes-map-type: atomic
+ secretKeyRef:
+ description: Selects a key of a secret in the pod's
+ namespace
+ properties:
+ key:
+ description: The key of the secret to select from. Must
+ be a valid secret key.
+ type: string
+ name:
+ description: |-
+ Name of the referent.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ type: object
+ required:
+ - name
+ type: object
+ type: array
+ x-kubernetes-preserve-unknown-fields: true
restorePointInTime:
description: |-
Specifies the point in time to which the restore should be performed.
diff --git a/controllers/apps/operations/restore.go b/controllers/apps/operations/restore.go
index a514cb1c45b..10e89378346 100644
--- a/controllers/apps/operations/restore.go
+++ b/controllers/apps/operations/restore.go
@@ -189,7 +189,7 @@ func (r RestoreOpsHandler) getClusterObjFromBackup(backup *dpv1alpha1.Backup, op
}
restoreSpec := opsRequest.Spec.GetRestore()
// set the restore annotation to cluster
- restoreAnnotation, err := restore.GetRestoreFromBackupAnnotation(backup, restoreSpec.VolumeRestorePolicy, restoreSpec.RestorePointInTime, restoreSpec.DeferPostReadyUntilClusterRunning)
+ restoreAnnotation, err := restore.GetRestoreFromBackupAnnotation(backup, restoreSpec.VolumeRestorePolicy, restoreSpec.RestorePointInTime, restoreSpec.Env, restoreSpec.DeferPostReadyUntilClusterRunning)
if err != nil {
return nil, err
}
diff --git a/deploy/helm/crds/apps.kubeblocks.io_opsrequests.yaml b/deploy/helm/crds/apps.kubeblocks.io_opsrequests.yaml
index e1dc71b8afa..4c51f5d712a 100644
--- a/deploy/helm/crds/apps.kubeblocks.io_opsrequests.yaml
+++ b/deploy/helm/crds/apps.kubeblocks.io_opsrequests.yaml
@@ -4402,6 +4402,122 @@ spec:
This setting is useful for coordinating PostReady operations across the Cluster for optimal cluster conditions.
type: boolean
+ env:
+ description: Specifies a list of environment variables to be set
+ in the container.
+ items:
+ description: EnvVar represents an environment variable present
+ in a Container.
+ properties:
+ name:
+ description: Name of the environment variable. Must be a
+ C_IDENTIFIER.
+ type: string
+ value:
+ description: |-
+ Variable references $(VAR_NAME) are expanded
+ using the previously defined environment variables in the container and
+ any service environment variables. If a variable cannot be resolved,
+ the reference in the input string will be unchanged. Double $$ are reduced
+ to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
+ "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
+ Escaped references will never be expanded, regardless of whether the variable
+ exists or not.
+ Defaults to "".
+ type: string
+ valueFrom:
+ description: Source for the environment variable's value.
+ Cannot be used if value is not empty.
+ properties:
+ configMapKeyRef:
+ description: Selects a key of a ConfigMap.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: |-
+ Name of the referent.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ fieldRef:
+ description: |-
+ Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`,
+ spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
+ properties:
+ apiVersion:
+ description: Version of the schema the FieldPath
+ is written in terms of, defaults to "v1".
+ type: string
+ fieldPath:
+ description: Path of the field to select in the
+ specified API version.
+ type: string
+ required:
+ - fieldPath
+ type: object
+ x-kubernetes-map-type: atomic
+ resourceFieldRef:
+ description: |-
+ Selects a resource of the container: only resources limits and requests
+ (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
+ properties:
+ containerName:
+ description: 'Container name: required for volumes,
+ optional for env vars'
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Specifies the output format of the
+ exposed resources, defaults to "1"
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ description: 'Required: resource to select'
+ type: string
+ required:
+ - resource
+ type: object
+ x-kubernetes-map-type: atomic
+ secretKeyRef:
+ description: Selects a key of a secret in the pod's
+ namespace
+ properties:
+ key:
+ description: The key of the secret to select from. Must
+ be a valid secret key.
+ type: string
+ name:
+ description: |-
+ Name of the referent.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ type: object
+ required:
+ - name
+ type: object
+ type: array
+ x-kubernetes-preserve-unknown-fields: true
restorePointInTime:
description: |-
Specifies the point in time to which the restore should be performed.
@@ -4449,6 +4565,122 @@ spec:
This setting is useful for coordinating PostReady operations across the Cluster for optimal cluster conditions.
type: boolean
+ env:
+ description: Specifies a list of environment variables to be set
+ in the container.
+ items:
+ description: EnvVar represents an environment variable present
+ in a Container.
+ properties:
+ name:
+ description: Name of the environment variable. Must be a
+ C_IDENTIFIER.
+ type: string
+ value:
+ description: |-
+ Variable references $(VAR_NAME) are expanded
+ using the previously defined environment variables in the container and
+ any service environment variables. If a variable cannot be resolved,
+ the reference in the input string will be unchanged. Double $$ are reduced
+ to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
+ "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
+ Escaped references will never be expanded, regardless of whether the variable
+ exists or not.
+ Defaults to "".
+ type: string
+ valueFrom:
+ description: Source for the environment variable's value.
+ Cannot be used if value is not empty.
+ properties:
+ configMapKeyRef:
+ description: Selects a key of a ConfigMap.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: |-
+ Name of the referent.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ fieldRef:
+ description: |-
+ Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`,
+ spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
+ properties:
+ apiVersion:
+ description: Version of the schema the FieldPath
+ is written in terms of, defaults to "v1".
+ type: string
+ fieldPath:
+ description: Path of the field to select in the
+ specified API version.
+ type: string
+ required:
+ - fieldPath
+ type: object
+ x-kubernetes-map-type: atomic
+ resourceFieldRef:
+ description: |-
+ Selects a resource of the container: only resources limits and requests
+ (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
+ properties:
+ containerName:
+ description: 'Container name: required for volumes,
+ optional for env vars'
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Specifies the output format of the
+ exposed resources, defaults to "1"
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ description: 'Required: resource to select'
+ type: string
+ required:
+ - resource
+ type: object
+ x-kubernetes-map-type: atomic
+ secretKeyRef:
+ description: Selects a key of a secret in the pod's
+ namespace
+ properties:
+ key:
+ description: The key of the secret to select from. Must
+ be a valid secret key.
+ type: string
+ name:
+ description: |-
+ Name of the referent.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ type: object
+ required:
+ - name
+ type: object
+ type: array
+ x-kubernetes-preserve-unknown-fields: true
restorePointInTime:
description: |-
Specifies the point in time to which the restore should be performed.
diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md
index 80e00b8d380..6cfdeea5b15 100644
--- a/docs/developer_docs/api-reference/cluster.md
+++ b/docs/developer_docs/api-reference/cluster.md
@@ -27477,6 +27477,20 @@ Supported time formats:
+env
+
+
+[]Kubernetes core/v1.EnvVar
+
+
+ |
+
+(Optional)
+ Specifies a list of environment variables to be set in the container.
+ |
+
+
+
volumeRestorePolicy
string
diff --git a/pkg/controller/plan/restore.go b/pkg/controller/plan/restore.go
index e76b0455271..6bee1974fb1 100644
--- a/pkg/controller/plan/restore.go
+++ b/pkg/controller/plan/restore.go
@@ -56,6 +56,7 @@ type RestoreManager struct {
// private
namespace string
restoreTime string
+ env []corev1.EnvVar
volumeRestorePolicy dpv1alpha1.VolumeClaimRestorePolicy
doReadyRestoreAfterClusterRunning bool
startingIndex int32
@@ -224,6 +225,7 @@ func (r *RestoreManager) BuildPrepareDataRestore(comp *component.SynthesizedComp
SourceTargetName: sourceTargetName,
},
RestoreTime: r.restoreTime,
+ Env: r.env,
PrepareDataConfig: &dpv1alpha1.PrepareDataConfig{
RequiredPolicyForAllPodSelection: r.buildRequiredPolicy(sourceTarget),
SchedulingSpec: schedulingSpec,
@@ -256,6 +258,7 @@ func (r *RestoreManager) DoPostReady(comp *component.SynthesizedComponent,
SourceTargetName: sourceTargetName,
},
RestoreTime: r.restoreTime,
+ Env: r.env,
ReadyConfig: &dpv1alpha1.ReadyConfig{
ExecAction: &dpv1alpha1.ExecAction{
Target: dpv1alpha1.ExecActionTarget{
@@ -366,6 +369,11 @@ func (r *RestoreManager) initFromAnnotation(synthesizedComponent *component.Synt
if doReadyRestoreAfterClusterRunning == "true" {
r.doReadyRestoreAfterClusterRunning = true
}
+ if env := backupSource[constant.EnvForRestore]; env != "" {
+ if err = json.Unmarshal([]byte(env), &r.env); err != nil {
+ return nil, err
+ }
+ }
return GetBackupFromClusterAnnotation(r.Ctx, r.Client, backupSource, synthesizedComponent.Name, r.Cluster.Namespace)
}
diff --git a/pkg/dataprotection/restore/utils.go b/pkg/dataprotection/restore/utils.go
index 12ce4872440..3feabede308 100644
--- a/pkg/dataprotection/restore/utils.go
+++ b/pkg/dataprotection/restore/utils.go
@@ -321,7 +321,7 @@ func isTimeInRange(t time.Time, start time.Time, end time.Time) bool {
return !t.Before(start) && !t.After(end)
}
-func GetRestoreFromBackupAnnotation(backup *dpv1alpha1.Backup, volumeRestorePolicy, restoreTime string, doReadyRestoreAfterClusterRunning bool) (string, error) {
+func GetRestoreFromBackupAnnotation(backup *dpv1alpha1.Backup, volumeRestorePolicy, restoreTime string, env []corev1.EnvVar, doReadyRestoreAfterClusterRunning bool) (string, error) {
componentName := backup.Labels[constant.KBAppShardingNameLabelKey]
if len(componentName) == 0 {
componentName = backup.Labels[constant.KBAppComponentLabelKey]
@@ -337,6 +337,14 @@ func GetRestoreFromBackupAnnotation(backup *dpv1alpha1.Backup, volumeRestorePoli
if restoreTime != "" {
restoreInfoMap[constant.RestoreTimeKeyForRestore] = restoreTime
}
+ if env != nil {
+ bytes, err := json.Marshal(env)
+ if err != nil {
+ return "", err
+ }
+ restoreInfoMap[constant.EnvForRestore] = string(bytes)
+ }
+
connectionPassword := backup.Annotations[dptypes.ConnectionPasswordAnnotationKey]
if connectionPassword != "" {
restoreInfoMap[constant.ConnectionPassword] = connectionPassword
|