Skip to content

Commit

Permalink
sig-storage-lib changes to support PV Deletion protection finalizer
Browse files Browse the repository at this point in the history
Signed-off-by: Deepak Kinni <[email protected]>
  • Loading branch information
Deepak Kinni committed Nov 5, 2021
1 parent f863560 commit 9e0046f
Show file tree
Hide file tree
Showing 2 changed files with 452 additions and 76 deletions.
90 changes: 79 additions & 11 deletions controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,28 @@ func (ctrl *ProvisionController) syncVolume(ctx context.Context, obj interface{}
if !ok {
return fmt.Errorf("expected volume but got %+v", obj)
}
var modifiedFinalizers []string
var modified bool
reclaimPolicy := volume.Spec.PersistentVolumeReclaimPolicy
// Check if the `addFinalizer` config option is disabled, i.e, rollback scenario, or the reclaim policy is changed
// to `Retain` or `Recycle`
if !ctrl.addFinalizer || reclaimPolicy == v1.PersistentVolumeReclaimRetain || reclaimPolicy == v1.PersistentVolumeReclaimRecycle {
modifiedFinalizers, modified = removeFinalizer(volume.ObjectMeta.Finalizers, finalizerPV)
}
// Add the finalizer only if `addFinalizer` config option is enabled, finalizer doesn't exist and PV is not already
// under deletion.
if ctrl.addFinalizer && reclaimPolicy == v1.PersistentVolumeReclaimDelete && volume.DeletionTimestamp == nil {
modifiedFinalizers, modified = addFinalizer(volume.ObjectMeta.Finalizers, finalizerPV)
}

if modified {
volume.ObjectMeta.Finalizers = modifiedFinalizers
newVolume, err := ctrl.updatePersistentVolume(ctx, volume)
if err != nil {
return fmt.Errorf("failed to modify finalizers to %+v on volume %s err: %+v", modifiedFinalizers, volume.Name, err)
}
volume = newVolume
}

if ctrl.shouldDelete(ctx, volume) {
startTime := time.Now()
Expand Down Expand Up @@ -1174,10 +1196,15 @@ func (ctrl *ProvisionController) shouldDelete(ctx context.Context, volume *v1.Pe
}
}

if ctrl.addFinalizer && !ctrl.checkFinalizer(volume, finalizerPV) && volume.ObjectMeta.DeletionTimestamp != nil {
return false
} else if volume.ObjectMeta.DeletionTimestamp != nil {
return false
if ctrl.addFinalizer {
if !ctrl.checkFinalizer(volume, finalizerPV) && volume.ObjectMeta.DeletionTimestamp != nil {
// The finalizer was removed, i.e. the volume has been already deleted.
return false
}
} else {
if volume.ObjectMeta.DeletionTimestamp != nil {
return false
}
}

if volume.Status.Phase != v1.VolumeReleased {
Expand Down Expand Up @@ -1243,6 +1270,22 @@ func (ctrl *ProvisionController) updateDeleteStats(volume *v1.PersistentVolume,
}
}

func (ctrl *ProvisionController) updatePersistentVolume(ctx context.Context, volume *v1.PersistentVolume) (*v1.PersistentVolume, error) {
if !metav1.HasAnnotation(volume.ObjectMeta, annDynamicallyProvisioned) {
return volume, nil
}
provisionedBy := volume.Annotations[annDynamicallyProvisioned]
migratedTo := volume.Annotations[annMigratedTo]
if provisionedBy != ctrl.provisionerName && migratedTo != ctrl.provisionerName {
return volume, nil
}
newVolume, err := ctrl.client.CoreV1().PersistentVolumes().Update(ctx, volume, metav1.UpdateOptions{})
if err != nil {
return volume, err
}
return newVolume, nil
}

// rescheduleProvisioning signal back to the scheduler to retry dynamic provisioning
// by removing the annSelectedNode annotation
func (ctrl *ProvisionController) rescheduleProvisioning(ctx context.Context, claim *v1.PersistentVolumeClaim) error {
Expand Down Expand Up @@ -1459,15 +1502,10 @@ func (ctrl *ProvisionController) deleteVolumeOperation(ctx context.Context, volu
if !ok {
return fmt.Errorf("expected volume but got %+v", volumeObj)
}
finalizers := make([]string, 0)
for _, finalizer := range newVolume.ObjectMeta.Finalizers {
if finalizer != finalizerPV {
finalizers = append(finalizers, finalizer)
}
}
finalizers, modified := removeFinalizer(newVolume.ObjectMeta.Finalizers, finalizerPV)

// Only update the finalizers if we actually removed something
if len(finalizers) != len(newVolume.ObjectMeta.Finalizers) {
if modified {
newVolume.ObjectMeta.Finalizers = finalizers
if _, err = ctrl.client.CoreV1().PersistentVolumes().Update(ctx, newVolume, metav1.UpdateOptions{}); err != nil {
if !apierrs.IsNotFound(err) {
Expand All @@ -1490,6 +1528,36 @@ func (ctrl *ProvisionController) deleteVolumeOperation(ctx context.Context, volu
return nil
}

func removeFinalizer(finalizers []string, finalizerToRemove string) ([]string, bool) {
modified := false
modifiedFinalizers := make([]string, 0)
for _, finalizer := range finalizers {
if finalizer != finalizerToRemove {
modifiedFinalizers = append(modifiedFinalizers, finalizer)
}
}
if len(modifiedFinalizers) == 0 {
modifiedFinalizers = nil
}
if len(modifiedFinalizers) != len(finalizers) {
modified = true
}
return modifiedFinalizers, modified
}

func addFinalizer(finalizers []string, finalizerToAdd string) ([]string, bool) {
modifiedFinalizers := make([]string, 0)
for _, finalizer := range finalizers {
if finalizer == finalizerToAdd {
// finalizer already exists
return finalizers, false
}
}
modifiedFinalizers = append(modifiedFinalizers, finalizers...)
modifiedFinalizers = append(modifiedFinalizers, finalizerToAdd)
return modifiedFinalizers, true
}

func logOperation(operation, format string, a ...interface{}) string {
return fmt.Sprintf(fmt.Sprintf("%s: %s", operation, format), a...)
}
Expand Down
Loading

0 comments on commit 9e0046f

Please sign in to comment.