diff --git a/cmd/kube-controller-manager/app/controllermanager.go b/cmd/kube-controller-manager/app/controllermanager.go index 4390fa0574d..46305e90fde 100644 --- a/cmd/kube-controller-manager/app/controllermanager.go +++ b/cmd/kube-controller-manager/app/controllermanager.go @@ -530,14 +530,9 @@ func StartControllers(controllers map[string]InitFunc, s *options.CMServer, root } if ctx.IsControllerEnabled(pvBinderControllerName) { - alphaProvisioner, err := NewAlphaVolumeProvisioner(cloud, s.VolumeConfiguration) - if err != nil { - return fmt.Errorf("an backward-compatible provisioner could not be created: %v, but one was expected. Provisioning will not work. This functionality is considered an early Alpha version.", err) - } params := persistentvolumecontroller.ControllerParameters{ KubeClient: clientBuilder.ClientOrDie("persistent-volume-binder"), SyncPeriod: s.PVClaimBinderSyncPeriod.Duration, - AlphaProvisioner: alphaProvisioner, VolumePlugins: ProbeControllerVolumePlugins(cloud, s.VolumeConfiguration), Cloud: cloud, ClusterName: s.ClusterName, diff --git a/cmd/kube-controller-manager/app/plugins.go b/cmd/kube-controller-manager/app/plugins.go index e02e506cea3..38f126f6b88 100644 --- a/cmd/kube-controller-manager/app/plugins.go +++ b/cmd/kube-controller-manager/app/plugins.go @@ -29,7 +29,6 @@ import ( // Volume plugins "github.com/golang/glog" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider/providers/aws" "k8s.io/kubernetes/pkg/cloudprovider/providers/azure" @@ -37,7 +36,6 @@ import ( "k8s.io/kubernetes/pkg/cloudprovider/providers/openstack" "k8s.io/kubernetes/pkg/cloudprovider/providers/photon" "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/util/io" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/aws_ebs" @@ -144,45 +142,6 @@ func ProbeControllerVolumePlugins(cloud cloudprovider.Interface, config componen return allPlugins } -// NewAlphaVolumeProvisioner returns a volume provisioner to use when running in -// a cloud or development environment. The alpha implementation of provisioning -// allows 1 implied provisioner per cloud and is here only for compatibility -// with Kubernetes 1.3 -// TODO: remove in Kubernetes 1.5 -func NewAlphaVolumeProvisioner(cloud cloudprovider.Interface, config componentconfig.VolumeConfiguration) (volume.ProvisionableVolumePlugin, error) { - switch { - case !utilfeature.DefaultFeatureGate.Enabled(features.DynamicVolumeProvisioning): - return nil, nil - case cloud == nil && config.EnableHostPathProvisioning: - return getProvisionablePluginFromVolumePlugins(host_path.ProbeVolumePlugins( - volume.VolumeConfig{ - ProvisioningEnabled: true, - })) - case cloud != nil && aws.ProviderName == cloud.ProviderName(): - return getProvisionablePluginFromVolumePlugins(aws_ebs.ProbeVolumePlugins()) - case cloud != nil && gce.ProviderName == cloud.ProviderName(): - return getProvisionablePluginFromVolumePlugins(gce_pd.ProbeVolumePlugins()) - case cloud != nil && openstack.ProviderName == cloud.ProviderName(): - return getProvisionablePluginFromVolumePlugins(cinder.ProbeVolumePlugins()) - case cloud != nil && vsphere.ProviderName == cloud.ProviderName(): - return getProvisionablePluginFromVolumePlugins(vsphere_volume.ProbeVolumePlugins()) - case cloud != nil && azure.CloudProviderName == cloud.ProviderName(): - return getProvisionablePluginFromVolumePlugins(azure_dd.ProbeVolumePlugins()) - case cloud != nil && photon.ProviderName == cloud.ProviderName(): - return getProvisionablePluginFromVolumePlugins(photon_pd.ProbeVolumePlugins()) - } - return nil, nil -} - -func getProvisionablePluginFromVolumePlugins(plugins []volume.VolumePlugin) (volume.ProvisionableVolumePlugin, error) { - for _, plugin := range plugins { - if provisonablePlugin, ok := plugin.(volume.ProvisionableVolumePlugin); ok { - return provisonablePlugin, nil - } - } - return nil, fmt.Errorf("ProvisionablePlugin expected but not found in %#v: ", plugins) -} - // AttemptToLoadRecycler tries decoding a pod from a filepath for use as a recycler for a volume. // If successful, this method will set the recycler on the config. // If unsuccessful, an error is returned. Function is exported for reuse downstream. diff --git a/pkg/api/v1/types.go b/pkg/api/v1/types.go index 2741ec3da4a..cf298521df6 100644 --- a/pkg/api/v1/types.go +++ b/pkg/api/v1/types.go @@ -431,11 +431,6 @@ type PersistentVolumeSource struct { } const ( - // AlphaStorageClassAnnotation represents the previous alpha storage class - // annotation. It's currently still used and will be held for backwards - // compatibility - AlphaStorageClassAnnotation = "volume.alpha.kubernetes.io/storage-class" - // BetaStorageClassAnnotation represents the beta/previous StorageClass annotation. // It's currently still used and will be held for backwards compatibility BetaStorageClassAnnotation = "volume.beta.kubernetes.io/storage-class" diff --git a/pkg/controller/volume/persistentvolume/framework_test.go b/pkg/controller/volume/persistentvolume/framework_test.go index 24e7f2181f6..ec744b5ddf7 100644 --- a/pkg/controller/volume/persistentvolume/framework_test.go +++ b/pkg/controller/volume/persistentvolume/framework_test.go @@ -825,9 +825,6 @@ 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) } } diff --git a/pkg/controller/volume/persistentvolume/index.go b/pkg/controller/volume/persistentvolume/index.go index 0d6df1d0c5e..77ffca300f2 100644 --- a/pkg/controller/volume/persistentvolume/index.go +++ b/pkg/controller/volume/persistentvolume/index.go @@ -126,14 +126,6 @@ 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, v1.AlphaStorageClassAnnotation) { - continue - } - // filter out: // - volumes bound to another claim // - volumes whose labels don't match the claim's selector, if specified diff --git a/pkg/controller/volume/persistentvolume/provision_test.go b/pkg/controller/volume/persistentvolume/provision_test.go index 20996919f4e..7e2a7c6d346 100644 --- a/pkg/controller/volume/persistentvolume/provision_test.go +++ b/pkg/controller/volume/persistentvolume/provision_test.go @@ -359,36 +359,6 @@ 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, classEmpty, annBoundByController, annDynamicallyProvisioned), - newClaimArray("claim14-1", "uid14-1", "1Gi", "", v1.ClaimPending, nil, v1.AlphaStorageClassAnnotation), - // Binding will be completed in the next syncClaim - newClaimArray("claim14-1", "uid14-1", "1Gi", "", v1.ClaimPending, nil, v1.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, classEmpty), - []*v1.PersistentVolume{ - newVolume("volume14-2", "1Gi", "", "", v1.VolumePending, v1.PersistentVolumeReclaimRetain, classEmpty), - newVolume("pvc-uid14-2", "1Gi", "uid14-2", "claim14-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, annBoundByController, annDynamicallyProvisioned), - }, - newClaimArray("claim14-2", "uid14-2", "1Gi", "", v1.ClaimPending, nil, v1.AlphaStorageClassAnnotation), - // Binding will be completed in the next syncClaim - newClaimArray("claim14-2", "uid14-2", "1Gi", "", v1.ClaimPending, nil, v1.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. diff --git a/pkg/controller/volume/persistentvolume/pv_controller.go b/pkg/controller/volume/persistentvolume/pv_controller.go index b165b2ea380..9561d16a2df 100644 --- a/pkg/controller/volume/persistentvolume/pv_controller.go +++ b/pkg/controller/volume/persistentvolume/pv_controller.go @@ -203,10 +203,6 @@ 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. @@ -262,7 +258,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 v1.GetPersistentVolumeClaimClass(claim) != "" || metav1.HasAnnotation(claim.ObjectMeta, v1.AlphaStorageClassAnnotation) { + if v1.GetPersistentVolumeClaimClass(claim) != "" { if err = ctrl.provisionClaim(claim); err != nil { return err } @@ -1353,8 +1349,6 @@ 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()) - // 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 != "" { volume.Spec.StorageClassName = claimClass @@ -1465,20 +1459,6 @@ 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, v1.AlphaStorageClassAnnotation) - if alpha && v1.PersistentVolumeClaimHasClass(claim) { - // Both Alpha annotation and storage class name is set. Use the storage - // class name. - alpha = false - msg := fmt.Sprintf("both %q annotation and storageClassName are present, using storageClassName", v1.AlphaStorageClassAnnotation) - 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 := v1.GetPersistentVolumeClaimClass(claim) @@ -1499,28 +1479,6 @@ 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) { diff --git a/pkg/controller/volume/persistentvolume/pv_controller_base.go b/pkg/controller/volume/persistentvolume/pv_controller_base.go index 3ca34cea0c9..626847bd413 100644 --- a/pkg/controller/volume/persistentvolume/pv_controller_base.go +++ b/pkg/controller/volume/persistentvolume/pv_controller_base.go @@ -56,7 +56,6 @@ import ( type ControllerParameters struct { KubeClient clientset.Interface SyncPeriod time.Duration - AlphaProvisioner vol.ProvisionableVolumePlugin VolumePlugins []vol.VolumePlugin Cloud cloudprovider.Interface ClusterName string @@ -87,17 +86,11 @@ 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) - } - } p.VolumeInformer.Informer().AddEventHandlerWithResyncPeriod( cache.ResourceEventHandlerFuncs{ diff --git a/staging/src/k8s.io/client-go/pkg/api/v1/types.go b/staging/src/k8s.io/client-go/pkg/api/v1/types.go index 2741ec3da4a..cf298521df6 100644 --- a/staging/src/k8s.io/client-go/pkg/api/v1/types.go +++ b/staging/src/k8s.io/client-go/pkg/api/v1/types.go @@ -431,11 +431,6 @@ type PersistentVolumeSource struct { } const ( - // AlphaStorageClassAnnotation represents the previous alpha storage class - // annotation. It's currently still used and will be held for backwards - // compatibility - AlphaStorageClassAnnotation = "volume.alpha.kubernetes.io/storage-class" - // BetaStorageClassAnnotation represents the beta/previous StorageClass annotation. // It's currently still used and will be held for backwards compatibility BetaStorageClassAnnotation = "volume.beta.kubernetes.io/storage-class" diff --git a/test/e2e/volume_provisioning.go b/test/e2e/volume_provisioning.go index b34eda1bfa5..4d330800e85 100644 --- a/test/e2e/volume_provisioning.go +++ b/test/e2e/volume_provisioning.go @@ -499,25 +499,6 @@ var _ = framework.KubeDescribe("Dynamic Provisioning", func() { }) }) - framework.KubeDescribe("DynamicProvisioner Alpha", func() { - It("should create and delete alpha persistent volumes [Slow] [Volume]", func() { - framework.SkipUnlessProviderIs("openstack", "gce", "aws", "gke", "vsphere") - - By("creating a claim with an alpha dynamic provisioning annotation") - test := storageClassTest{ - name: "alpha test", - claimSize: "2Gi", - expectedSize: "2Gi", - } - - claim := newClaim(test, ns, "alpha") - claim.Annotations = map[string]string{ - v1.AlphaStorageClassAnnotation: "true", - } - testDynamicProvisioning(test, c, claim, nil) - }) - }) - framework.KubeDescribe("DynamicProvisioner External", func() { It("should let an external dynamic provisioner create and delete persistent volumes [Slow] [Volume]", func() { // external dynamic provisioner pods need additional permissions provided by the