Change:
<!-- Please use this template while reporting a bug and provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. Thanks! If the matter is security related, please disclose it privately via --What happened: I created a block EBS volume using dynamic provisioning. Then I resized the volume from 10GB to 20 GB. Both PV and block volume reflects the change, but the PVC's capacity is still 10GB. This could be caused by in-tree resize put the PVC condition under state, but no one is acting on the condition since it is block volume: /cc /sig storage What you expected to happen: PVC's capacity should be updated to 20GB How to reproduce it (as minimally and precisely as possible): Easy to reproduce using following specs: StorageClass: Claim: Pod: Anything else we need to know?: This will affect whether CSI migration should handle migration scenario for block volume resizing. Environment: Kubernetes version (use ):1.13 Cloud provider or hardware configuration: OS (e.g: ): Kernel (e.g. ): Install tools: kops Network plugin and version (if this is a network-related bug): Others:
/sig aws
/assign

Discussion:
klog.Infof("ExpandVolume.UpdatePV succeeded for volume %s", pvcWithResizeRequest.QualifiedName()) } <ins> fsVolume, _ := util.CheckVolumeModeFilesystem(volumeSpec) </ins> // 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. <del> if !volumePlugin.RequiresFSResize() { </del> <ins> if !volumePlugin.RequiresFSResize() || !fsVolume { </ins> klog.V(4).Infof("Controller resizing done for PVC %s", pvcWithResizeRequest.QualifiedName()) err := resizeMap.MarkAsResized(pvcWithResizeRequest, newSize)

ClaimSize            string ExpectedSize         string PvCheck              func(claim *v1.PersistentVolumeClaim) <del> VolumeMode           *v1.PersistentVolumeMode </del> <ins> VolumeMode           v1.PersistentVolumeMode </ins> AllowVolumeExpansion bool }

var _ = utils.SIGDescribe("Volume expand", func() { var ( <del> c           clientset.Interface ns          string err         error pvc         *v1.PersistentVolumeClaim resizableSc *storage.StorageClass </del> <ins> c               clientset.Interface ns              string err             error pvc             *v1.PersistentVolumeClaim storageClassVar *storage.StorageClass </ins> ) f := framework.NewDefaultFramework("volume-expand")

c = f.ClientSet ns = f.Namespace.Name framework.ExpectNoError(framework.WaitForAllNodesSchedulable(c, framework.TestContext.NodeSchedulableTimeout)) <ins> }) setupFunc := func(allowExpansion bool, blockVolume bool) (*v1.PersistentVolumeClaim, *storage.StorageClass, error) { </ins> test := testsuites.StorageClassTest{ <del> Name:                 "default", ClaimSize:            "2Gi", AllowVolumeExpansion: true, </del> <ins> Name:      "default", ClaimSize: "2Gi", </ins> } <del> 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") }) </del> <ins> 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 } </ins> AfterEach(func() { framework.ExpectNoError(framework.DeletePersistentVolumeClaim(c, pvc.Name, pvc.Namespace)) <del> framework.ExpectNoError(c.StorageV1().StorageClasses().Delete(resizableSc.Name, nil)) </del> <ins> framework.ExpectNoError(c.StorageV1().StorageClasses().Delete(storageClassVar.Name, nil)) </ins> }) It("should not allow expansion of pvcs without AllowVolumeExpansion property", func() { <del> test := testsuites.StorageClassTest{ Name:      "no-expansion", ClaimSize: "2Gi", } regularSC, err := createStorageClass(test, ns, "noexpand", c) framework.ExpectNoError(err, "Error creating non-expandable storage class") </del> <ins> pvc, storageClassVar, err = setupFunc(false /* allowExpansion */, false /*BlockVolume*/) framework.ExpectNoError(err, "Error creating non-expandable PVC") </ins> <del> defer func() { framework.ExpectNoError(c.StorageV1().StorageClasses().Delete(regularSC.Name, nil)) }() Expect(regularSC.AllowVolumeExpansion).To(BeNil()) </del> <ins> Expect(storageClassVar.AllowVolumeExpansion).To(BeNil()) </ins> <del> 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} </del> <ins> pvcClaims := []*v1.PersistentVolumeClaim{pvc} </ins> 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") <del> noExpandPVC, err = expandPVCSize(noExpandPVC, newSize, c) </del> <ins> pvc, err = expandPVCSize(pvc, newSize, c) </ins> Expect(err).To(HaveOccurred(), "While updating non-expandable PVC") }) It("Verify if editing PVC allows resize", func() { <ins> pvc, storageClassVar, err = setupFunc(true /* allowExpansion */, false /*BlockVolume*/) framework.ExpectNoError(err, "Error creating non-expandable PVC") </ins> By("Waiting for pvc to be in bound phase") pvcClaims := []*v1.PersistentVolumeClaim{pvc} pvs, err := framework.WaitForPVClaimBoundPhase(c, pvcClaims, framework.ClaimProvisionTimeout)

pvcConditions := pvc.Status.Conditions Expect(len(pvcConditions)).To(Equal(0), "pvc should not have conditions") }) <ins> 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") 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") }) </ins> }) func createStorageClass(t testsuites.StorageClassTest, ns string, suffix string, c clientset.Interface) (*storage.StorageClass, error) {

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