Skip to content

Commit ea04a85

Browse files
committed
fix: add annotation to pv after resize if filesystem resize is
necessary. delete when pvc.status.capacity >= pv.spec.capacity
1 parent 132dd95 commit ea04a85

File tree

2 files changed

+61
-17
lines changed

2 files changed

+61
-17
lines changed

pkg/controller/controller.go

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,11 @@ func (ctrl *resizeController) updatePVC(oldObj, newObj interface{}) {
172172
return
173173
}
174174

175-
newSize := newPVC.Spec.Resources.Requests[v1.ResourceStorage]
176-
oldSize := oldPVC.Spec.Resources.Requests[v1.ResourceStorage]
175+
newReq := newPVC.Spec.Resources.Requests[v1.ResourceStorage]
176+
oldReq := oldPVC.Spec.Resources.Requests[v1.ResourceStorage]
177+
178+
newCap := newPVC.Status.Capacity[v1.ResourceStorage]
179+
oldCap := oldPVC.Status.Capacity[v1.ResourceStorage]
177180

178181
newResizerName := newPVC.Annotations[util.VolumeResizerKey]
179182
oldResizerName := oldPVC.Annotations[util.VolumeResizerKey]
@@ -192,23 +195,27 @@ func (ctrl *resizeController) updatePVC(oldObj, newObj interface{}) {
192195
// know how to support resizing of a "un-annotated" in-tree PVC. When in-tree resizer does add the annotation, a second
193196
// update even will be received and we add the pvc to workqueue. If annotation matches the registered driver name in
194197
// csi_resizer object, we proceeds with expansion internally or we discard the PVC.
195-
// 2. An already expanded in-tree PVC:
198+
// 3. An already expanded in-tree PVC:
196199
// An in-tree PVC is resized with in-tree resizer. And later, CSI migration is turned on and resizer name is updated from
197200
// in-tree resizer name to CSI driver name.
198-
if newSize.Cmp(oldSize) > 0 || newResizerName != oldResizerName {
201+
if newReq.Cmp(oldReq) > 0 || newResizerName != oldResizerName {
199202
ctrl.addPVC(newObj)
200203
} else {
201204
// PVC's size not changed, so this Update event maybe caused by:
202205
//
203206
// 1. Administrators or users introduce other changes(such as add labels, modify annotations, etc.)
204207
// unrelated to volume resize.
205208
// 2. Informer resynced the PVC and send this Update event without any changes.
209+
// 3. PV's filesystem has recently been resized and requires removal of its resize annotation
206210
//
207-
// If it is case 1, we can just discard this event. If case 2, we need to put it into the queue to
211+
// If it is case 1, we can just discard this event. If case 2 or 3, we need to put it into the queue to
208212
// perform a resync operation.
209213
if newPVC.ResourceVersion == oldPVC.ResourceVersion {
210214
// This is case 2.
211215
ctrl.addPVC(newObj)
216+
} else if newCap.Cmp(oldCap) > 0 {
217+
// This is case 3
218+
ctrl.addPVC(newObj)
212219
}
213220
}
214221
}
@@ -300,16 +307,10 @@ func (ctrl *resizeController) syncPVC(key string) error {
300307
return fmt.Errorf("expected PVC got: %v", pvcObject)
301308
}
302309

303-
if !ctrl.pvcNeedResize(pvc) {
304-
klog.V(4).Infof("No need to resize PVC %q", util.PVCKey(pvc))
305-
return nil
306-
}
307-
308310
volumeObj, exists, err := ctrl.volumes.GetByKey(pvc.Spec.VolumeName)
309311
if err != nil {
310312
return fmt.Errorf("Get PV %q of pvc %q failed: %v", pvc.Spec.VolumeName, util.PVCKey(pvc), err)
311313
}
312-
313314
if !exists {
314315
klog.Warningf("PV %q bound to PVC %s not found", pvc.Spec.VolumeName, util.PVCKey(pvc))
315316
return nil
@@ -320,6 +321,16 @@ func (ctrl *resizeController) syncPVC(key string) error {
320321
return fmt.Errorf("expected volume but got %+v", volumeObj)
321322
}
322323

324+
if ctrl.isFsResizeComplete(pvc, pv) && metav1.HasAnnotation(pv.ObjectMeta, util.AnnPreResizeCapacity) {
325+
if err := ctrl.deletePreResizeCapAnnotation(pv); err != nil {
326+
return fmt.Errorf("Failed removing annotation %s from pv %q: %v", util.AnnPreResizeCapacity, pv.Name, err)
327+
}
328+
}
329+
330+
if !ctrl.pvcNeedResize(pvc) {
331+
klog.V(4).Infof("No need to resize PVC %q", util.PVCKey(pvc))
332+
return nil
333+
}
323334
if !ctrl.pvNeedResize(pvc, pv) {
324335
klog.V(4).Infof("No need to resize PV %q", pv.Name)
325336
return nil
@@ -376,6 +387,13 @@ func (ctrl *resizeController) pvNeedResize(pvc *v1.PersistentVolumeClaim, pv *v1
376387
return true
377388
}
378389

390+
// isFsResizeComplete returns true if pvc.Status.Capacity >= pv.Spec.Capacity
391+
func (ctrl *resizeController) isFsResizeComplete(pvc *v1.PersistentVolumeClaim, pv *v1.PersistentVolume) bool {
392+
klog.V(4).Infof("pv %q capacity = %v, pvc %s capacity = %v", pv.Name, pv.Spec.Capacity[v1.ResourceStorage], util.PVCKey(pvc), pvc.Status.Capacity[v1.ResourceStorage])
393+
pvcCap, pvCap := pvc.Status.Capacity[v1.ResourceStorage], pv.Spec.Capacity[v1.ResourceStorage]
394+
return pvcCap.Cmp(pvCap) >= 0
395+
}
396+
379397
// resizePVC will:
380398
// 1. Mark pvc as resizing.
381399
// 2. Resize the volume and the pv object.
@@ -446,7 +464,7 @@ func (ctrl *resizeController) resizeVolume(
446464
}
447465
klog.V(4).Infof("Resize volume succeeded for volume %q, start to update PV's capacity", pv.Name)
448466

449-
err = ctrl.updatePVCapacity(pv, newSize)
467+
err = ctrl.updatePVCapacity(pv, pvc.Status.Capacity[v1.ResourceStorage], newSize, fsResizeRequired)
450468
if err != nil {
451469
return newSize, fsResizeRequired, err
452470
}
@@ -533,11 +551,34 @@ func (ctrl *resizeController) patchClaim(oldPVC, newPVC *v1.PersistentVolumeClai
533551
return updatedClaim, nil
534552
}
535553

536-
func (ctrl *resizeController) updatePVCapacity(pv *v1.PersistentVolume, newCapacity resource.Quantity) error {
554+
func (ctrl *resizeController) deletePreResizeCapAnnotation(pv *v1.PersistentVolume) error {
555+
// if the pv does not have a resize annotation skip the entire process
556+
if !metav1.HasAnnotation(pv.ObjectMeta, util.AnnPreResizeCapacity) {
557+
return nil
558+
}
559+
pvClone := pv.DeepCopy()
560+
delete(pvClone.ObjectMeta.Annotations, util.AnnPreResizeCapacity)
561+
562+
_, err := ctrl.patchPersistentVolume(pv, pvClone)
563+
return err
564+
}
565+
566+
func (ctrl *resizeController) updatePVCapacity(pv *v1.PersistentVolume, oldCapacity, newCapacity resource.Quantity, fsResizeRequired bool) error {
537567
klog.V(4).Infof("Resize volume succeeded for volume %q, start to update PV's capacity", pv.Name)
538568
newPV := pv.DeepCopy()
539569
newPV.Spec.Capacity[v1.ResourceStorage] = newCapacity
540570

571+
if fsResizeRequired {
572+
// if the pv already has a resize annotation skip
573+
if metav1.HasAnnotation(pv.ObjectMeta, util.AnnPreResizeCapacity) {
574+
return nil
575+
}
576+
if newPV.ObjectMeta.Annotations == nil {
577+
newPV.ObjectMeta.Annotations = make(map[string]string)
578+
}
579+
newPV.ObjectMeta.Annotations[util.AnnPreResizeCapacity] = (&oldCapacity).String()
580+
}
581+
541582
_, err := ctrl.patchPersistentVolume(pv, newPV)
542583
if err != nil {
543584
return fmt.Errorf("updating capacity of PV %q to %s failed: %v", pv.Name, newCapacity.String(), err)

pkg/util/util.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,13 @@ import (
2727
"k8s.io/apimachinery/pkg/util/strategicpatch"
2828
)
2929

30-
var knownResizeConditions = map[v1.PersistentVolumeClaimConditionType]bool{
31-
v1.PersistentVolumeClaimResizing: true,
32-
v1.PersistentVolumeClaimFileSystemResizePending: true,
33-
}
30+
var (
31+
knownResizeConditions = map[v1.PersistentVolumeClaimConditionType]bool{
32+
v1.PersistentVolumeClaimResizing: true,
33+
v1.PersistentVolumeClaimFileSystemResizePending: true,
34+
}
35+
AnnPreResizeCapacity = "volume.kubernetes.io/pre-resize-capacity"
36+
)
3437

3538
// PVCKey returns an unique key of a PVC object,
3639
func PVCKey(pvc *v1.PersistentVolumeClaim) string {

0 commit comments

Comments
 (0)