Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix block volume expansion #77317

Merged
merged 1 commit into from May 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion pkg/volume/util/operationexecutor/operation_generator.go
Expand Up @@ -1499,10 +1499,11 @@ func (og *operationGenerator) GenerateExpandVolumeFunc(
klog.Infof("ExpandVolume.UpdatePV succeeded for volume %s", pvcWithResizeRequest.QualifiedName())
}

fsVolume, _ := util.CheckVolumeModeFilesystem(volumeSpec)
// No Cloudprovider resize needed, lets mark resizing as done
// Rest of the volume expand controller code will assume PVC as *not* resized until pvc.Status.Size
// reflects user requested size.
if !volumePlugin.RequiresFSResize() {
if !volumePlugin.RequiresFSResize() || !fsVolume {
klog.V(4).Infof("Controller resizing done for PVC %s", pvcWithResizeRequest.QualifiedName())
err := resizeMap.MarkAsResized(pvcWithResizeRequest, newSize)

Expand Down
2 changes: 1 addition & 1 deletion test/e2e/storage/testsuites/provisioning.go
Expand Up @@ -53,7 +53,7 @@ type StorageClassTest struct {
ClaimSize string
ExpectedSize string
PvCheck func(claim *v1.PersistentVolumeClaim)
VolumeMode *v1.PersistentVolumeMode
VolumeMode v1.PersistentVolumeMode
AllowVolumeExpansion bool
}

Expand Down
109 changes: 69 additions & 40 deletions test/e2e/storage/volume_expand.go
Expand Up @@ -42,11 +42,11 @@ const (

var _ = utils.SIGDescribe("Volume expand", func() {
var (
c clientset.Interface
ns string
err error
pvc *v1.PersistentVolumeClaim
resizableSc *storage.StorageClass
c clientset.Interface
ns string
err error
pvc *v1.PersistentVolumeClaim
storageClassVar *storage.StorageClass
)

f := framework.NewDefaultFramework("volume-expand")
Expand All @@ -55,61 +55,58 @@ var _ = utils.SIGDescribe("Volume expand", func() {
c = f.ClientSet
ns = f.Namespace.Name
framework.ExpectNoError(framework.WaitForAllNodesSchedulable(c, framework.TestContext.NodeSchedulableTimeout))
})

setupFunc := func(allowExpansion bool, blockVolume bool) (*v1.PersistentVolumeClaim, *storage.StorageClass, error) {
test := testsuites.StorageClassTest{
Name: "default",
ClaimSize: "2Gi",
AllowVolumeExpansion: true,
Name: "default",
ClaimSize: "2Gi",
}
resizableSc, err = createStorageClass(test, ns, "resizing", c)
framework.ExpectNoError(err, "Error creating resizable storage class")
Expect(resizableSc.AllowVolumeExpansion).NotTo(BeNil())
Expect(*resizableSc.AllowVolumeExpansion).To(BeTrue())

pvc = newClaim(test, ns, "default")
pvc.Spec.StorageClassName = &resizableSc.Name
pvc, err = c.CoreV1().PersistentVolumeClaims(pvc.Namespace).Create(pvc)
framework.ExpectNoError(err, "Error creating pvc")
})
if allowExpansion {
test.AllowVolumeExpansion = true
}
if blockVolume {
test.VolumeMode = v1.PersistentVolumeBlock
}

sc, err := createStorageClass(test, ns, "resizing", c)
framework.ExpectNoError(err, "Error creating storage class for resizing")

tPVC := newClaim(test, ns, "default")
tPVC.Spec.StorageClassName = &sc.Name
tPVC, err = c.CoreV1().PersistentVolumeClaims(tPVC.Namespace).Create(tPVC)
if err != nil {
return nil, sc, err
}
return tPVC, sc, nil
}

AfterEach(func() {
framework.ExpectNoError(framework.DeletePersistentVolumeClaim(c, pvc.Name, pvc.Namespace))
framework.ExpectNoError(c.StorageV1().StorageClasses().Delete(resizableSc.Name, nil))
framework.ExpectNoError(c.StorageV1().StorageClasses().Delete(storageClassVar.Name, nil))
})

It("should not allow expansion of pvcs without AllowVolumeExpansion property", func() {
test := testsuites.StorageClassTest{
Name: "no-expansion",
ClaimSize: "2Gi",
}
regularSC, err := createStorageClass(test, ns, "noexpand", c)
framework.ExpectNoError(err, "Error creating non-expandable storage class")
pvc, storageClassVar, err = setupFunc(false /* allowExpansion */, false /*BlockVolume*/)
framework.ExpectNoError(err, "Error creating non-expandable PVC")

defer func() {
framework.ExpectNoError(c.StorageV1().StorageClasses().Delete(regularSC.Name, nil))
}()
Expect(regularSC.AllowVolumeExpansion).To(BeNil())
Expect(storageClassVar.AllowVolumeExpansion).To(BeNil())

noExpandPVC := newClaim(test, ns, "noexpand")
noExpandPVC.Spec.StorageClassName = &regularSC.Name
noExpandPVC, err = c.CoreV1().PersistentVolumeClaims(noExpandPVC.Namespace).Create(noExpandPVC)
framework.ExpectNoError(err, "Error creating pvc")

defer func() {
framework.ExpectNoError(framework.DeletePersistentVolumeClaim(c, noExpandPVC.Name, noExpandPVC.Namespace))
}()

pvcClaims := []*v1.PersistentVolumeClaim{noExpandPVC}
pvcClaims := []*v1.PersistentVolumeClaim{pvc}
pvs, err := framework.WaitForPVClaimBoundPhase(c, pvcClaims, framework.ClaimProvisionTimeout)
framework.ExpectNoError(err, "Failed waiting for PVC to be bound %v", err)
Expect(len(pvs)).To(Equal(1))

By("Expanding non-expandable pvc")
newSize := resource.MustParse("6Gi")
noExpandPVC, err = expandPVCSize(noExpandPVC, newSize, c)
pvc, err = expandPVCSize(pvc, newSize, c)
Expect(err).To(HaveOccurred(), "While updating non-expandable PVC")
})

It("Verify if editing PVC allows resize", func() {
pvc, storageClassVar, err = setupFunc(true /* allowExpansion */, false /*BlockVolume*/)
framework.ExpectNoError(err, "Error creating non-expandable PVC")

By("Waiting for pvc to be in bound phase")
pvcClaims := []*v1.PersistentVolumeClaim{pvc}
pvs, err := framework.WaitForPVClaimBoundPhase(c, pvcClaims, framework.ClaimProvisionTimeout)
Expand Down Expand Up @@ -166,6 +163,38 @@ var _ = utils.SIGDescribe("Volume expand", func() {
pvcConditions := pvc.Status.Conditions
Expect(len(pvcConditions)).To(Equal(0), "pvc should not have conditions")
})

It("should allow expansion of block volumes", func() {
pvc, storageClassVar, err = setupFunc(true /*allowExpansion*/, true /*blockVolume*/)

By("Waiting for pvc to be in bound phase")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi, when moving these tests to the framework, they will need to be able to handle delayed binding, so the pod needs to be created first.

pvcClaims := []*v1.PersistentVolumeClaim{pvc}
pvs, err := framework.WaitForPVClaimBoundPhase(c, pvcClaims, framework.ClaimProvisionTimeout)
framework.ExpectNoError(err, "Failed waiting for PVC to be bound %v", err)
Expect(len(pvs)).To(Equal(1))

By("Expanding current pvc")
newSize := resource.MustParse("6Gi")
pvc, err = expandPVCSize(pvc, newSize, c)
framework.ExpectNoError(err, "While updating pvc for more size")
Expect(pvc).NotTo(BeNil())

pvcSize := pvc.Spec.Resources.Requests[v1.ResourceStorage]
if pvcSize.Cmp(newSize) != 0 {
framework.Failf("error updating pvc size %q", pvc.Name)
}

By("Waiting for cloudprovider resize to finish")
err = waitForControllerVolumeResize(pvc, c, totalResizeWaitPeriod)
framework.ExpectNoError(err, "While waiting for pvc resize to finish")

By("Waiting for file system resize to finish")
pvc, err = waitForFSResize(pvc, c)
framework.ExpectNoError(err, "while waiting for fs resize to finish")

pvcConditions := pvc.Status.Conditions
Expect(len(pvcConditions)).To(Equal(0), "pvc should not have conditions")
})
})

func createStorageClass(t testsuites.StorageClassTest, ns string, suffix string, c clientset.Interface) (*storage.StorageClass, error) {
Expand Down
7 changes: 6 additions & 1 deletion test/e2e/storage/volume_provisioning.go
Expand Up @@ -1034,7 +1034,12 @@ func getClaim(claimSize string, ns string) *v1.PersistentVolumeClaim {
}

func newClaim(t testsuites.StorageClassTest, ns, suffix string) *v1.PersistentVolumeClaim {
return getClaim(t.ClaimSize, ns)
claim := getClaim(t.ClaimSize, ns)
if t.VolumeMode == v1.PersistentVolumeBlock {
blockVolumeMode := v1.PersistentVolumeBlock
claim.Spec.VolumeMode = &blockVolumeMode
}
return claim
}

func getDefaultPluginName() string {
Expand Down