const createProvisionedPVRetryCount … const createProvisionedPVInterval … type CSINameTranslator … type CSIMigratedPluginManager … type PersistentVolumeController … // syncClaim is the main controller method to decide what to do with a claim. // It's invoked by appropriate cache.Controller callbacks when a claim is // created, updated or periodically synced. We do not differentiate between // these events. // For easier readability, it was split into syncUnboundClaim and syncBoundClaim // methods. func (ctrl *PersistentVolumeController) syncClaim(ctx context.Context, claim *v1.PersistentVolumeClaim) error { … } // checkVolumeSatisfyClaim checks if the volume requested by the claim satisfies the requirements of the claim func checkVolumeSatisfyClaim(volume *v1.PersistentVolume, claim *v1.PersistentVolumeClaim) error { … } // emitEventForUnboundDelayBindingClaim generates informative event for claim // if it's in delay binding mode and not bound yet. func (ctrl *PersistentVolumeController) emitEventForUnboundDelayBindingClaim(claim *v1.PersistentVolumeClaim) error { … } // syncUnboundClaim is the main controller method to decide what to do with an // unbound claim. func (ctrl *PersistentVolumeController) syncUnboundClaim(ctx context.Context, claim *v1.PersistentVolumeClaim) error { … } // syncBoundClaim is the main controller method to decide what to do with a // bound claim. func (ctrl *PersistentVolumeController) syncBoundClaim(ctx context.Context, claim *v1.PersistentVolumeClaim) error { … } // syncVolume is the main controller method to decide what to do with a volume. // It's invoked by appropriate cache.Controller callbacks when a volume is // created, updated or periodically synced. We do not differentiate between // these events. func (ctrl *PersistentVolumeController) syncVolume(ctx context.Context, volume *v1.PersistentVolume) error { … } // updateClaimStatus saves new claim.Status to API server. // Parameters: // // claim - claim to update // phase - phase to set // volume - volume which Capacity is set into claim.Status.Capacity and VolumeAttributesClassName is set into claim.Status.CurrentVolumeAttributesClassName func (ctrl *PersistentVolumeController) updateClaimStatus(ctx context.Context, claim *v1.PersistentVolumeClaim, phase v1.PersistentVolumeClaimPhase, volume *v1.PersistentVolume) (*v1.PersistentVolumeClaim, error) { … } // updateClaimStatusWithEvent saves new claim.Status to API server and emits // given event on the claim. It saves the status and emits the event only when // the status has actually changed from the version saved in API server. // Parameters: // // claim - claim to update // phase - phase to set // volume - volume which Capacity is set into claim.Status.Capacity and VolumeAttributesClassName is set into claim.Status.CurrentVolumeAttributesClassName // eventtype, reason, message - event to send, see EventRecorder.Event() func (ctrl *PersistentVolumeController) updateClaimStatusWithEvent(ctx context.Context, claim *v1.PersistentVolumeClaim, phase v1.PersistentVolumeClaimPhase, volume *v1.PersistentVolume, eventtype, reason, message string) (*v1.PersistentVolumeClaim, error) { … } // updateVolumePhase saves new volume phase to API server. func (ctrl *PersistentVolumeController) updateVolumePhase(ctx context.Context, volume *v1.PersistentVolume, phase v1.PersistentVolumePhase, message string) (*v1.PersistentVolume, error) { … } // updateVolumePhaseWithEvent saves new volume phase to API server and emits // given event on the volume. It saves the phase and emits the event only when // the phase has actually changed from the version saved in API server. func (ctrl *PersistentVolumeController) updateVolumePhaseWithEvent(ctx context.Context, volume *v1.PersistentVolume, phase v1.PersistentVolumePhase, eventtype, reason, message string) (*v1.PersistentVolume, error) { … } // assignDefaultStorageClass updates the claim storage class if there is any, the claim is updated to the API server. // Ignores claims that already have a storage class. // TODO: if resync is ever changed to a larger period, we might need to change how we set the default class on existing unbound claims func (ctrl *PersistentVolumeController) assignDefaultStorageClass(ctx context.Context, claim *v1.PersistentVolumeClaim) (bool, error) { … } // bindVolumeToClaim modifies given volume to be bound to a claim and saves it to // API server. The claim is not modified in this method! func (ctrl *PersistentVolumeController) bindVolumeToClaim(ctx context.Context, volume *v1.PersistentVolume, claim *v1.PersistentVolumeClaim) (*v1.PersistentVolume, error) { … } // updateBindVolumeToClaim modifies given volume to be bound to a claim and saves it to // API server. The claim is not modified in this method! func (ctrl *PersistentVolumeController) updateBindVolumeToClaim(ctx context.Context, volumeClone *v1.PersistentVolume, updateCache bool) (*v1.PersistentVolume, error) { … } // bindClaimToVolume modifies the given claim to be bound to a volume and // saves it to API server. The volume is not modified in this method! func (ctrl *PersistentVolumeController) bindClaimToVolume(ctx context.Context, claim *v1.PersistentVolumeClaim, volume *v1.PersistentVolume) (*v1.PersistentVolumeClaim, error) { … } // bind saves binding information both to the volume and the claim and marks // both objects as Bound. Volume is saved first. // It returns on first error, it's up to the caller to implement some retry // mechanism. func (ctrl *PersistentVolumeController) bind(ctx context.Context, volume *v1.PersistentVolume, claim *v1.PersistentVolumeClaim) error { … } // unbindVolume rolls back previous binding of the volume. This may be necessary // when two controllers bound two volumes to single claim - when we detect this, // only one binding succeeds and the second one must be rolled back. // This method updates both Spec and Status. // It returns on first error, it's up to the caller to implement some retry // mechanism. func (ctrl *PersistentVolumeController) unbindVolume(ctx context.Context, volume *v1.PersistentVolume) error { … } // reclaimVolume implements volume.Spec.PersistentVolumeReclaimPolicy and // starts appropriate reclaim action. func (ctrl *PersistentVolumeController) reclaimVolume(ctx context.Context, volume *v1.PersistentVolume) error { … } // recycleVolumeOperation recycles a volume. This method is running in // standalone goroutine and already has all necessary locks. func (ctrl *PersistentVolumeController) recycleVolumeOperation(ctx context.Context, volume *v1.PersistentVolume) { … } // deleteVolumeOperation deletes a volume. This method is running in standalone // goroutine and already has all necessary locks. func (ctrl *PersistentVolumeController) deleteVolumeOperation(ctx context.Context, volume *v1.PersistentVolume) (string, error) { … } // isVolumeReleased returns true if given volume is released and can be recycled // or deleted, based on its retain policy. I.e. the volume is bound to a claim // and the claim does not exist or exists and is bound to different volume. func (ctrl *PersistentVolumeController) isVolumeReleased(logger klog.Logger, volume *v1.PersistentVolume) (bool, error) { … } func (ctrl *PersistentVolumeController) findPodsByPVCKey(key string) ([]*v1.Pod, error) { … } // isVolumeUsed returns list of active pods that use given PV. func (ctrl *PersistentVolumeController) isVolumeUsed(pv *v1.PersistentVolume) ([]string, bool, error) { … } // findNonScheduledPodsByPVC returns list of non-scheduled active pods that reference given PVC. func (ctrl *PersistentVolumeController) findNonScheduledPodsByPVC(pvc *v1.PersistentVolumeClaim) ([]string, error) { … } // doDeleteVolume finds appropriate delete plugin and deletes given volume, returning // the volume plugin name. Also, it returns 'true', when the volume was deleted and // 'false' when the volume cannot be deleted because the deleter is external. No // error should be reported in this case. func (ctrl *PersistentVolumeController) doDeleteVolume(ctx context.Context, volume *v1.PersistentVolume) (string, bool, error) { … } func (ctrl *PersistentVolumeController) removeDeletionProtectionFinalizer(ctx context.Context, volume *v1.PersistentVolume) error { … } // provisionClaim starts new asynchronous operation to provision a claim if // provisioning is enabled. func (ctrl *PersistentVolumeController) provisionClaim(ctx context.Context, claim *v1.PersistentVolumeClaim) error { … } // provisionClaimOperation provisions a volume. This method is running in // standalone goroutine and already has all necessary locks. func (ctrl *PersistentVolumeController) provisionClaimOperation( ctx context.Context, claim *v1.PersistentVolumeClaim, plugin vol.ProvisionableVolumePlugin, storageClass *storage.StorageClass) (string, error) { … } // provisionClaimOperationExternal provisions a volume using external provisioner async-ly // This method will be running in a standalone go-routine scheduled in "provisionClaim" func (ctrl *PersistentVolumeController) provisionClaimOperationExternal( ctx context.Context, claim *v1.PersistentVolumeClaim, storageClass *storage.StorageClass) (string, error) { … } // rescheduleProvisioning signal back to the scheduler to retry dynamic provisioning // by removing the AnnSelectedNode annotation func (ctrl *PersistentVolumeController) rescheduleProvisioning(ctx context.Context, claim *v1.PersistentVolumeClaim) { … } // getProvisionedVolumeNameForClaim returns PV.Name for the provisioned volume. // The name must be unique. func (ctrl *PersistentVolumeController) getProvisionedVolumeNameForClaim(claim *v1.PersistentVolumeClaim) string { … } // scheduleOperation starts given asynchronous operation on given volume. It // makes sure the operation is already not running. func (ctrl *PersistentVolumeController) scheduleOperation(logger klog.Logger, operationName string, operation func() error) { … } // newRecyclerEventRecorder returns a RecycleEventRecorder that sends all events // to given volume. func (ctrl *PersistentVolumeController) newRecyclerEventRecorder(volume *v1.PersistentVolume) recyclerclient.RecycleEventRecorder { … } // findProvisionablePlugin finds a provisioner plugin for a given claim. // It returns either the provisioning plugin or nil when an external // provisioner is requested. func (ctrl *PersistentVolumeController) findProvisionablePlugin(claim *v1.PersistentVolumeClaim) (vol.ProvisionableVolumePlugin, *storage.StorageClass, error) { … } // findDeletablePlugin finds a deleter plugin for a given volume. It returns // either the deleter plugin or nil when an external deleter is requested. func (ctrl *PersistentVolumeController) findDeletablePlugin(volume *v1.PersistentVolume) (vol.DeletableVolumePlugin, error) { … } // obtain provisioner/deleter name for a volume func (ctrl *PersistentVolumeController) getProvisionerNameFromVolume(volume *v1.PersistentVolume) string { … } // obtain plugin/external provisioner name from plugin and storage class for timestamp logging purposes func (ctrl *PersistentVolumeController) getProvisionerName(plugin vol.ProvisionableVolumePlugin, storageClass *storage.StorageClass) string { … }