diff --git a/e2e/rbd.go b/e2e/rbd.go index 344d269f6..1fb3105ef 100644 --- a/e2e/rbd.go +++ b/e2e/rbd.go @@ -184,6 +184,18 @@ func createORDeleteRbdResources(action kubectlAction) { } } +func validateRBDSnapshotCount(f *framework.Framework, count int, pool, image string) error{ + snapshotList, err := listRBDSnapshots(f, pool, image) + if err != nil { + return fmt.Errorf("failed to list RBD snapshots: %v", err) + } + if len(snapshotList) != count { + return fmt.Errorf("RBD snapshots count not mactching, snapshot count for image %s/%s %d, expected %d", pool, image, len(snapshotList), count) + } + + return nil +} + func validateRBDImageCount(f *framework.Framework, count int, pool string) { imageList, err := listRBDImages(f, pool) if err != nil { diff --git a/e2e/rbd_helper.go b/e2e/rbd_helper.go index 02da4bfbc..a3c2d3b84 100644 --- a/e2e/rbd_helper.go +++ b/e2e/rbd_helper.go @@ -248,6 +248,13 @@ type imageInfoFromPVC struct { pvName string } +type SnapInfo struct { + ID int `json:"id"` + Name string `json:"name"` + Size int64 `json:"size"` + Protected string `json:"protected"` +} + // getImageInfoFromPVC reads volume handle of the bound PV to the passed in PVC, // and returns imageInfoFromPVC or error. func getImageInfoFromPVC(pvcNamespace, pvcName string, f *framework.Framework) (imageInfoFromPVC, error) { @@ -715,6 +722,25 @@ func librbdSupportsVolumeGroupSnapshot(f *framework.Framework) (bool, error) { return strings.TrimSpace(stdout) == "0", nil } +func listRBDSnapshots(f *framework.Framework, pool, image string) ([]SnapInfo, error) { + var snapInfos []SnapInfo + command := fmt.Sprintf("rbd snap ls --format=json %s %s", rbdOptions(pool), image) + stdout, stdErr, err := execCommandInToolBoxPod(f, command, rookNamespace) + if err != nil { + return snapInfos, err + } + if stdErr != "" { + return snapInfos, fmt.Errorf("failed to list RBD snapshots %v", stdErr) + } + + err = json.Unmarshal([]byte(stdout), &snapInfos) + if err != nil { + return snapInfos, err + } + + return snapInfos, nil +} + func listRBDImages(f *framework.Framework, pool string) ([]string, error) { var imgInfos []string diff --git a/e2e/utils.go b/e2e/utils.go index 04cc03f2b..52bd25150 100644 --- a/e2e/utils.go +++ b/e2e/utils.go @@ -1003,6 +1003,16 @@ func validatePVCClone( if wgErrs[n] == nil && validatePVC != nil && kms != noKMS { wgErrs[n] = validatePVC(f, &p, &a) } + if wgErrs[n] == nil { + // validate RBD snapshot under temporary clone is not deleted. + imageData, err := getImageInfoFromPVC(p.Namespace, name, f) + if err != nil { + wgErrs[n] = err + } else { + cloneRBDImageName := fmt.Sprintf("%s-temp", imageData.imageName) + wgErrs[n] = validateRBDSnapshotCount(f, 1, defaultRBDPool, cloneRBDImageName) + } + } wg.Done() }(i, *pvcClone, *appClone) }