mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-07-22 07:52:54 +00:00
decide restorePVC volumeMode by data mover type (#9941)
Signed-off-by: Lyndon-Li <lyonghui@vmware.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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{})
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user