From 494c9b91cb1d9213b835717826459963e71b406e Mon Sep 17 00:00:00 2001 From: Madhu Rajanna Date: Thu, 16 Dec 2021 10:57:46 +0530 Subject: [PATCH] e2e: add e2e for bigger size restore added e2e for below cases Normal PVC snapshot restore to a bigger size PVC (without encryption) * Filesystem pvc restore to a bigger size * Block pvc restore to a bigger size Encrypted PVC snapshot restore to a bigger size PVC * Filesystem pvc restore to a bigger size * Block pvc restore to a bigger size Signed-off-by: Madhu Rajanna --- e2e/rbd.go | 106 ++++++++++++++++++++++++++++ e2e/snapshot.go | 87 +++++++++++++++++++++++ examples/rbd/pod-block-restore.yaml | 17 +++++ examples/rbd/pvc-block-restore.yaml | 17 +++++ 4 files changed, 227 insertions(+) create mode 100644 examples/rbd/pod-block-restore.yaml create mode 100644 examples/rbd/pvc-block-restore.yaml diff --git a/e2e/rbd.go b/e2e/rbd.go index 124d9b988..3f6cc729b 100644 --- a/e2e/rbd.go +++ b/e2e/rbd.go @@ -60,6 +60,8 @@ var ( appClonePath = rbdExamplePath + "pod-restore.yaml" appSmartClonePath = rbdExamplePath + "pod-clone.yaml" appBlockSmartClonePath = rbdExamplePath + "block-pod-clone.yaml" + pvcBlockRestorePath = rbdExamplePath + "pvc-block-restore.yaml" + appBlockRestorePath = rbdExamplePath + "pod-block-restore.yaml" appEphemeralPath = rbdExamplePath + "pod-ephemeral.yaml" snapshotPath = rbdExamplePath + "snapshot.yaml" deployFSAppPath = e2eTemplatesPath + "rbd-fs-deployment.yaml" @@ -3338,6 +3340,110 @@ var _ = Describe("RBD", func() { } }) + By("restore snapshot to a bigger size PVC", func() { + By("restore snapshot to bigger size pvc", func() { + err := deleteResource(rbdExamplePath + "storageclass.yaml") + if err != nil { + e2elog.Failf("failed to delete storageclass: %v", err) + } + err = createRBDStorageClass(f.ClientSet, f, defaultSCName, nil, nil, deletePolicy) + if err != nil { + e2elog.Failf("failed to create storageclass: %v", err) + } + defer func() { + err = deleteResource(rbdExamplePath + "storageclass.yaml") + if err != nil { + e2elog.Failf("failed to delete storageclass: %v", err) + } + }() + err = createRBDSnapshotClass(f) + if err != nil { + e2elog.Failf("failed to create VolumeSnapshotClass: %v", err) + } + defer func() { + err = deleteRBDSnapshotClass() + if err != nil { + e2elog.Failf("failed to delete VolumeSnapshotClass: %v", err) + } + }() + // validate filesystem mode PVC + err = validateBiggerPVCFromSnapshot(f, + pvcPath, + appPath, + snapshotPath, + pvcClonePath, + appClonePath) + if err != nil { + e2elog.Failf("failed to validate restore bigger size clone: %v", err) + } + // validate block mode PVC + err = validateBiggerPVCFromSnapshot(f, + rawPvcPath, + rawAppPath, + snapshotPath, + pvcBlockRestorePath, + appBlockRestorePath) + if err != nil { + e2elog.Failf("failed to validate restore bigger size clone: %v", err) + } + }) + + By("restore snapshot to bigger size encrypted PVC with VaultKMS", func() { + scOpts := map[string]string{ + "encrypted": "true", + "encryptionKMSID": "vault-test", + } + err := createRBDStorageClass(f.ClientSet, f, defaultSCName, nil, scOpts, deletePolicy) + if err != nil { + e2elog.Failf("failed to create storageclass: %v", err) + } + defer func() { + err = deleteResource(rbdExamplePath + "storageclass.yaml") + if err != nil { + e2elog.Failf("failed to delete storageclass: %v", err) + } + }() + err = createRBDSnapshotClass(f) + if err != nil { + e2elog.Failf("failed to create VolumeSnapshotClass: %v", err) + } + defer func() { + err = deleteRBDSnapshotClass() + if err != nil { + e2elog.Failf("failed to delete VolumeSnapshotClass: %v", err) + } + }() + // validate filesystem mode PVC + err = validateBiggerPVCFromSnapshot(f, + pvcPath, + appPath, + snapshotPath, + pvcClonePath, + appClonePath) + if err != nil { + e2elog.Failf("failed to validate restore bigger size clone: %v", err) + } + // validate block mode PVC + err = validateBiggerPVCFromSnapshot(f, + rawPvcPath, + rawAppPath, + snapshotPath, + pvcBlockRestorePath, + appBlockRestorePath) + if err != nil { + e2elog.Failf("failed to validate restore bigger size clone: %v", err) + } + }) + + By("validate image deletion", func() { + validateRBDImageCount(f, 0, defaultRBDPool) + err := waitToRemoveImagesFromTrash(f, defaultRBDPool, deployTimeout) + if err != nil { + e2elog.Failf("failed to validate rbd images in pool %s trash: %v", defaultRBDPool, err) + } + }) + }) + // Make sure this should be last testcase in this file, because // it deletes pool By("Create a PVC and delete PVC when backend pool deleted", func() { diff --git a/e2e/snapshot.go b/e2e/snapshot.go index 390a1a09b..b6d15c750 100644 --- a/e2e/snapshot.go +++ b/e2e/snapshot.go @@ -9,7 +9,9 @@ import ( snapapi "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1" snapclient "github.com/kubernetes-csi/external-snapshotter/client/v4/clientset/versioned/typed/volumesnapshot/v1" . "github.com/onsi/gomega" // nolint + v1 "k8s.io/api/core/v1" apierrs "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/kubernetes/test/e2e/framework" @@ -218,3 +220,88 @@ func getVolumeSnapshotContent(namespace, snapshotName string) (*snapapi.VolumeSn return volumeSnapshotContent, nil } + +func validateBiggerPVCFromSnapshot(f *framework.Framework, + pvcPath, + appPath, + snapPath, + pvcClonePath, + appClonePath string) error { + const ( + size = "1Gi" + newSize = "2Gi" + ) + pvc, err := loadPVC(pvcPath) + if err != nil { + return fmt.Errorf("failed to load PVC: %w", err) + } + label := make(map[string]string) + pvc.Namespace = f.UniqueName + pvc.Spec.Resources.Requests[v1.ResourceStorage] = resource.MustParse(size) + app, err := loadApp(appPath) + if err != nil { + return fmt.Errorf("failed to load app: %w", err) + } + label[appKey] = appLabel + app.Namespace = f.UniqueName + app.Labels = label + opt := metav1.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", appKey, label[appKey]), + } + err = createPVCAndApp("", f, pvc, app, deployTimeout) + if err != nil { + return fmt.Errorf("failed to create pvc and application: %w", err) + } + + snap := getSnapshot(snapPath) + snap.Namespace = f.UniqueName + snap.Spec.Source.PersistentVolumeClaimName = &pvc.Name + err = createSnapshot(&snap, deployTimeout) + if err != nil { + return fmt.Errorf("failed to create snapshot: %w", err) + } + err = deletePVCAndApp("", f, pvc, app) + if err != nil { + return fmt.Errorf("failed to delete pvc and application: %w", err) + } + pvcClone, err := loadPVC(pvcClonePath) + if err != nil { + e2elog.Failf("failed to load PVC: %v", err) + } + pvcClone.Namespace = f.UniqueName + pvcClone.Spec.DataSource.Name = snap.Name + pvcClone.Spec.Resources.Requests[v1.ResourceStorage] = resource.MustParse(newSize) + appClone, err := loadApp(appClonePath) + if err != nil { + e2elog.Failf("failed to load application: %v", err) + } + appClone.Namespace = f.UniqueName + appClone.Labels = label + err = createPVCAndApp("", f, pvcClone, appClone, deployTimeout) + if err != nil { + return fmt.Errorf("failed to create pvc clone and application: %w", err) + } + err = deleteSnapshot(&snap, deployTimeout) + if err != nil { + return fmt.Errorf("failed to delete snapshot: %w", err) + } + if pvcClone.Spec.VolumeMode == nil || *pvcClone.Spec.VolumeMode == v1.PersistentVolumeFilesystem { + err = checkDirSize(appClone, f, &opt, newSize) + if err != nil { + return fmt.Errorf("failed to validate directory size: %w", err) + } + } + + if pvcClone.Spec.VolumeMode != nil && *pvcClone.Spec.VolumeMode == v1.PersistentVolumeBlock { + err = checkDeviceSize(appClone, f, &opt, newSize) + if err != nil { + return fmt.Errorf("failed to validate device size: %w", err) + } + } + err = deletePVCAndApp("", f, pvcClone, appClone) + if err != nil { + return fmt.Errorf("failed to delete pvc and application: %w", err) + } + + return nil +} diff --git a/examples/rbd/pod-block-restore.yaml b/examples/rbd/pod-block-restore.yaml new file mode 100644 index 000000000..230b2fd87 --- /dev/null +++ b/examples/rbd/pod-block-restore.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: v1 +kind: Pod +metadata: + name: pod-block-volume-restore +spec: + containers: + - name: centos + image: quay.io/centos/centos:latest + command: ["/bin/sleep", "infinity"] + volumeDevices: + - name: data + devicePath: /dev/xvda + volumes: + - name: data + persistentVolumeClaim: + claimName: rbd-block-pvc-restore diff --git a/examples/rbd/pvc-block-restore.yaml b/examples/rbd/pvc-block-restore.yaml new file mode 100644 index 000000000..deb333cf3 --- /dev/null +++ b/examples/rbd/pvc-block-restore.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: rbd-block-pvc-restore +spec: + storageClassName: csi-rbd-sc + dataSource: + name: rbd-pvc-snapshot + kind: VolumeSnapshot + apiGroup: snapshot.storage.k8s.io + accessModes: + - ReadWriteOnce + volumeMode: Block + resources: + requests: + storage: 1Gi