Skip to content

Commit

Permalink
fix: create snapshot failed if storageClass's provisioner not equals …
Browse files Browse the repository at this point in the history
…to driver name
  • Loading branch information
wangyelei committed Oct 25, 2023
1 parent aec1be5 commit 9fdbfa7
Show file tree
Hide file tree
Showing 15 changed files with 61 additions and 37 deletions.
5 changes: 1 addition & 4 deletions controllers/apps/components/hscale_volume_populator.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,11 +454,8 @@ func isVolumeSnapshotEnabled(ctx context.Context, cli client.Client,
if err := cli.Get(ctx, pvcKey, &pvc); err != nil {
return false, client.IgnoreNotFound(err)
}
if pvc.Spec.StorageClassName == nil {
return false, nil
}

return intctrlutil.IsVolumeSnapshotEnabled(ctx, cli, *pvc.Spec.StorageClassName)
return intctrlutil.IsVolumeSnapshotEnabled(ctx, cli, pvc.Spec.VolumeName)
}

func getBackupMethods(backupPolicy *dpv1alpha1.BackupPolicy, useVolumeSnapshot bool) []string {
Expand Down
25 changes: 15 additions & 10 deletions controllers/dataprotection/backup_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,11 @@ func (r *BackupReconciler) prepareBackupRequest(
}

request.BackupPolicy = backupPolicy
if err = r.handleBackupRepo(request); err != nil {
return nil, err
if !snapshotVolumes {
// if use volume snapshot, ignore backup repo
if err = r.handleBackupRepo(request); err != nil {
return nil, err
}
}

request.BackupMethod = backupMethod
Expand Down Expand Up @@ -349,11 +352,12 @@ func (r *BackupReconciler) patchBackupStatus(
request.Status.Path = dpbackup.BuildBackupPath(request.Backup, request.BackupPolicy.Spec.PathPrefix)
request.Status.Target = request.BackupPolicy.Spec.Target
request.Status.BackupMethod = request.BackupMethod
request.Status.BackupRepoName = request.BackupRepo.Name
if request.BackupRepo != nil {
request.Status.BackupRepoName = request.BackupRepo.Name
}
if request.BackupRepoPVC != nil {
request.Status.PersistentVolumeClaimName = request.BackupRepoPVC.Name
}

// init action status
actions, err := request.BuildActions()
if err != nil {
Expand Down Expand Up @@ -398,16 +402,17 @@ func (r *BackupReconciler) patchBackupObjectMeta(
request.Labels[v] = targetPod.Labels[v]
}

request.Labels[dataProtectionBackupRepoKey] = request.BackupRepo.Name
request.Labels[constant.AppManagedByLabelKey] = constant.AppName
request.Labels[dptypes.BackupTypeLabelKey] = request.GetBackupType()

// wait for the backup repo controller to prepare the essential resource.
wait := false
if (request.BackupRepo.AccessByMount() && request.BackupRepoPVC == nil) ||
(request.BackupRepo.AccessByTool() && request.ToolConfigSecret == nil) {
request.Labels[dataProtectionWaitRepoPreparationKey] = trueVal
wait = true
if request.BackupRepo != nil {
request.Labels[dataProtectionBackupRepoKey] = request.BackupRepo.Name
if (request.BackupRepo.AccessByMount() && request.BackupRepoPVC == nil) ||
(request.BackupRepo.AccessByTool() && request.ToolConfigSecret == nil) {
request.Labels[dataProtectionWaitRepoPreparationKey] = trueVal
wait = true
}
}

// set annotations
Expand Down
3 changes: 2 additions & 1 deletion controllers/dataprotection/backup_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ var _ = Describe("Backup Controller test", func() {
// non-namespaced
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.ActionSetSignature, true, ml)
testapps.ClearResources(&testCtx, generics.StorageClassSignature, ml)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.PersistentVolumeSignature, true, ml)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.BackupRepoSignature, true, ml)
testapps.ClearResources(&testCtx, generics.StorageProviderSignature, ml)
testapps.ClearResources(&testCtx, generics.VolumeSnapshotClassSignature, ml)
Expand Down Expand Up @@ -328,7 +329,7 @@ var _ = Describe("Backup Controller test", func() {

BeforeEach(func() {
// mock VolumeSnapshotClass for volume snapshot
testk8s.CreateVolumeSnapshotClass(&testCtx, testutil.DefaultStorageProvisoner)
testk8s.CreateVolumeSnapshotClass(&testCtx, testutil.DefaultCSIDriver)

By("create a backup from backupPolicy " + testdp.BackupPolicyName)
backup = testdp.NewFakeBackup(&testCtx, func(backup *dpv1alpha1.Backup) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ var _ = Describe("Backup Schedule Controller", func() {
// non-namespaced
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.ActionSetSignature, true, ml)
testapps.ClearResources(&testCtx, generics.StorageClassSignature, ml)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.PersistentVolumeSignature, true, ml)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.BackupRepoSignature, true, ml)
testapps.ClearResources(&testCtx, generics.StorageProviderSignature, ml)
}
Expand Down
1 change: 1 addition & 0 deletions controllers/dataprotection/gc_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ var _ = Describe("Data Protection Garbage Collection Controller", func() {
// non-namespaced
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.ActionSetSignature, true, ml)
testapps.ClearResources(&testCtx, generics.StorageClassSignature, ml)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.PersistentVolumeSignature, true, ml)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.BackupRepoSignature, true, ml)
testapps.ClearResources(&testCtx, generics.StorageProviderSignature, ml)
}
Expand Down
1 change: 1 addition & 0 deletions controllers/dataprotection/restore_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ var _ = Describe("Restore Controller test", func() {
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.StorageClassSignature, true, ml)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.BackupRepoSignature, true, ml)
testapps.ClearResources(&testCtx, generics.StorageProviderSignature, ml)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.PersistentVolumeSignature, true, ml)
}

BeforeEach(func() {
Expand Down
19 changes: 12 additions & 7 deletions pkg/controllerutil/volumesnapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (

snapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/client/v3/apis/volumesnapshot/v1beta1"
snapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v6/apis/volumesnapshot/v1"
storagev1 "k8s.io/api/storage/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"

Expand Down Expand Up @@ -165,12 +165,17 @@ func typeofV1Beta1(v any) any {
}

// IsVolumeSnapshotEnabled checks if the CSI supports the volume snapshot.
func IsVolumeSnapshotEnabled(ctx context.Context, cli client.Client, storageClassName string) (bool, error) {
storageClass := storagev1.StorageClass{}
if err := cli.Get(ctx, types.NamespacedName{Name: storageClassName}, &storageClass); err != nil {
return false, client.IgnoreNotFound(err)
func IsVolumeSnapshotEnabled(ctx context.Context, cli client.Client, pvName string) (bool, error) {
if len(pvName) == 0 {
return false, nil
}
pv := &corev1.PersistentVolume{}
if err := cli.Get(ctx, types.NamespacedName{Name: pvName}, pv); err != nil {
return false, err
}
if pv.Spec.CSI == nil {
return false, nil
}

vsCli := VolumeSnapshotCompatClient{
Client: cli,
Ctx: ctx,
Expand All @@ -180,7 +185,7 @@ func IsVolumeSnapshotEnabled(ctx context.Context, cli client.Client, storageClas
return false, err
}
for _, vsc := range vscList.Items {
if vsc.Driver == storageClass.Provisioner {
if vsc.Driver == pv.Spec.CSI.Driver {
return true, nil
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/dataprotection/action/action_create_vs.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func (c *CreateVolumeSnapshotAction) createVolumeSnapshotIfNotExist(ctx Context,

msg := fmt.Sprintf("creating volume snapshot %s/%s", snap.Namespace, snap.Name)
ctx.Recorder.Event(c.Owner, corev1.EventTypeNormal, "CreatingVolumeSnapshot", msg)
if err = ctx.Client.Create(ctx.Ctx, snap); err != nil {
if err = vsCli.Create(snap); err != nil {
return err
}
return nil
Expand Down
1 change: 1 addition & 0 deletions pkg/dataprotection/backup/request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ var _ = Describe("Request Test", func() {
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.BackupRepoSignature, true, ml)
testapps.ClearResources(&testCtx, generics.StorageProviderSignature, ml)
testapps.ClearResources(&testCtx, generics.VolumeSnapshotClassSignature, ml)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.PersistentVolumeSignature, true, ml)
}

var clusterInfo *testdp.BackupClusterInfo
Expand Down
1 change: 1 addition & 0 deletions pkg/dataprotection/restore/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ var _ = Describe("Backup Deleter Test", func() {
// non-namespaced
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.ActionSetSignature, true, ml)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.StorageClassSignature, true, ml)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.PersistentVolumeSignature, true, ml)
}

BeforeEach(func() {
Expand Down
11 changes: 2 additions & 9 deletions pkg/dataprotection/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,24 +163,17 @@ func VolumeSnapshotEnabled(ctx context.Context, cli client.Client, pod *corev1.P
return false, fmt.Errorf(`can not find any volume by targetVolumes %v on pod "%s"`, volumes, pod.Name)
}
// get the storageClass by pvc
storageClassMap := map[string]string{}
for i := range pvcNames {
pvc := &corev1.PersistentVolumeClaim{}
if err := cli.Get(ctx, types.NamespacedName{Name: pvcNames[i], Namespace: pod.Namespace}, pvc); err != nil {
return false, nil
}
if pvc.Spec.StorageClassName == nil {
return false, nil
}
storageClassMap[*pvc.Spec.StorageClassName] = pvcNames[i]
}
for k := range storageClassMap {
enabled, err := intctrlutil.IsVolumeSnapshotEnabled(ctx, cli, k)
enabled, err := intctrlutil.IsVolumeSnapshotEnabled(ctx, cli, pvc.Spec.VolumeName)
if err != nil {
return false, err
}
if !enabled {
return false, fmt.Errorf(`cannot find any VolumeSnapshotClass of persistentVolumeClaim "%s" to do volume snapshot on pod "%s"`, storageClassMap[k], pod.Name)
return false, fmt.Errorf(`cannot find any VolumeSnapshotClass of persistentVolumeClaim "%s" to do volume snapshot on pod "%s"`, pvc.Name, pod.Name)
}
}
return true, nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/testutil/apps/native_object_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func CreateVolumeSnapshotClass(testCtx *testutil.TestContext) {
ObjectMeta: metav1.ObjectMeta{
Name: "default-vs",
},
Driver: testutil.DefaultStorageProvisoner,
Driver: testutil.DefaultCSIDriver,
DeletionPolicy: vsv1.VolumeSnapshotContentDelete,
}
CreateK8sResource(testCtx, volumeSnapshotClass)
Expand Down
10 changes: 10 additions & 0 deletions pkg/testutil/apps/pv_factoy.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,13 @@ func (f *MockPersistentVolumeFactory) SetClaimRef(obj client.Object) *MockPersis
}
return f
}

func (f *MockPersistentVolumeFactory) SetCSIDriver(driverName string) *MockPersistentVolumeFactory {
f.Get().Spec.CSI = &corev1.CSIPersistentVolumeSource{
Driver: driverName,
VolumeHandle: f.Get().Name,
}
// clear default persistentVolumeSource
f.Get().Spec.PersistentVolumeSource.HostPath = nil
return f
}
15 changes: 11 additions & 4 deletions pkg/testutil/dataprotection/backup_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,19 @@ func NewFakeBackup(testCtx *testutil.TestContext,
}

func NewFakeCluster(testCtx *testutil.TestContext) *BackupClusterInfo {
createPVC := func(name string) *corev1.PersistentVolumeClaim {
return testapps.NewPersistentVolumeClaimFactory(
createPVCAndPV := func(name string) *corev1.PersistentVolumeClaim {
pvName := "pv-" + name
pvc := testapps.NewPersistentVolumeClaimFactory(
testCtx.DefaultNamespace, name, ClusterName, ComponentName, "data").
SetVolumeName(pvName).
SetStorage("1Gi").
SetStorageClass(StorageClassName).
Create(testCtx).GetObject()

testapps.NewPersistentVolumeFactory(testCtx.DefaultNamespace, pvName, name).
SetStorage("1Gi").
SetClaimRef(pvc).SetCSIDriver(testutil.DefaultCSIDriver).Create(testCtx)
return pvc
}

podFactory := func(name string) *testapps.MockPodFactory {
Expand All @@ -148,10 +155,10 @@ func NewFakeCluster(testCtx *testutil.TestContext) *BackupClusterInfo {
_ = testapps.CreateStorageClass(testCtx, StorageClassName, true)

By("mocking a pvc belonging to the pod 0")
pvc := createPVC("data-" + podName + "-0")
pvc := createPVCAndPV("data-" + podName + "-0")

By("mocking a pvc belonging to the pod 1")
pvc1 := createPVC("data-" + podName + "-1")
pvc1 := createPVCAndPV("data-" + podName + "-1")

By("mocking pod 0 belonging to the statefulset")
volume := corev1.Volume{Name: DataVolumeName, VolumeSource: corev1.VolumeSource{
Expand Down
1 change: 1 addition & 0 deletions pkg/testutil/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const (
envExistingClusterType = "EXISTING_CLUSTER_TYPE"
envUseExistingCluster = "USE_EXISTING_CLUSTER"
DefaultStorageProvisoner = "kubernetes.io/no-provisioner"
DefaultCSIDriver = "hostpath.csi.k8s.io"
)

func init() {
Expand Down

0 comments on commit 9fdbfa7

Please sign in to comment.