e2e: validate thick-provisioned PVC-PVC cloning

Add a case to create a new PVC with VolumeContentSource set to a
thick-provisioned PVC. This should result in a new thick-provisioned PVC
once the cloning is done.

Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
Niels de Vos 2021-06-07 10:13:14 +02:00 committed by mergify[bot]
parent 6cc11c15d3
commit 0fe0962dc1
3 changed files with 52 additions and 8 deletions

View File

@ -761,7 +761,35 @@ var _ = Describe("RBD", func() {
By("create a PVC-PVC clone and bind it to an app", func() {
// pvc clone is only supported from v1.16+
if k8sVersionGreaterEquals(f.ClientSet, 1, 16) {
validatePVCClone(defaultCloneCount, pvcPath, appPath, pvcSmartClonePath, appSmartClonePath, false, f)
validatePVCClone(defaultCloneCount, pvcPath, appPath, pvcSmartClonePath, appSmartClonePath, noPVCValidation, f)
}
})
By("create a thick-provisioned PVC-PVC clone and bind it to an app", func() {
// pvc clone is only supported from v1.16+
if !k8sVersionGreaterEquals(f.ClientSet, 1, 16) {
Skip("pvc clone is only supported from v1.16+")
}
err := deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil {
e2elog.Failf("failed to delete storageclass with error %v", err)
}
err = createRBDStorageClass(f.ClientSet, f, defaultSCName, nil, map[string]string{
"thickProvision": "true"}, deletePolicy)
if err != nil {
e2elog.Failf("failed to create storageclass with error %v", err)
}
validatePVCClone(1, pvcPath, appPath, pvcSmartClonePath, appSmartClonePath, isThickPVC, f)
err = deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil {
e2elog.Failf("failed to delete storageclass with error %v", err)
}
err = createRBDStorageClass(f.ClientSet, f, defaultSCName, nil, nil, deletePolicy)
if err != nil {
e2elog.Failf("failed to create storageclass with error %v", err)
}
})
@ -813,7 +841,7 @@ var _ = Describe("RBD", func() {
e2elog.Failf("failed to create storageclass with error %v", err)
}
validatePVCClone(1, pvcPath, appPath, pvcSmartClonePath, appSmartClonePath, true, f)
validatePVCClone(1, pvcPath, appPath, pvcSmartClonePath, appSmartClonePath, isEncryptedPVC, f)
err = deleteResource(rbdExamplePath + "storageclass.yaml")
if err != nil {
@ -838,7 +866,7 @@ var _ = Describe("RBD", func() {
}
// pvc clone is only supported from v1.16+
if v.Major > "1" || (v.Major == "1" && v.Minor >= "16") {
validatePVCClone(defaultCloneCount, rawPvcPath, rawAppPath, pvcBlockSmartClonePath, appBlockSmartClonePath, false, f)
validatePVCClone(defaultCloneCount, rawPvcPath, rawAppPath, pvcBlockSmartClonePath, appBlockSmartClonePath, noPVCValidation, f)
}
})
By("create/delete multiple PVCs and Apps", func() {

View File

@ -414,7 +414,13 @@ func validateEncryptedPVCAndAppBinding(pvcPath, appPath, kms string, f *framewor
return nil
}
func validateEncryptedPVC(f *framework.Framework, pvc *v1.PersistentVolumeClaim, app *v1.Pod) error {
type validateFunc func(f *framework.Framework, pvc *v1.PersistentVolumeClaim, app *v1.Pod) error
// noPVCValidation can be used to pass to validatePVCClone when no extra
// validation of the PVC is needed.
var noPVCValidation validateFunc = nil
func isEncryptedPVC(f *framework.Framework, pvc *v1.PersistentVolumeClaim, app *v1.Pod) error {
imageData, err := getImageInfoFromPVC(pvc.Namespace, pvc.Name, f)
if err != nil {
return err
@ -424,6 +430,16 @@ func validateEncryptedPVC(f *framework.Framework, pvc *v1.PersistentVolumeClaim,
return validateEncryptedImage(f, rbdImageSpec, app)
}
func isThickPVC(f *framework.Framework, pvc *v1.PersistentVolumeClaim, app *v1.Pod) error {
du, err := getRbdDu(f, pvc)
if err != nil {
return fmt.Errorf("failed to get allocations of RBD image: %w", err)
} else if du.UsedSize == 0 || du.UsedSize != du.ProvisionedSize {
return fmt.Errorf("backing RBD image is not thick-provisioned (%d/%d)", du.UsedSize, du.ProvisionedSize)
}
return nil
}
// validateEncryptedImage verifies that the RBD image is encrypted. The
// following checks are performed:
// - Metadata of the image should be set with the encryption state;

View File

@ -522,7 +522,7 @@ func writeDataAndCalChecksum(app *v1.Pod, opt *metav1.ListOptions, f *framework.
}
// nolint:gocyclo,gocognit // reduce complexity
func validatePVCClone(totalCount int, sourcePvcPath, sourceAppPath, clonePvcPath, clonePvcAppPath string, validateEncryption bool, f *framework.Framework) {
func validatePVCClone(totalCount int, sourcePvcPath, sourceAppPath, clonePvcPath, clonePvcAppPath string, validatePVC validateFunc, f *framework.Framework) {
var wg sync.WaitGroup
wgErrs := make([]error, totalCount)
chErrs := make([]error, totalCount)
@ -598,8 +598,8 @@ func validatePVCClone(totalCount int, sourcePvcPath, sourceAppPath, clonePvcPath
e2elog.Logf("checksum didn't match. checksum=%s and checksumclone=%s", checkSum, checkSumClone)
}
}
if wgErrs[n] == nil && validateEncryption {
wgErrs[n] = validateEncryptedPVC(f, &p, &a)
if wgErrs[n] == nil && validatePVC != nil {
wgErrs[n] = validatePVC(f, &p, &a)
}
w.Done()
}(&wg, i, *pvcClone, *appClone)
@ -791,7 +791,7 @@ func validatePVCSnapshot(totalCount int, pvcPath, appPath, snapshotPath, pvcClon
}
}
if wgErrs[n] == nil && kms != "" {
wgErrs[n] = validateEncryptedPVC(f, &p, &a)
wgErrs[n] = isEncryptedPVC(f, &p, &a)
}
w.Done()
}(&wg, i, *pvcClone, *appClone)