Revert "Remove alpha provisioning"
This commit is contained in:
@@ -834,6 +834,9 @@ func wrapTestWithPluginCalls(expectedRecycleCalls, expectedDeleteCalls []error,
|
||||
provisionCalls: expectedProvisionCalls,
|
||||
}
|
||||
ctrl.volumePluginMgr.InitPlugins([]vol.VolumePlugin{plugin}, ctrl)
|
||||
if expectedProvisionCalls != nil {
|
||||
ctrl.alphaProvisioner = plugin
|
||||
}
|
||||
return toWrap(ctrl, reactor, test)
|
||||
}
|
||||
}
|
||||
|
@@ -130,6 +130,14 @@ func (pvIndex *persistentVolumeOrderedIndex) findByClaim(claim *v1.PersistentVol
|
||||
return volume, nil
|
||||
}
|
||||
|
||||
// In Alpha dynamic provisioning, we do now want not match claims
|
||||
// with existing PVs, findByClaim must find only PVs that are
|
||||
// pre-bound to the claim (by dynamic provisioning). TODO: remove in
|
||||
// 1.5
|
||||
if metav1.HasAnnotation(claim.ObjectMeta, storageutil.AlphaStorageClassAnnotation) {
|
||||
continue
|
||||
}
|
||||
|
||||
// filter out:
|
||||
// - volumes bound to another claim
|
||||
// - volumes whose labels don't match the claim's selector, if specified
|
||||
|
@@ -95,6 +95,10 @@ var provision2Success = provisionCall{
|
||||
expectedParameters: class2Parameters,
|
||||
}
|
||||
|
||||
var provisionAlphaSuccess = provisionCall{
|
||||
ret: nil,
|
||||
}
|
||||
|
||||
// Test single call to syncVolume, expecting provisioning to happen.
|
||||
// 1. Fill in the controller with initial data
|
||||
// 2. Call the syncVolume *once*.
|
||||
@@ -356,6 +360,36 @@ func TestProvisionSync(t *testing.T) {
|
||||
runSyncTests(t, tests, storageClasses)
|
||||
}
|
||||
|
||||
func TestAlphaProvisionSync(t *testing.T) {
|
||||
tests := []controllerTest{
|
||||
{
|
||||
// Provision a volume with alpha annotation
|
||||
"14-1 - successful alpha provisioning",
|
||||
novolumes,
|
||||
newVolumeArray("pvc-uid14-1", "1Gi", "uid14-1", "claim14-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, annBoundByController, annDynamicallyProvisioned),
|
||||
newClaimArray("claim14-1", "uid14-1", "1Gi", "", v1.ClaimPending, storageutil.AlphaStorageClassAnnotation),
|
||||
// Binding will be completed in the next syncClaim
|
||||
newClaimArray("claim14-1", "uid14-1", "1Gi", "", v1.ClaimPending, storageutil.AlphaStorageClassAnnotation, annStorageProvisioner),
|
||||
noevents, noerrors, wrapTestWithProvisionCalls([]provisionCall{provisionAlphaSuccess}, testSyncClaim),
|
||||
},
|
||||
{
|
||||
// Provision success - there is already a volume available, still
|
||||
// we provision a new one when requested.
|
||||
"14-2 - no alpha provisioning when there is a volume available",
|
||||
newVolumeArray("volume14-2", "1Gi", "", "", v1.VolumePending, v1.PersistentVolumeReclaimRetain),
|
||||
[]*v1.PersistentVolume{
|
||||
newVolume("volume14-2", "1Gi", "", "", v1.VolumePending, v1.PersistentVolumeReclaimRetain),
|
||||
newVolume("pvc-uid14-2", "1Gi", "uid14-2", "claim14-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, annBoundByController, annDynamicallyProvisioned),
|
||||
},
|
||||
newClaimArray("claim14-2", "uid14-2", "1Gi", "", v1.ClaimPending, storageutil.AlphaStorageClassAnnotation),
|
||||
// Binding will be completed in the next syncClaim
|
||||
newClaimArray("claim14-2", "uid14-2", "1Gi", "", v1.ClaimPending, storageutil.AlphaStorageClassAnnotation, annStorageProvisioner),
|
||||
noevents, noerrors, wrapTestWithProvisionCalls([]provisionCall{provisionAlphaSuccess}, testSyncClaim),
|
||||
},
|
||||
}
|
||||
runSyncTests(t, tests, []*storage.StorageClass{})
|
||||
}
|
||||
|
||||
// Test multiple calls to syncClaim/syncVolume and periodic sync of all
|
||||
// volume/claims. The test follows this pattern:
|
||||
// 0. Load the controller with initial data.
|
||||
|
@@ -203,6 +203,10 @@ type PersistentVolumeController struct {
|
||||
|
||||
createProvisionedPVRetryCount int
|
||||
createProvisionedPVInterval time.Duration
|
||||
|
||||
// Provisioner for annAlphaClass.
|
||||
// TODO: remove in 1.5
|
||||
alphaProvisioner vol.ProvisionableVolumePlugin
|
||||
}
|
||||
|
||||
// syncClaim is the main controller method to decide what to do with a claim.
|
||||
@@ -239,7 +243,7 @@ func (ctrl *PersistentVolumeController) syncUnboundClaim(claim *v1.PersistentVol
|
||||
glog.V(4).Infof("synchronizing unbound PersistentVolumeClaim[%s]: no volume found", claimToClaimKey(claim))
|
||||
// No PV could be found
|
||||
// OBSERVATION: pvc is "Pending", will retry
|
||||
if storageutil.GetClaimStorageClass(claim) != "" {
|
||||
if storageutil.GetClaimStorageClass(claim) != "" || metav1.HasAnnotation(claim.ObjectMeta, storageutil.AlphaStorageClassAnnotation) {
|
||||
if err = ctrl.provisionClaim(claim); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1336,7 +1340,12 @@ func (ctrl *PersistentVolumeController) provisionClaimOperation(claimObj interfa
|
||||
// Add annBoundByController (used in deleting the volume)
|
||||
metav1.SetMetaDataAnnotation(&volume.ObjectMeta, annBoundByController, "yes")
|
||||
metav1.SetMetaDataAnnotation(&volume.ObjectMeta, annDynamicallyProvisioned, plugin.GetPluginName())
|
||||
metav1.SetMetaDataAnnotation(&volume.ObjectMeta, storageutil.StorageClassAnnotation, claimClass)
|
||||
// For Alpha provisioning behavior, do not add storage.BetaStorageClassAnnotations for volumes created
|
||||
// by storage.AlphaStorageClassAnnotation
|
||||
// TODO: remove this check in 1.5, storage.StorageClassAnnotation will be always non-empty there.
|
||||
if claimClass != "" {
|
||||
metav1.SetMetaDataAnnotation(&volume.ObjectMeta, storageutil.StorageClassAnnotation, claimClass)
|
||||
}
|
||||
|
||||
// Try to create the PV object several times
|
||||
for i := 0; i < ctrl.createProvisionedPVRetryCount; i++ {
|
||||
@@ -1438,6 +1447,20 @@ func (ctrl *PersistentVolumeController) newRecyclerEventRecorder(volume *v1.Pers
|
||||
// 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) {
|
||||
// TODO: remove this alpha behavior in 1.5
|
||||
alpha := metav1.HasAnnotation(claim.ObjectMeta, storageutil.AlphaStorageClassAnnotation)
|
||||
beta := metav1.HasAnnotation(claim.ObjectMeta, storageutil.BetaStorageClassAnnotation)
|
||||
if alpha && beta {
|
||||
// Both Alpha and Beta annotations are set. Do beta.
|
||||
alpha = false
|
||||
msg := fmt.Sprintf("both %q and %q annotations are present, using %q", storageutil.AlphaStorageClassAnnotation, storageutil.BetaStorageClassAnnotation, storageutil.BetaStorageClassAnnotation)
|
||||
ctrl.eventRecorder.Event(claim, v1.EventTypeNormal, "ProvisioningIgnoreAlpha", msg)
|
||||
}
|
||||
if alpha {
|
||||
// Fall back to fixed list of provisioner plugins
|
||||
return ctrl.findAlphaProvisionablePlugin()
|
||||
}
|
||||
|
||||
// provisionClaim() which leads here is never called with claimClass=="", we
|
||||
// can save some checks.
|
||||
claimClass := storageutil.GetClaimStorageClass(claim)
|
||||
@@ -1465,6 +1488,28 @@ func (ctrl *PersistentVolumeController) findProvisionablePlugin(claim *v1.Persis
|
||||
return plugin, class, nil
|
||||
}
|
||||
|
||||
// findAlphaProvisionablePlugin returns a volume plugin compatible with
|
||||
// Kubernetes 1.3.
|
||||
// TODO: remove in Kubernetes 1.5
|
||||
func (ctrl *PersistentVolumeController) findAlphaProvisionablePlugin() (vol.ProvisionableVolumePlugin, *storage.StorageClass, error) {
|
||||
if ctrl.alphaProvisioner == nil {
|
||||
return nil, nil, fmt.Errorf("cannot find volume plugin for alpha provisioning")
|
||||
}
|
||||
|
||||
// Return a dummy StorageClass instance with no parameters
|
||||
storageClass := &storage.StorageClass{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "StorageClass",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "",
|
||||
},
|
||||
Provisioner: ctrl.alphaProvisioner.GetPluginName(),
|
||||
}
|
||||
glog.V(4).Infof("using alpha provisioner %s", ctrl.alphaProvisioner.GetPluginName())
|
||||
return ctrl.alphaProvisioner, storageClass, nil
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
@@ -53,6 +53,7 @@ import (
|
||||
type ControllerParameters struct {
|
||||
KubeClient clientset.Interface
|
||||
SyncPeriod time.Duration
|
||||
AlphaProvisioner vol.ProvisionableVolumePlugin
|
||||
VolumePlugins []vol.VolumePlugin
|
||||
Cloud cloudprovider.Interface
|
||||
ClusterName string
|
||||
@@ -81,11 +82,17 @@ func NewController(p ControllerParameters) *PersistentVolumeController {
|
||||
clusterName: p.ClusterName,
|
||||
createProvisionedPVRetryCount: createProvisionedPVRetryCount,
|
||||
createProvisionedPVInterval: createProvisionedPVInterval,
|
||||
alphaProvisioner: p.AlphaProvisioner,
|
||||
claimQueue: workqueue.NewNamed("claims"),
|
||||
volumeQueue: workqueue.NewNamed("volumes"),
|
||||
}
|
||||
|
||||
controller.volumePluginMgr.InitPlugins(p.VolumePlugins, controller)
|
||||
if controller.alphaProvisioner != nil {
|
||||
if err := controller.alphaProvisioner.Init(controller); err != nil {
|
||||
glog.Errorf("PersistentVolumeController: error initializing alpha provisioner plugin: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
volumeSource := p.VolumeSource
|
||||
if volumeSource == nil {
|
||||
|
Reference in New Issue
Block a user