mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-09-18 14:04:39 +00:00
add fallback to volume info and backup/restore describe
Signed-off-by: Lyndon-Li <lyonghui@vmware.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Add fallback full to DU/DD/PVB/PVR CRs, volume info and backup/restore describe
|
||||
@@ -204,6 +204,10 @@ spec:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
fallbackFull:
|
||||
description: FallbackFull indicates whether the incremental backup
|
||||
has fallen back to full backup
|
||||
type: boolean
|
||||
incrementalBytes:
|
||||
description: |-
|
||||
IncrementalBytes holds the number of bytes new or changed since the last backup.
|
||||
|
||||
@@ -204,6 +204,10 @@ spec:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
fallbackFull:
|
||||
description: FallbackFull indicates whether the incremental restore
|
||||
has fallen back to full restore
|
||||
type: boolean
|
||||
incrementalBytes:
|
||||
description: IncrementalBytes holds the number of bytes restored incrementally
|
||||
format: int64
|
||||
|
||||
@@ -213,6 +213,10 @@ spec:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
fallbackFull:
|
||||
description: FallbackFull indicates whether the incremental restore
|
||||
has fallen back to full restore
|
||||
type: boolean
|
||||
incrementalBytes:
|
||||
description: IncrementalBytes holds the number of bytes restored incrementally
|
||||
since the last snapshot
|
||||
|
||||
@@ -195,6 +195,10 @@ spec:
|
||||
as a result of the DataUpload.
|
||||
nullable: true
|
||||
type: object
|
||||
fallbackFull:
|
||||
description: FallbackFull indicates whether the incremental backup
|
||||
has fallen back to full backup
|
||||
type: boolean
|
||||
incrementalBytes:
|
||||
description: |-
|
||||
IncrementalBytes holds the number of bytes new or changed since the last backup.
|
||||
|
||||
@@ -93,7 +93,7 @@ type BackupVolumeInfo struct {
|
||||
// How volume data is backed up, with possible values including Full and Incremental.
|
||||
BackupType velerov1api.BackupType `json:"backupType,omitempty"`
|
||||
|
||||
// FallbackFull indicates whether the incremental backup fallbacks to full backup
|
||||
// FallbackFull indicates whether the incremental backup has fallen back to full backup
|
||||
FallbackFull bool `json:"fallbackFull,omitempty"`
|
||||
|
||||
CSISnapshotInfo *CSISnapshotInfo `json:"csiSnapshotInfo,omitempty"`
|
||||
@@ -132,7 +132,7 @@ type RestoreVolumeInfo struct {
|
||||
// Indicates the type of the restore, incremental or full.
|
||||
RestoreType string `json:"restoreType,omitempty"`
|
||||
|
||||
// FallbackFull indicates whether the incremental restore fallbacks to full restore
|
||||
// FallbackFull indicates whether the incremental restore has fallen back to full restore
|
||||
FallbackFull bool `json:"fallbackFull,omitempty"`
|
||||
|
||||
CSISnapshotInfo *CSISnapshotInfo `json:"csiSnapshotInfo,omitempty"`
|
||||
@@ -300,7 +300,7 @@ type PodVolumeBackupInfo struct {
|
||||
// This field will be empty when the struct is used to represent a podvolumerestore.
|
||||
NodeName string `json:"nodeName,omitempty"`
|
||||
|
||||
// FallbackFull indicates whether the incremental backup fallbacks to full backup
|
||||
// FallbackFull indicates whether the incremental backup has fallen back to full backup
|
||||
FallbackFull bool `json:"fallbackFull,omitempty"`
|
||||
|
||||
// BackupType indicates the type of the backup, incremental or full.
|
||||
|
||||
@@ -142,7 +142,7 @@ type PodVolumeBackupStatus struct {
|
||||
// +nullable
|
||||
AcceptedTimestamp *metav1.Time `json:"acceptedTimestamp,omitempty"`
|
||||
|
||||
// FallbackFull indicates whether the incremental backup fallbacks to full backup
|
||||
// FallbackFull indicates whether the incremental backup has fallen back to full backup
|
||||
FallbackFull bool `json:"fallbackFull,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ type PodVolumeRestoreStatus struct {
|
||||
// +optional
|
||||
Node string `json:"node,omitempty"`
|
||||
|
||||
// FallbackFull indicates whether the incremental restore fallbacks to full restore
|
||||
// FallbackFull indicates whether the incremental restore has fallen back to full restore
|
||||
FallbackFull bool `json:"fallbackFull,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ type DataDownloadStatus struct {
|
||||
// +nullable
|
||||
AcceptedTimestamp *metav1.Time `json:"acceptedTimestamp,omitempty"`
|
||||
|
||||
// FallbackFull indicates whether the incremental restore fallbacks to full restore
|
||||
// FallbackFull indicates whether the incremental restore has fallen back to full restore
|
||||
FallbackFull bool `json:"fallbackFull,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ type DataUploadStatus struct {
|
||||
// +nullable
|
||||
AcceptedTimestamp *metav1.Time `json:"acceptedTimestamp,omitempty"`
|
||||
|
||||
// FallbackFull indicates whether the incremental backup fallbacks to full backup
|
||||
// FallbackFull indicates whether the incremental backup has fallen back to full backup
|
||||
FallbackFull bool `json:"fallbackFull,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ func TestOnDataUploadCompleted(t *testing.T) {
|
||||
{
|
||||
name: "marshal fail",
|
||||
marshalErr: errors.New("fake-marshal-error"),
|
||||
expectedErr: "Failed to marshal backup result { false { } 0 <nil> 0}: fake-marshal-error",
|
||||
expectedErr: "Failed to marshal backup result { false { } 0 <nil> 0 false}: fake-marshal-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
|
||||
@@ -102,7 +102,7 @@ func TestOnDataDownloadCompleted(t *testing.T) {
|
||||
{
|
||||
name: "marshal fail",
|
||||
marshalErr: errors.New("fake-marshal-error"),
|
||||
expectedErr: "Failed to marshal restore result {{ } 0 0}: fake-marshal-error",
|
||||
expectedErr: "Failed to marshal restore result {{ } 0 0 false}: fake-marshal-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
|
||||
@@ -156,7 +156,7 @@ func TestOnDataPathCompleted(t *testing.T) {
|
||||
{
|
||||
name: "marshal fail",
|
||||
marshalErr: errors.New("fake-marshal-error"),
|
||||
expectedErr: "Failed to marshal backup result { false { } 0 <nil> 0}: fake-marshal-error",
|
||||
expectedErr: "Failed to marshal backup result { false { } 0 <nil> 0 false}: fake-marshal-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
|
||||
@@ -165,7 +165,7 @@ func TestOnPvrCompleted(t *testing.T) {
|
||||
{
|
||||
name: "marshal fail",
|
||||
marshalErr: errors.New("fake-marshal-error"),
|
||||
expectedErr: "error marshaling restore result {{ } 0 0}: fake-marshal-error",
|
||||
expectedErr: "error marshaling restore result {{ } 0 0 false}: fake-marshal-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
|
||||
@@ -128,7 +128,10 @@ func snapshotSource(
|
||||
log.WithError(err).Warnf("Failed to create CBT with source %v", cbtSource)
|
||||
}
|
||||
|
||||
fallback := (len(bitmap.Errors()) > 0)
|
||||
fallback := false
|
||||
if !forceFull {
|
||||
fallback = (len(bitmap.Errors()) > 0)
|
||||
}
|
||||
|
||||
snap, backupSize, err := u.Backup(source, parentBackup.parentObject, bitmap.Iterator(), uploaderCfg)
|
||||
if err != nil {
|
||||
@@ -251,7 +254,10 @@ func Restore(ctx context.Context, blkUp Uploader, rep udmrepo.BackupRepo, snapsh
|
||||
bitmap.SetFull()
|
||||
}
|
||||
|
||||
fallback := (len(bitmap.Errors()) > 0)
|
||||
fallback := false
|
||||
if incremental {
|
||||
fallback = (len(bitmap.Errors()) > 0)
|
||||
}
|
||||
|
||||
destPath, err := filepath.Abs(dest)
|
||||
if err != nil {
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/cbtservice"
|
||||
cbtservicemocks "github.com/vmware-tanzu/velero/pkg/cbtservice/mocks"
|
||||
@@ -126,6 +127,7 @@ func TestBackup(t *testing.T) {
|
||||
assert.Equal(t, int64(8), info.IncrementalSize)
|
||||
assert.Equal(t, int64(2048), info.SnapshotSize)
|
||||
assert.Equal(t, int64(len("test-block-data")), info.SourceSize)
|
||||
assert.False(t, info.Fallback)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -149,6 +151,7 @@ func TestBackup(t *testing.T) {
|
||||
assert.Equal(t, int64(8), info.IncrementalSize)
|
||||
assert.Equal(t, int64(len("test-block-data")), info.SnapshotSize)
|
||||
assert.Equal(t, int64(len("test-block-data")), info.SourceSize)
|
||||
assert.False(t, info.Fallback)
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -210,6 +213,8 @@ func TestSnapshotSource(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
forceFull *bool
|
||||
parentSnapshot string
|
||||
setupMocks func(blkup *mockUploader, repo *udmrepomocks.BackupRepo)
|
||||
expectedErrStr string
|
||||
expectedSnapID string
|
||||
@@ -260,7 +265,7 @@ func TestSnapshotSource(t *testing.T) {
|
||||
expectedSnapID: "snap-success",
|
||||
expectedSize: 512,
|
||||
expectedSnapshotSize: 2048,
|
||||
expectedFallback: true,
|
||||
expectedFallback: false,
|
||||
},
|
||||
{
|
||||
name: "tags from cbtSource and snapshotTags are merged onto snapshot",
|
||||
@@ -278,7 +283,7 @@ func TestSnapshotSource(t *testing.T) {
|
||||
expectedSnapID: "snap-tags",
|
||||
expectedSize: 256,
|
||||
expectedSnapshotSize: 4096,
|
||||
expectedFallback: true,
|
||||
expectedFallback: false,
|
||||
},
|
||||
{
|
||||
name: "success with cbtService getting allocated blocks",
|
||||
@@ -322,6 +327,23 @@ func TestSnapshotSource(t *testing.T) {
|
||||
expectedSnapID: "snap-cbt-fallback",
|
||||
expectedSize: 1024,
|
||||
expectedSnapshotSize: 1024,
|
||||
expectedFallback: false,
|
||||
},
|
||||
{
|
||||
name: "incremental backup falls back to full when parent snapshot load fails",
|
||||
forceFull: ptr.To(false),
|
||||
parentSnapshot: "snap-parent",
|
||||
setupMocks: func(blkup *mockUploader, repo *udmrepomocks.BackupRepo) {
|
||||
repo.On("GetSnapshot", mock.Anything, udmrepo.ID("snap-parent")).
|
||||
Return(udmrepo.Snapshot{}, errors.New("parent not found"))
|
||||
blkup.On("Backup", mock.Anything, udmrepo.ID(""), mock.Anything, mock.Anything).
|
||||
Return(udmrepo.Snapshot{TotalSize: 1024}, int64(1024), nil)
|
||||
repo.On("SaveSnapshot", mock.Anything, mock.Anything).Return(udmrepo.ID("snap-inc-fallback"), nil)
|
||||
repo.On("Flush", mock.Anything).Return(nil)
|
||||
},
|
||||
expectedSnapID: "snap-inc-fallback",
|
||||
expectedSize: 1024,
|
||||
expectedSnapshotSize: 1024,
|
||||
expectedFallback: true,
|
||||
},
|
||||
}
|
||||
@@ -342,10 +364,15 @@ func TestSnapshotSource(t *testing.T) {
|
||||
cbtSvc = tc.cbtService(t)
|
||||
}
|
||||
|
||||
forceFull := true
|
||||
if tc.forceFull != nil {
|
||||
forceFull = *tc.forceFull
|
||||
}
|
||||
|
||||
snapID, size, snapshotSize, fallback, err := snapshotSource(
|
||||
ctx, mockRepo, mockBlkup,
|
||||
baseSource,
|
||||
true, "",
|
||||
forceFull, tc.parentSnapshot,
|
||||
cbtSrc, cbtSvc,
|
||||
snapshotTags, map[string]string{},
|
||||
testLog(), "Block Uploader",
|
||||
|
||||
Reference in New Issue
Block a user