mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-11-26 08:10:20 +00:00
Move resize E2E to new resize.go file
Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
parent
3394432371
commit
374e47046f
177
e2e/resize.go
Normal file
177
e2e/resize.go
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
package e2e
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
. "github.com/onsi/gomega" // nolint
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/cloud-provider/volume/helpers"
|
||||||
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
||||||
|
testutils "k8s.io/kubernetes/test/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func expandPVCSize(c kubernetes.Interface, pvc *v1.PersistentVolumeClaim, size string, t int) error {
|
||||||
|
pvcName := pvc.Name
|
||||||
|
updatedPVC := pvc.DeepCopy()
|
||||||
|
var err error
|
||||||
|
|
||||||
|
updatedPVC, err = c.CoreV1().PersistentVolumeClaims(pvc.Namespace).Get(pvcName, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error fetching pvc %q with %v", pvcName, err)
|
||||||
|
}
|
||||||
|
timeout := time.Duration(t) * time.Minute
|
||||||
|
|
||||||
|
updatedPVC.Spec.Resources.Requests[v1.ResourceStorage] = resource.MustParse(size)
|
||||||
|
_, err = c.CoreV1().PersistentVolumeClaims(updatedPVC.Namespace).Update(updatedPVC)
|
||||||
|
Expect(err).Should(BeNil())
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
e2elog.Logf("Waiting up to %v to be in Resized state", pvc)
|
||||||
|
return wait.PollImmediate(poll, timeout, func() (bool, error) {
|
||||||
|
e2elog.Logf("waiting for PVC %s (%d seconds elapsed)", updatedPVC.Name, int(time.Since(start).Seconds()))
|
||||||
|
updatedPVC, err = c.CoreV1().PersistentVolumeClaims(updatedPVC.Namespace).Get(pvcName, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
e2elog.Logf("Error getting pvc in namespace: '%s': %v", updatedPVC.Namespace, err)
|
||||||
|
if testutils.IsRetryableAPIError(err) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
pvcConditions := updatedPVC.Status.Conditions
|
||||||
|
if len(pvcConditions) > 0 {
|
||||||
|
e2elog.Logf("pvc state %v", pvcConditions[0].Type)
|
||||||
|
if pvcConditions[0].Type == v1.PersistentVolumeClaimResizing || pvcConditions[0].Type == v1.PersistentVolumeClaimFileSystemResizePending {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if updatedPVC.Status.Capacity[v1.ResourceStorage] != resource.MustParse(size) {
|
||||||
|
e2elog.Logf("current size in status %v,expected size %v", updatedPVC.Status.Capacity[v1.ResourceStorage], resource.MustParse(size))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func resizePVCAndValidateSize(pvcPath, appPath string, f *framework.Framework) error {
|
||||||
|
size := "1Gi"
|
||||||
|
expandSize := "10Gi"
|
||||||
|
pvc, err := loadPVC(pvcPath)
|
||||||
|
if pvc == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pvc.Namespace = f.UniqueName
|
||||||
|
|
||||||
|
resizePvc, err := loadPVC(pvcPath)
|
||||||
|
if resizePvc == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
resizePvc.Namespace = f.UniqueName
|
||||||
|
|
||||||
|
app, err := loadApp(appPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pvc.Spec.Resources.Requests[v1.ResourceStorage] = resource.MustParse(size)
|
||||||
|
app.Labels = map[string]string{"app": "resize-pvc"}
|
||||||
|
app.Namespace = f.UniqueName
|
||||||
|
|
||||||
|
err = createPVCAndApp("", f, pvc, app)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
opt := metav1.ListOptions{
|
||||||
|
LabelSelector: "app=resize-pvc",
|
||||||
|
}
|
||||||
|
|
||||||
|
if *pvc.Spec.VolumeMode == v1.PersistentVolumeFilesystem {
|
||||||
|
err = checkDirSize(app, f, &opt, size)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if *pvc.Spec.VolumeMode == v1.PersistentVolumeBlock {
|
||||||
|
err = checkDeviceSize(app, f, &opt, size)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// resize PVC
|
||||||
|
err = expandPVCSize(f.ClientSet, resizePvc, expandSize, deployTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// wait for application pod to come up after resize
|
||||||
|
err = waitForPodInRunningState(app.Name, app.Namespace, f.ClientSet, deployTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if *pvc.Spec.VolumeMode == v1.PersistentVolumeFilesystem {
|
||||||
|
err = checkDirSize(app, f, &opt, expandSize)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if *pvc.Spec.VolumeMode == v1.PersistentVolumeBlock {
|
||||||
|
err = checkDeviceSize(app, f, &opt, expandSize)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = deletePVCAndApp("", f, resizePvc, app)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkDirSize(app *v1.Pod, f *framework.Framework, opt *metav1.ListOptions, size string) error {
|
||||||
|
cmd := getDirSizeCheckCmd(app.Spec.Containers[0].VolumeMounts[0].MountPath)
|
||||||
|
return checkAppMntSize(f, opt, size, cmd, app.Namespace, deployTimeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkDeviceSize(app *v1.Pod, f *framework.Framework, opt *metav1.ListOptions, size string) error {
|
||||||
|
cmd := getDeviceSizeCheckCmd(app.Spec.Containers[0].VolumeDevices[0].DevicePath)
|
||||||
|
return checkAppMntSize(f, opt, size, cmd, app.Namespace, deployTimeout)
|
||||||
|
|
||||||
|
}
|
||||||
|
func getDirSizeCheckCmd(dirPath string) string {
|
||||||
|
return fmt.Sprintf("df -h|grep %s |awk '{print $2}'", dirPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDeviceSizeCheckCmd(devPath string) string {
|
||||||
|
return fmt.Sprintf("blockdev --getsize64 %s", devPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkAppMntSize(f *framework.Framework, opt *metav1.ListOptions, size, cmd, ns string, t int) error {
|
||||||
|
timeout := time.Duration(t) * time.Minute
|
||||||
|
start := time.Now()
|
||||||
|
|
||||||
|
return wait.PollImmediate(poll, timeout, func() (bool, error) {
|
||||||
|
e2elog.Logf("executing cmd %s (%d seconds elapsed)", cmd, int(time.Since(start).Seconds()))
|
||||||
|
output, stdErr := execCommandInPod(f, cmd, ns, opt)
|
||||||
|
|
||||||
|
if stdErr != "" {
|
||||||
|
e2elog.Logf("failed to execute command in app pod %v", stdErr)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
s := resource.MustParse(strings.TrimSpace(output))
|
||||||
|
actualSize := helpers.RoundUpToGiB(s)
|
||||||
|
|
||||||
|
s = resource.MustParse(size)
|
||||||
|
expectedSize := helpers.RoundUpToGiB(s)
|
||||||
|
|
||||||
|
if actualSize != expectedSize {
|
||||||
|
e2elog.Logf("expected size %s found %s information", size, output)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
})
|
||||||
|
}
|
125
e2e/utils.go
125
e2e/utils.go
@ -19,14 +19,12 @@ import (
|
|||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
scv1 "k8s.io/api/storage/v1"
|
scv1 "k8s.io/api/storage/v1"
|
||||||
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/fields"
|
"k8s.io/apimachinery/pkg/fields"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
utilyaml "k8s.io/apimachinery/pkg/util/yaml"
|
utilyaml "k8s.io/apimachinery/pkg/util/yaml"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/cloud-provider/volume/helpers"
|
|
||||||
"k8s.io/kubernetes/pkg/client/conditions"
|
"k8s.io/kubernetes/pkg/client/conditions"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
||||||
@ -879,126 +877,3 @@ func checkDataPersist(pvcPath, appPath string, f *framework.Framework) error {
|
|||||||
err = deletePVCAndApp("", f, pvc, app)
|
err = deletePVCAndApp("", f, pvc, app)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func expandPVCSize(c kubernetes.Interface, pvc *v1.PersistentVolumeClaim, size string, t int) error {
|
|
||||||
pvcName := pvc.Name
|
|
||||||
updatedPVC := pvc.DeepCopy()
|
|
||||||
var err error
|
|
||||||
|
|
||||||
updatedPVC, err = c.CoreV1().PersistentVolumeClaims(pvc.Namespace).Get(pvcName, metav1.GetOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error fetching pvc %q with %v", pvcName, err)
|
|
||||||
}
|
|
||||||
timeout := time.Duration(t) * time.Minute
|
|
||||||
|
|
||||||
updatedPVC.Spec.Resources.Requests[v1.ResourceStorage] = resource.MustParse(size)
|
|
||||||
_, err = c.CoreV1().PersistentVolumeClaims(updatedPVC.Namespace).Update(updatedPVC)
|
|
||||||
Expect(err).Should(BeNil())
|
|
||||||
|
|
||||||
start := time.Now()
|
|
||||||
e2elog.Logf("Waiting up to %v to be in Resized state", pvc)
|
|
||||||
return wait.PollImmediate(poll, timeout, func() (bool, error) {
|
|
||||||
e2elog.Logf("waiting for PVC %s (%d seconds elapsed)", updatedPVC.Name, int(time.Since(start).Seconds()))
|
|
||||||
updatedPVC, err = c.CoreV1().PersistentVolumeClaims(updatedPVC.Namespace).Get(pvcName, metav1.GetOptions{})
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Logf("Error getting pvc in namespace: '%s': %v", updatedPVC.Namespace, err)
|
|
||||||
if testutils.IsRetryableAPIError(err) {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
pvcConditions := updatedPVC.Status.Conditions
|
|
||||||
if len(pvcConditions) > 0 {
|
|
||||||
e2elog.Logf("pvc state %v", pvcConditions[0].Type)
|
|
||||||
if pvcConditions[0].Type == v1.PersistentVolumeClaimResizing || pvcConditions[0].Type == v1.PersistentVolumeClaimFileSystemResizePending {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if updatedPVC.Status.Capacity[v1.ResourceStorage] != resource.MustParse(size) {
|
|
||||||
e2elog.Logf("current size in status %v,expected size %v", updatedPVC.Status.Capacity[v1.ResourceStorage], resource.MustParse(size))
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func resizePVCAndValidateSize(pvcPath, appPath string, f *framework.Framework) error {
|
|
||||||
size := "1Gi"
|
|
||||||
expandSize := "10Gi"
|
|
||||||
pvc, err := loadPVC(pvcPath)
|
|
||||||
if pvc == nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pvc.Namespace = f.UniqueName
|
|
||||||
|
|
||||||
resizePvc, err := loadPVC(pvcPath)
|
|
||||||
if resizePvc == nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
resizePvc.Namespace = f.UniqueName
|
|
||||||
|
|
||||||
app, err := loadApp(appPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pvc.Spec.Resources.Requests[v1.ResourceStorage] = resource.MustParse(size)
|
|
||||||
app.Labels = map[string]string{"app": "resize-pvc"}
|
|
||||||
app.Namespace = f.UniqueName
|
|
||||||
|
|
||||||
err = createPVCAndApp("", f, pvc, app)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
opt := metav1.ListOptions{
|
|
||||||
LabelSelector: "app=resize-pvc",
|
|
||||||
}
|
|
||||||
err = checkDirSize(app, f, &opt, size, deployTimeout)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// resize PVC
|
|
||||||
err = expandPVCSize(f.ClientSet, resizePvc, expandSize, deployTimeout)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// wait for application pod to come up after resize
|
|
||||||
err = waitForPodInRunningState(app.Name, app.Namespace, f.ClientSet, deployTimeout)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = checkDirSize(app, f, &opt, expandSize, deployTimeout)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = deletePVCAndApp("", f, resizePvc, app)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkDirSize(app *v1.Pod, f *framework.Framework, opt *metav1.ListOptions, size string, t int) error {
|
|
||||||
dirPath := app.Spec.Containers[0].VolumeMounts[0].MountPath
|
|
||||||
timeout := time.Duration(t) * time.Minute
|
|
||||||
start := time.Now()
|
|
||||||
|
|
||||||
return wait.PollImmediate(poll, timeout, func() (bool, error) {
|
|
||||||
e2elog.Logf("checking directory size %s (%d seconds elapsed)", dirPath, int(time.Since(start).Seconds()))
|
|
||||||
output, stdErr := execCommandInPod(f, fmt.Sprintf("df -h|grep %s |awk '{print $2}'", dirPath), app.Namespace, opt)
|
|
||||||
|
|
||||||
if stdErr != "" {
|
|
||||||
e2elog.Logf("failed to execute command in app pod %v", stdErr)
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
s := resource.MustParse(strings.TrimSpace(output))
|
|
||||||
actualSize := helpers.RoundUpToGiB(s)
|
|
||||||
|
|
||||||
s = resource.MustParse(size)
|
|
||||||
expectedSize := helpers.RoundUpToGiB(s)
|
|
||||||
|
|
||||||
if actualSize != expectedSize {
|
|
||||||
e2elog.Logf("expected directory size %s found %s information", size, output)
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user