decide restorePVC volumeMode by data mover type (#9941)

Signed-off-by: Lyndon-Li <lyonghui@vmware.com>
This commit is contained in:
lyndon-li
2026-06-25 11:06:53 +08:00
committed by GitHub
parent 5844ce873d
commit cfd4914123
5 changed files with 78 additions and 16 deletions
+1
View File
@@ -0,0 +1 @@
Decide restorePVC volumeMode by data mover type for block data mover
@@ -949,6 +949,7 @@ func (r *DataDownloadReconciler) setupExposeParam(dd *velerov2alpha1api.DataDown
PriorityClassName: r.dataMovePriorityClass,
RestoreSize: dd.Spec.SnapshotSize,
CacheVolume: cacheVolume,
DataMover: dd.Spec.DataMover,
}, nil
}
@@ -1429,6 +1429,7 @@ func TestDataDownloadSetupExposeParam(t *testing.T) {
// Core fields
assert.Equal(t, baseDataDownload.Spec.TargetVolume.PVC, got.TargetPVCName)
assert.Equal(t, baseDataDownload.Spec.TargetVolume.Namespace, got.TargetNamespace)
assert.Equal(t, baseDataDownload.Spec.DataMover, got.DataMover)
// Labels and Annotations
assert.Equal(t, tt.want.labels, got.HostingPodLabels)
+27 -15
View File
@@ -31,6 +31,7 @@ import (
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/vmware-tanzu/velero/pkg/datamover"
"github.com/vmware-tanzu/velero/pkg/nodeagent"
velerotypes "github.com/vmware-tanzu/velero/pkg/types"
"github.com/vmware-tanzu/velero/pkg/util/boolptr"
@@ -80,6 +81,9 @@ type GenericRestoreExposeParam struct {
// CacheVolume specifies the info for cache volumes
CacheVolume *CacheConfigs
// DataMover is the data mover type, e.g., velero-fs, velero-block
DataMover string
}
// GenericRestoreRebindVolumeParam define the input param for Generic Restore Rebind Volume
@@ -192,10 +196,23 @@ func (e *genericRestoreExposer) Expose(ctx context.Context, ownerObject corev1ap
}
}
restorePVC, err := e.createRestorePVC(ctx, ownerObject, targetPVC, selectedNode, param.DataMover)
if err != nil {
return errors.Wrap(err, "error to create restore pvc")
}
curLog.WithField("pvc name", restorePVC.Name).Info("Restore PVC is created")
defer func() {
if err != nil {
kube.DeletePVAndPVCIfAny(ctx, e.kubeClient.CoreV1(), restorePVC.Name, restorePVC.Namespace, 0, curLog)
}
}()
restorePod, err := e.createRestorePod(
ctx,
ownerObject,
targetPVC,
restorePVC,
param.OperationTimeout,
param.HostingPodLabels,
param.HostingPodAnnotations,
@@ -219,19 +236,6 @@ func (e *genericRestoreExposer) Expose(ctx context.Context, ownerObject corev1ap
}
}()
restorePVC, err := e.createRestorePVC(ctx, ownerObject, targetPVC, selectedNode)
if err != nil {
return errors.Wrap(err, "error to create restore pvc")
}
curLog.WithField("pvc name", restorePVC.Name).Info("Restore PVC is created")
defer func() {
if err != nil {
kube.DeletePVAndPVCIfAny(ctx, e.kubeClient.CoreV1(), restorePVC.Name, restorePVC.Namespace, 0, curLog)
}
}()
return nil
}
@@ -802,7 +806,7 @@ func (e *genericRestoreExposer) createRestorePod(
return e.kubeClient.CoreV1().Pods(ownerObject.Namespace).Create(ctx, pod, metav1.CreateOptions{})
}
func (e *genericRestoreExposer) createRestorePVC(ctx context.Context, ownerObject corev1api.ObjectReference, targetPVC *corev1api.PersistentVolumeClaim, selectedNode string) (*corev1api.PersistentVolumeClaim, error) {
func (e *genericRestoreExposer) createRestorePVC(ctx context.Context, ownerObject corev1api.ObjectReference, targetPVC *corev1api.PersistentVolumeClaim, selectedNode string, dataMover string) (*corev1api.PersistentVolumeClaim, error) {
restorePVCName := ownerObject.Name
pvcObj := &corev1api.PersistentVolumeClaim{
@@ -835,5 +839,13 @@ func (e *genericRestoreExposer) createRestorePVC(ctx context.Context, ownerObjec
}
}
if dataMover == datamover.DataMoverTypeVeleroBlock {
if pvcObj.Spec.VolumeMode == nil {
pvcObj.Spec.VolumeMode = new(corev1api.PersistentVolumeMode)
}
*pvcObj.Spec.VolumeMode = corev1api.PersistentVolumeBlock
}
return e.kubeClient.CoreV1().PersistentVolumeClaims(pvcObj.Namespace).Create(ctx, pvcObj, metav1.CreateOptions{})
}
+48 -1
View File
@@ -33,6 +33,7 @@ import (
clientTesting "k8s.io/client-go/testing"
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/datamover"
velerotest "github.com/vmware-tanzu/velero/pkg/test"
"github.com/vmware-tanzu/velero/pkg/util/kube"
)
@@ -61,6 +62,18 @@ func TestRestoreExpose(t *testing.T) {
},
}
modeFilesystem := corev1api.PersistentVolumeFilesystem
targetPVCObjWithVolumeMode := &corev1api.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Namespace: "fake-ns",
Name: "fake-target-pvc",
},
Spec: corev1api.PersistentVolumeClaimSpec{
StorageClassName: &scName,
VolumeMode: &modeFilesystem,
},
}
storageClass := &storagev1api.StorageClass{
ObjectMeta: metav1.ObjectMeta{
Name: "fake-sc",
@@ -107,6 +120,7 @@ func TestRestoreExpose(t *testing.T) {
targetNamespace string
kubeReactors []reactor
cacheVolume *CacheConfigs
dataMover string
expectBackupPod bool
expectBackupPVC bool
expectCachePVC bool
@@ -236,6 +250,34 @@ func TestRestoreExpose(t *testing.T) {
expectBackupPVC: true,
expectCachePVC: true,
},
{
name: "succeed with velero-block data mover",
targetPVCName: "fake-target-pvc",
targetNamespace: "fake-ns",
ownerRestore: restore,
kubeClientObj: []runtime.Object{
targetPVCObj,
daemonSet,
storageClass,
},
dataMover: datamover.DataMoverTypeVeleroBlock,
expectBackupPod: true,
expectBackupPVC: true,
},
{
name: "succeed with velero-block data mover and existing volume mode",
targetPVCName: "fake-target-pvc",
targetNamespace: "fake-ns",
ownerRestore: restore,
kubeClientObj: []runtime.Object{
targetPVCObjWithVolumeMode,
daemonSet,
storageClass,
},
dataMover: datamover.DataMoverTypeVeleroBlock,
expectBackupPod: true,
expectBackupPVC: true,
},
}
for _, test := range tests {
@@ -273,6 +315,7 @@ func TestRestoreExpose(t *testing.T) {
ExposeTimeout: time.Millisecond,
LoadAffinity: nil,
CacheVolume: test.cacheVolume,
DataMover: test.dataMover,
},
)
@@ -289,9 +332,13 @@ func TestRestoreExpose(t *testing.T) {
require.True(t, apierrors.IsNotFound(err))
}
_, err = exposer.kubeClient.CoreV1().PersistentVolumeClaims(ownerObject.Namespace).Get(t.Context(), ownerObject.Name, metav1.GetOptions{})
pvc, err := exposer.kubeClient.CoreV1().PersistentVolumeClaims(ownerObject.Namespace).Get(t.Context(), ownerObject.Name, metav1.GetOptions{})
if test.expectBackupPVC {
require.NoError(t, err)
if test.dataMover == datamover.DataMoverTypeVeleroBlock {
require.NotNil(t, pvc.Spec.VolumeMode)
require.Equal(t, corev1api.PersistentVolumeBlock, *pvc.Spec.VolumeMode)
}
} else {
require.True(t, apierrors.IsNotFound(err))
}