mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-08-21 14:46:07 +00:00
Full backup for all data movers (#10185)
* support full backup for fs data mover Signed-off-by: Lyndon-Li <lyonghui@vmware.com> * full backup for PVB Signed-off-by: Lyndon-Li <lyonghui@vmware.com> * full backup for all data movers Signed-off-by: Lyndon-Li <lyonghui@vmware.com> * fix UT error Signed-off-by: Lyndon-Li <lyonghui@vmware.com> --------- Signed-off-by: Lyndon-Li <lyonghui@vmware.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Support full backup for file system data mover and pod volume backup
|
||||
@@ -96,6 +96,13 @@ spec:
|
||||
description: Node is the name of the node that the Pod is running
|
||||
on.
|
||||
type: string
|
||||
parentSnapshot:
|
||||
description: |-
|
||||
ParentSnapshot specifies the parent snapshot that current backup is based on.
|
||||
If its value is "" or "auto", the data mover finds the recent backup of the same volume as parent.
|
||||
If its value is "none", the data mover will do a full backup
|
||||
If its value is a specific snapshotID, the data mover finds the specific snapshot as parent.
|
||||
type: string
|
||||
pod:
|
||||
description: Pod is a reference to the pod containing the volume to
|
||||
be backed up.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -17,6 +17,6 @@ limitations under the License.
|
||||
package shared
|
||||
|
||||
const (
|
||||
DataUploadParentSnapshotNone = "none"
|
||||
DataUploadParentSnapshotAuto = "auto"
|
||||
ParentSnapshotNone = "none"
|
||||
ParentSnapshotAuto = "auto"
|
||||
)
|
||||
|
||||
@@ -61,6 +61,12 @@ type PodVolumeBackupSpec struct {
|
||||
// Cancel indicates request to cancel the ongoing PodVolumeBackup. It can be set
|
||||
// when the PodVolumeBackup is in InProgress phase
|
||||
Cancel bool `json:"cancel,omitempty"`
|
||||
|
||||
// ParentSnapshot specifies the parent snapshot that current backup is based on.
|
||||
// If its value is "" or "auto", the data mover finds the recent backup of the same volume as parent.
|
||||
// If its value is "none", the data mover will do a full backup
|
||||
// If its value is a specific snapshotID, the data mover finds the specific snapshot as parent.
|
||||
ParentSnapshot string `json:"parentSnapshot,omitempty"`
|
||||
}
|
||||
|
||||
// PodVolumeBackupPhase represents the lifecycle phase of a PodVolumeBackup.
|
||||
|
||||
@@ -569,7 +569,7 @@ func newDataUpload(
|
||||
parentSnapshot := ""
|
||||
|
||||
if backup.Spec.BackupType == velerov1api.BackupTypeFull {
|
||||
parentSnapshot = veleroshared.DataUploadParentSnapshotNone
|
||||
parentSnapshot = veleroshared.ParentSnapshotNone
|
||||
}
|
||||
|
||||
dataMover := backup.Spec.DataMover
|
||||
|
||||
@@ -184,7 +184,7 @@ func (r *BackupMicroService) RunCancelableDataPath(ctx context.Context) (string,
|
||||
return "", errors.Wrap(err, "error to create data path")
|
||||
}
|
||||
|
||||
log.Debug("Async fs br created")
|
||||
log.Debug("Async br created")
|
||||
|
||||
if err := dp.Init(ctx, &datapath.InitParam{
|
||||
BSLName: du.Spec.BackupStorageLocation,
|
||||
@@ -198,7 +198,7 @@ func (r *BackupMicroService) RunCancelableDataPath(ctx context.Context) (string,
|
||||
return "", errors.Wrap(err, "error to initialize data path")
|
||||
}
|
||||
|
||||
log.Info("Async fs br init")
|
||||
log.Info("Async br init")
|
||||
|
||||
tags := map[string]string{
|
||||
velerov1api.AsyncOperationIDLabel: du.Labels[velerov1api.AsyncOperationIDLabel],
|
||||
@@ -207,7 +207,7 @@ func (r *BackupMicroService) RunCancelableDataPath(ctx context.Context) (string,
|
||||
// Modify the ParentSnapshot to "" and ForceFull to true when ParentSnapshot is "none".
|
||||
parentSnapshot := du.Spec.ParentSnapshot
|
||||
forceFull := false
|
||||
if du.Spec.ParentSnapshot == veleroshared.DataUploadParentSnapshotNone {
|
||||
if du.Spec.ParentSnapshot == veleroshared.ParentSnapshotNone {
|
||||
parentSnapshot = ""
|
||||
forceFull = true
|
||||
}
|
||||
@@ -231,7 +231,7 @@ func (r *BackupMicroService) RunCancelableDataPath(ctx context.Context) (string,
|
||||
result := ""
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
err = errors.New("timed out waiting for fs backup to complete")
|
||||
err = errors.New("timed out waiting for backup to complete")
|
||||
break
|
||||
case res := <-r.resultSignal:
|
||||
err = res.err
|
||||
@@ -315,9 +315,9 @@ func (r *BackupMicroService) OnDataUploadProgress(ctx context.Context, namespace
|
||||
}
|
||||
|
||||
func (r *BackupMicroService) closeDataPath(ctx context.Context, duName string) {
|
||||
fsBackup := r.dataPathMgr.GetAsyncBR(duName)
|
||||
if fsBackup != nil {
|
||||
fsBackup.Close(ctx)
|
||||
asyncBR := r.dataPathMgr.GetAsyncBR(duName)
|
||||
if asyncBR != nil {
|
||||
asyncBR.Close(ctx)
|
||||
}
|
||||
|
||||
r.dataPathMgr.RemoveAsyncBR(duName)
|
||||
@@ -328,11 +328,11 @@ func (r *BackupMicroService) cancelDataUpload(du *velerov2alpha1api.DataUpload)
|
||||
|
||||
r.eventRecorder.Event(du, false, datapath.EventReasonCancelling, "Canceling for data upload %s", du.Name)
|
||||
|
||||
fsBackup := r.dataPathMgr.GetAsyncBR(du.Name)
|
||||
if fsBackup == nil {
|
||||
asyncBR := r.dataPathMgr.GetAsyncBR(du.Name)
|
||||
if asyncBR == nil {
|
||||
r.OnDataUploadCancelled(r.ctx, du.GetNamespace(), du.GetName())
|
||||
r.eventRecorder.EndingEvent(du, false, datapath.EventReasonStopped, "Data path for %s exited without start", du.Name)
|
||||
} else {
|
||||
fsBackup.Cancel()
|
||||
asyncBR.Cancel()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ func TestRunCancelableDataPath(t *testing.T) {
|
||||
kubeClientObj: []runtime.Object{duInProgress},
|
||||
dataPathStarted: true,
|
||||
expectedEventMsg: fmt.Sprintf("Data path for %s stopped", dataUploadName),
|
||||
expectedErr: "timed out waiting for fs backup to complete",
|
||||
expectedErr: "timed out waiting for backup to complete",
|
||||
},
|
||||
{
|
||||
name: "data path returns error",
|
||||
|
||||
@@ -178,7 +178,7 @@ func (r *RestoreMicroService) RunCancelableDataPath(ctx context.Context) (string
|
||||
}); err != nil {
|
||||
return "", errors.Wrap(err, "error to initialize data path")
|
||||
}
|
||||
log.Info("fs init")
|
||||
log.Info("Async br init")
|
||||
|
||||
if err := dp.StartRestore(dd.Spec.SnapshotID, r.sourceTargetPath, dd.Spec.DataMoverConfig, &datapath.RestoreStartParam{}); err != nil {
|
||||
return "", errors.Wrap(err, "error starting data path restore")
|
||||
@@ -190,7 +190,7 @@ func (r *RestoreMicroService) RunCancelableDataPath(ctx context.Context) (string
|
||||
result := ""
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
err = errors.New("timed out waiting for fs restore to complete")
|
||||
err = errors.New("timed out waiting for restore to complete")
|
||||
break
|
||||
case res := <-r.resultSignal:
|
||||
err = res.err
|
||||
@@ -199,7 +199,7 @@ func (r *RestoreMicroService) RunCancelableDataPath(ctx context.Context) (string
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Async fs restore was not completed")
|
||||
log.WithError(err).Error("Async restore was not completed")
|
||||
}
|
||||
|
||||
r.eventRecorder.EndingEvent(dd, false, datapath.EventReasonStopped, "Data path for %s stopped", dd.Name)
|
||||
@@ -272,9 +272,9 @@ func (r *RestoreMicroService) OnDataDownloadProgress(ctx context.Context, namesp
|
||||
}
|
||||
|
||||
func (r *RestoreMicroService) closeDataPath(ctx context.Context, ddName string) {
|
||||
fsRestore := r.dataPathMgr.GetAsyncBR(ddName)
|
||||
if fsRestore != nil {
|
||||
fsRestore.Close(ctx)
|
||||
asyncBR := r.dataPathMgr.GetAsyncBR(ddName)
|
||||
if asyncBR != nil {
|
||||
asyncBR.Close(ctx)
|
||||
}
|
||||
|
||||
r.dataPathMgr.RemoveAsyncBR(ddName)
|
||||
@@ -285,11 +285,11 @@ func (r *RestoreMicroService) cancelDataDownload(dd *velerov2alpha1api.DataDownl
|
||||
|
||||
r.eventRecorder.Event(dd, false, datapath.EventReasonCancelling, "Canceling for data download %s", dd.Name)
|
||||
|
||||
fsBackup := r.dataPathMgr.GetAsyncBR(dd.Name)
|
||||
if fsBackup == nil {
|
||||
asyncBR := r.dataPathMgr.GetAsyncBR(dd.Name)
|
||||
if asyncBR == nil {
|
||||
r.OnDataDownloadCancelled(r.ctx, dd.GetNamespace(), dd.GetName())
|
||||
r.eventRecorder.EndingEvent(dd, false, datapath.EventReasonStopped, "Data path for %s exited without start", dd.Name)
|
||||
} else {
|
||||
fsBackup.Cancel()
|
||||
asyncBR.Cancel()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ func TestRunCancelableRestore(t *testing.T) {
|
||||
kubeClientObj: []runtime.Object{ddInProgress},
|
||||
dataPathStarted: true,
|
||||
expectedEventMsg: fmt.Sprintf("Data path for %s stopped", dataDownloadName),
|
||||
expectedErr: "timed out waiting for fs restore to complete",
|
||||
expectedErr: "timed out waiting for restore to complete",
|
||||
},
|
||||
{
|
||||
name: "data path returns error",
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/credentials"
|
||||
veleroshared "github.com/vmware-tanzu/velero/pkg/apis/velero/shared"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/datapath"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
@@ -192,10 +193,18 @@ func (r *BackupMicroService) RunCancelableDataPath(ctx context.Context) (string,
|
||||
|
||||
tags := map[string]string{}
|
||||
|
||||
// Modify the ParentSnapshot to "" and ForceFull to true when ParentSnapshot is "none".
|
||||
parentSnapshot := pvb.Spec.ParentSnapshot
|
||||
forceFull := false
|
||||
if pvb.Spec.ParentSnapshot == veleroshared.ParentSnapshotNone {
|
||||
parentSnapshot = ""
|
||||
forceFull = true
|
||||
}
|
||||
|
||||
if err := fsBackup.StartBackup(r.sourceTargetPath, pvb.Spec.UploaderSettings, &datapath.BackupStartParam{
|
||||
RealSource: GetRealSource(pvb),
|
||||
ParentSnapshot: "",
|
||||
ForceFull: false,
|
||||
ParentSnapshot: parentSnapshot,
|
||||
ForceFull: forceFull,
|
||||
Tags: tags,
|
||||
}); err != nil {
|
||||
return "", errors.Wrap(err, "error starting data path backup")
|
||||
|
||||
@@ -34,6 +34,7 @@ import (
|
||||
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/resourcepolicies"
|
||||
veleroshared "github.com/vmware-tanzu/velero/pkg/apis/velero/shared"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
veleroclient "github.com/vmware-tanzu/velero/pkg/client"
|
||||
"github.com/vmware-tanzu/velero/pkg/label"
|
||||
@@ -598,5 +599,9 @@ func newPodVolumeBackup(backup *velerov1api.Backup, pod *corev1api.Pod, volume c
|
||||
pvb.Spec.UploaderSettings = uploaderutil.StoreBackupConfig(backup.Spec.UploaderConfig)
|
||||
}
|
||||
|
||||
if backup.Spec.BackupType == velerov1api.BackupTypeFull {
|
||||
pvb.Spec.ParentSnapshot = veleroshared.ParentSnapshotNone
|
||||
}
|
||||
|
||||
return pvb
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user