mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-11-09 16:00:22 +00:00
4c96ad3c85
With client-go v1.18.0 there is a change where Signatures on methods in generated clientsets, dynamic, metadata, and scale clients have been modified to accept context.Context as a first argument. Signatures of Create, Update, and Patch methods have been updated to accept CreateOptions, UpdateOptions and PatchOptions respectively. Signatures of Delete and DeleteCollection methods now accept DeleteOptions by value instead of by reference The framework.RunkubectlInput now accepts namespace as the first parameter which is also accommodated with this PR. Signed-off-by: Humble Chirammal hchiramm@redhat.com
183 lines
5.5 KiB
Go
183 lines
5.5 KiB
Go
package e2e
|
|
|
|
import (
|
|
"context"
|
|
"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(context.TODO(), 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(context.TODO(), updatedPVC, metav1.UpdateOptions{})
|
|
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(context.TODO(), 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",
|
|
}
|
|
|
|
pvc, err = f.ClientSet.CoreV1().PersistentVolumeClaims(pvc.Namespace).Get(context.TODO(), pvc.Name, metav1.GetOptions{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
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
|
|
})
|
|
}
|