Skip to content

Commit

Permalink
fixes #5, add a finalizer to fix deletion during pv protection
Browse files Browse the repository at this point in the history
  • Loading branch information
rmb938 committed Dec 21, 2018
1 parent 2af57c2 commit 00f37cf
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
46 changes: 45 additions & 1 deletion controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ const annStorageProvisioner = "volume.beta.kubernetes.io/storage-provisioner"
// be dynamically provisioned. Its value is the name of the selected node.
const annSelectedNode = "volume.kubernetes.io/selected-node"

// Finalizer for PVs so we know to clean them up
const finalizerPV = "external-provisioner.volume.kubernetes.io"

// ProvisionController is a controller that provisions PersistentVolumes for
// PersistentVolumeClaims.
type ProvisionController struct {
Expand Down Expand Up @@ -857,7 +860,7 @@ func (ctrl *ProvisionController) shouldDelete(volume *v1.PersistentVolume) bool
// In 1.9+ PV protection means the object will exist briefly with a
// deletion timestamp even after our successful Delete. Ignore it.
if ctrl.kubeVersion.AtLeast(utilversion.MustParseSemantic("v1.9.0")) {
if volume.ObjectMeta.DeletionTimestamp != nil {
if !ctrl.checkFinalizer(volume, finalizerPV) && volume.ObjectMeta.DeletionTimestamp != nil {
return false
}
}
Expand Down Expand Up @@ -899,6 +902,15 @@ func (ctrl *ProvisionController) canProvision(claim *v1.PersistentVolumeClaim) e
return nil
}

func (ctrl *ProvisionController) checkFinalizer(volume *v1.PersistentVolume, finalizer string) bool {
for _, f := range volume.ObjectMeta.Finalizers {
if f == finalizer {
return true
}
}
return false
}

func (ctrl *ProvisionController) updateProvisionStats(claim *v1.PersistentVolumeClaim, err error, startTime time.Time) {
class := ""
if claim.Spec.StorageClassName != nil {
Expand Down Expand Up @@ -1034,6 +1046,11 @@ func (ctrl *ProvisionController) provisionClaimOperation(claim *v1.PersistentVol
// Set ClaimRef and the PV controller will bind and set annBoundByController for us
volume.Spec.ClaimRef = claimRef

// Add external provisioner finalizer if it doesn't already have it
if !ctrl.checkFinalizer(volume, finalizerPV) {
volume.ObjectMeta.Finalizers = append(volume.ObjectMeta.Finalizers, finalizerPV)
}

metav1.SetMetaDataAnnotation(&volume.ObjectMeta, annDynamicallyProvisioned, ctrl.provisionerName)
if ctrl.kubeVersion.AtLeast(utilversion.MustParseSemantic("v1.6.0")) {
volume.Spec.StorageClassName = claimClass
Expand Down Expand Up @@ -1138,6 +1155,33 @@ func (ctrl *ProvisionController) deleteVolumeOperation(volume *v1.PersistentVolu
return err
}

if len(newVolume.ObjectMeta.Finalizers) > 0 {
// Remove external-provisioner finalizer

// need to get the pv again because the delete has updated the object with a deletion timestamp
newVolume, err := ctrl.client.CoreV1().PersistentVolumes().Get(volume.Name, metav1.GetOptions{})
if err != nil {
// If we get an error the volume is probably gone
return nil
}
finalizers := make([]string, 0)
for _, finalizer := range newVolume.ObjectMeta.Finalizers {
if finalizer != finalizerPV {
finalizers = append(finalizers, finalizer)
}
}

newVolume.ObjectMeta.Finalizers = finalizers
if _, err = ctrl.client.CoreV1().PersistentVolumes().Update(newVolume); err != nil {
if !apierrs.IsNotFound(err) {
// Couldn't remove finalizer and the object still exists, the controller may
// try to remove the finalizer again on the next update
glog.Info(logOperation(operation, "failed to remove finalizer for persistentvolume: %v", err))
return err
}
}
}

glog.Info(logOperation(operation, "persistentvolume deleted"))

glog.Info(logOperation(operation, "succeeded"))
Expand Down
2 changes: 2 additions & 0 deletions controller/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,8 @@ func constructProvisionedVolumeWithoutStorageClassInfo(claim *v1.PersistentVolum
// TODO implement options.ProvisionerSelector parsing
// pv.Labels MUST be set to match claim.spec.selector. The provisioner MAY add additional labels.

volume.ObjectMeta.Finalizers = append(volume.ObjectMeta.Finalizers, finalizerPV)

return volume
}

Expand Down

0 comments on commit 00f37cf

Please sign in to comment.