diff --git a/vendor/k8s.io/kubernetes/pkg/controller/volume/persistentvolume/controller.go b/vendor/k8s.io/kubernetes/pkg/controller/volume/persistentvolume/controller.go index 2231bd349028..63c9d5a8e0f5 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/volume/persistentvolume/controller.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/volume/persistentvolume/controller.go @@ -19,6 +19,7 @@ package persistentvolume import ( "fmt" "reflect" + "strings" "time" "k8s.io/kubernetes/pkg/api" @@ -1234,6 +1235,19 @@ func (ctrl *PersistentVolumeController) provisionClaimOperation(claimObj interfa // syncVolume() call. return } + if plugin == nil { + // findProvisionablePlugin returned no error nor plugin. + // This means that an unknown provisioner is requested. Report an event + // and wait for the external provisioner + if storageClass != nil { + msg := fmt.Sprintf("cannot find provisioner %q, expecting that a volume for the claim is provisioned either manually or via external software", storageClass.Provisioner) + ctrl.eventRecorder.Event(claim, api.EventTypeNormal, "ExternalProvisioning", msg) + glog.V(3).Infof("provisioning claim %q: %s", claimToClaimKey(claim), msg) + } else { + glog.V(3).Infof("cannot find storage class for claim %q", claimToClaimKey(claim)) + } + return + } // Gather provisioning options tags := make(map[string]string) @@ -1366,6 +1380,9 @@ func (ctrl *PersistentVolumeController) scheduleOperation(operationName string, } } +// 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 *api.PersistentVolumeClaim) (vol.ProvisionableVolumePlugin, *storage.StorageClass, error) { // TODO: remove this alpha behavior in 1.5 alpha := hasAnnotation(claim.ObjectMeta, annAlphaClass) @@ -1399,7 +1416,11 @@ func (ctrl *PersistentVolumeController) findProvisionablePlugin(claim *api.Persi // Find a plugin for the class plugin, err := ctrl.volumePluginMgr.FindProvisionablePluginByName(class.Provisioner) if err != nil { - return nil, nil, err + if !strings.HasPrefix(class.Provisioner, "kubernetes.io/") { + // External provisioner is requested, do not report error + return nil, class, nil + } + return nil, class, err } return plugin, class, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/controller/volume/persistentvolume/framework_test.go b/vendor/k8s.io/kubernetes/pkg/controller/volume/persistentvolume/framework_test.go index 22dc8559054c..54ba1c0175cc 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/volume/persistentvolume/framework_test.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/volume/persistentvolume/framework_test.go @@ -95,7 +95,7 @@ type controllerTest struct { type testCall func(ctrl *PersistentVolumeController, reactor *volumeReactor, test controllerTest) error const testNamespace = "default" -const mockPluginName = "MockVolumePlugin" +const mockPluginName = "kubernetes.io/mock-volume" var versionConflictError = errors.New("VersionError") var novolumes []*api.PersistentVolume diff --git a/vendor/k8s.io/kubernetes/pkg/controller/volume/persistentvolume/provision_test.go b/vendor/k8s.io/kubernetes/pkg/controller/volume/persistentvolume/provision_test.go index 002d1bacf720..aeb7dbb22a88 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/volume/persistentvolume/provision_test.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/volume/persistentvolume/provision_test.go @@ -54,6 +54,26 @@ var storageClasses = []*storage.StorageClass{ Provisioner: mockPluginName, Parameters: class2Parameters, }, + { + TypeMeta: unversioned.TypeMeta{ + Kind: "StorageClass", + }, + ObjectMeta: api.ObjectMeta{ + Name: "external", + }, + Provisioner: "vendor.com/my-volume", + Parameters: class1Parameters, + }, + { + TypeMeta: unversioned.TypeMeta{ + Kind: "StorageClass", + }, + ObjectMeta: api.ObjectMeta{ + Name: "unknown-internal", + }, + Provisioner: "kubernetes.io/unknown", + Parameters: class1Parameters, + }, } // call to storageClass 1, returning an error @@ -314,6 +334,26 @@ func TestProvisionSync(t *testing.T) { newClaimArray("claim11-15", "uid11-15", "1Gi", "", api.ClaimPending), noevents, noerrors, wrapTestWithProvisionCalls([]provisionCall{}, testSyncClaim), }, + { + // No provisioning + normal event with external provisioner + "11-17 - external provisioner", + novolumes, + novolumes, + claimWithClass("external", newClaimArray("claim11-17", "uid11-17", "1Gi", "", api.ClaimPending)), + claimWithClass("external", newClaimArray("claim11-17", "uid11-17", "1Gi", "", api.ClaimPending)), + []string{"Normal ExternalProvisioning"}, + noerrors, wrapTestWithProvisionCalls([]provisionCall{}, testSyncClaim), + }, + { + // No provisioning + warning event with unknown internal provisioner + "11-18 - unknown internal provisioner", + novolumes, + novolumes, + claimWithClass("unknown-internal", newClaimArray("claim11-18", "uid11-18", "1Gi", "", api.ClaimPending)), + claimWithClass("unknown-internal", newClaimArray("claim11-18", "uid11-18", "1Gi", "", api.ClaimPending)), + []string{"Warning ProvisioningFailed"}, + noerrors, wrapTestWithProvisionCalls([]provisionCall{}, testSyncClaim), + }, } runSyncTests(t, tests, storageClasses) }