diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 064d031998e9c..9dfcbfd153800 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1561,6 +1561,7 @@ }, { "ImportPath": "github.com/ghodss/yaml", + "Comment": "v1.0.0-4-gc7ce166", "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577" }, { @@ -2334,11 +2335,11 @@ }, { "ImportPath": "github.com/kubernetes-csi/kubernetes-csi-migration-library", - "Rev": "d62704773030f6db982ef016b4fc1bf3b9ac32db" + "Rev": "5e48892b442e2bd3db1d28aabf43ba85c1dc69ca" }, { "ImportPath": "github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins", - "Rev": "d62704773030f6db982ef016b4fc1bf3b9ac32db" + "Rev": "5e48892b442e2bd3db1d28aabf43ba85c1dc69ca" }, { "ImportPath": "github.com/kubernetes/repo-infra/kazel", @@ -3824,6 +3825,7 @@ }, { "ImportPath": "gopkg.in/yaml.v2", + "Comment": "v2.2.1", "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183" }, { diff --git a/pkg/controller/volume/attachdetach/testing/testvolumespec.go b/pkg/controller/volume/attachdetach/testing/testvolumespec.go index 82788a85f7961..53bcb9b00dbb8 100644 --- a/pkg/controller/volume/attachdetach/testing/testvolumespec.go +++ b/pkg/controller/volume/attachdetach/testing/testvolumespec.go @@ -253,7 +253,7 @@ func (plugin *TestPlugin) CanSupport(spec *volume.Spec) bool { return true } -func (plugin *TestPlugin) IsMigratedToCSI() bool { +func (plugin *TestPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/controller/volume/persistentvolume/framework_test.go b/pkg/controller/volume/persistentvolume/framework_test.go index 365b41d9b638b..95b90a4ec70e8 100644 --- a/pkg/controller/volume/persistentvolume/framework_test.go +++ b/pkg/controller/volume/persistentvolume/framework_test.go @@ -1156,7 +1156,7 @@ func (plugin *mockVolumePlugin) CanSupport(spec *vol.Spec) bool { return true } -func (plugin *mockVolumePlugin) IsMigratedToCSI() bool { +func (plugin *mockVolumePlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/awsebs/aws_ebs.go b/pkg/volume/awsebs/aws_ebs.go index 65415de429cdd..2944c003b1d84 100644 --- a/pkg/volume/awsebs/aws_ebs.go +++ b/pkg/volume/awsebs/aws_ebs.go @@ -85,7 +85,7 @@ func (plugin *awsElasticBlockStorePlugin) CanSupport(spec *volume.Spec) bool { (spec.Volume != nil && spec.Volume.AWSElasticBlockStore != nil) } -func (plugin *awsElasticBlockStorePlugin) IsMigratedToCSI() bool { +func (plugin *awsElasticBlockStorePlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/azure_dd/azure_dd.go b/pkg/volume/azure_dd/azure_dd.go index 448090ebf80d1..32ce71260e1eb 100644 --- a/pkg/volume/azure_dd/azure_dd.go +++ b/pkg/volume/azure_dd/azure_dd.go @@ -121,7 +121,7 @@ func (plugin *azureDataDiskPlugin) CanSupport(spec *volume.Spec) bool { (spec.Volume != nil && spec.Volume.AzureDisk != nil) } -func (plugin *azureDataDiskPlugin) IsMigratedToCSI() bool { +func (plugin *azureDataDiskPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/azure_file/azure_file.go b/pkg/volume/azure_file/azure_file.go index 73dc528be2b69..ac141d3ae85d2 100644 --- a/pkg/volume/azure_file/azure_file.go +++ b/pkg/volume/azure_file/azure_file.go @@ -80,7 +80,7 @@ func (plugin *azureFilePlugin) CanSupport(spec *volume.Spec) bool { (spec.Volume != nil && spec.Volume.AzureFile != nil) } -func (plugin *azureFilePlugin) IsMigratedToCSI() bool { +func (plugin *azureFilePlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/cephfs/cephfs.go b/pkg/volume/cephfs/cephfs.go index b39430f4f17d3..bbe30d5e95fd4 100644 --- a/pkg/volume/cephfs/cephfs.go +++ b/pkg/volume/cephfs/cephfs.go @@ -71,7 +71,7 @@ func (plugin *cephfsPlugin) CanSupport(spec *volume.Spec) bool { return (spec.Volume != nil && spec.Volume.CephFS != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.CephFS != nil) } -func (plugin *cephfsPlugin) IsMigratedToCSI() bool { +func (plugin *cephfsPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/cinder/cinder.go b/pkg/volume/cinder/cinder.go index 6d76f70f969e5..c96f9a938f514 100644 --- a/pkg/volume/cinder/cinder.go +++ b/pkg/volume/cinder/cinder.go @@ -108,7 +108,7 @@ func (plugin *cinderPlugin) CanSupport(spec *volume.Spec) bool { return (spec.Volume != nil && spec.Volume.Cinder != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.Cinder != nil) } -func (plugin *cinderPlugin) IsMigratedToCSI() bool { +func (plugin *cinderPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/configmap/configmap.go b/pkg/volume/configmap/configmap.go index e0c5f088d5073..d2cf25979e366 100644 --- a/pkg/volume/configmap/configmap.go +++ b/pkg/volume/configmap/configmap.go @@ -73,7 +73,7 @@ func (plugin *configMapPlugin) CanSupport(spec *volume.Spec) bool { return spec.Volume != nil && spec.Volume.ConfigMap != nil } -func (plugin *configMapPlugin) IsMigratedToCSI() bool { +func (plugin *configMapPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/csi/csi_plugin.go b/pkg/volume/csi/csi_plugin.go index 719b3760e100a..f97c41c5b231e 100644 --- a/pkg/volume/csi/csi_plugin.go +++ b/pkg/volume/csi/csi_plugin.go @@ -204,7 +204,7 @@ func (p *csiPlugin) CanSupport(spec *volume.Spec) bool { return spec.PersistentVolume != nil && spec.PersistentVolume.Spec.CSI != nil } -func (p *csiPlugin) IsMigratedToCSI() bool { +func (p *csiPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/csi/nodeinfomanager/BUILD b/pkg/volume/csi/nodeinfomanager/BUILD index 588871e29e4e7..f209113bbaf2b 100644 --- a/pkg/volume/csi/nodeinfomanager/BUILD +++ b/pkg/volume/csi/nodeinfomanager/BUILD @@ -20,6 +20,7 @@ go_library( "//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library", "//vendor/github.com/container-storage-interface/spec/lib/go/csi/v0:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins:go_default_library", ], ) diff --git a/pkg/volume/csi/nodeinfomanager/nodeinfomanager.go b/pkg/volume/csi/nodeinfomanager/nodeinfomanager.go index bea909d6a5b1f..bf815ed7b6000 100644 --- a/pkg/volume/csi/nodeinfomanager/nodeinfomanager.go +++ b/pkg/volume/csi/nodeinfomanager/nodeinfomanager.go @@ -36,6 +36,8 @@ import ( "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util" + + csiPlugins "github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins" ) const ( @@ -45,6 +47,12 @@ const ( var nodeKind = v1.SchemeGroupVersion.WithKind("Node") +var migratedDrivers = map[string](func() bool){ + csiPlugins.GCEPDDriverName: func() bool { + return utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) && utilfeature.DefaultFeatureGate.Enabled(features.CSIMigrationGCE) + }, +} + // nodeInfoManager contains necessary common dependencies to update node info on both // the Node and CSINodeInfo objects. type nodeInfoManager struct { @@ -370,6 +378,15 @@ func (nim *nodeInfoManager) createNodeInfoObject( return err // do not wrap error } + isMigratable := false + if driverIsMigratableFunc, ok := migratedDrivers[driverName]; ok { + isMigratable = driverIsMigratableFunc() + glog.V(4).Infof("CSI Driver %v found in migrated driver list, and migration status is %v", driverName, isMigratable) + + } else { + glog.V(4).Infof("CSI Driver %v not found in migrated driver map", driverName) + } + nodeInfo := &csiv1alpha1.CSINodeInfo{ ObjectMeta: metav1.ObjectMeta{ Name: string(nim.nodeName), @@ -384,9 +401,10 @@ func (nim *nodeInfoManager) createNodeInfoObject( }, CSIDrivers: []csiv1alpha1.CSIDriverInfo{ { - Driver: driverName, - NodeID: driverNodeID, - TopologyKeys: topologyKeys, + Driver: driverName, + NodeID: driverNodeID, + TopologyKeys: topologyKeys, + IsDriverMigratableOnNode: isMigratable, }, }, } @@ -429,11 +447,17 @@ func (nim *nodeInfoManager) updateNodeInfoObject( } } + isMigratable := false + if driverIsMigratableFunc, ok := migratedDrivers[driverName]; ok { + isMigratable = driverIsMigratableFunc() + } + // Append new driver driverInfo := csiv1alpha1.CSIDriverInfo{ - Driver: driverName, - NodeID: driverNodeID, - TopologyKeys: topologyKeys.List(), + Driver: driverName, + NodeID: driverNodeID, + TopologyKeys: topologyKeys.List(), + IsDriverMigratableOnNode: isMigratable, } newDriverInfos = append(newDriverInfos, driverInfo) nodeInfo.CSIDrivers = newDriverInfos diff --git a/pkg/volume/downwardapi/downwardapi.go b/pkg/volume/downwardapi/downwardapi.go index 5935f1d62ebe0..56a197b6dad2f 100644 --- a/pkg/volume/downwardapi/downwardapi.go +++ b/pkg/volume/downwardapi/downwardapi.go @@ -78,7 +78,7 @@ func (plugin *downwardAPIPlugin) CanSupport(spec *volume.Spec) bool { return spec.Volume != nil && spec.Volume.DownwardAPI != nil } -func (plugin *downwardAPIPlugin) IsMigratedToCSI() bool { +func (plugin *downwardAPIPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/emptydir/empty_dir.go b/pkg/volume/emptydir/empty_dir.go index 68595f28351ae..5cfdce97c7e92 100644 --- a/pkg/volume/emptydir/empty_dir.go +++ b/pkg/volume/emptydir/empty_dir.go @@ -89,7 +89,7 @@ func (plugin *emptyDirPlugin) CanSupport(spec *volume.Spec) bool { return false } -func (plugin *emptyDirPlugin) IsMigratedToCSI() bool { +func (plugin *emptyDirPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/fc/fc.go b/pkg/volume/fc/fc.go index 3c5d23f356511..2b4bd86ac2395 100644 --- a/pkg/volume/fc/fc.go +++ b/pkg/volume/fc/fc.go @@ -85,7 +85,7 @@ func (plugin *fcPlugin) CanSupport(spec *volume.Spec) bool { return (spec.Volume != nil && spec.Volume.FC != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.FC != nil) } -func (plugin *fcPlugin) IsMigratedToCSI() bool { +func (plugin *fcPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/flexvolume/plugin.go b/pkg/volume/flexvolume/plugin.go index 3d70b78c3fc5a..00ff3b2e11c4e 100644 --- a/pkg/volume/flexvolume/plugin.go +++ b/pkg/volume/flexvolume/plugin.go @@ -147,7 +147,7 @@ func (plugin *flexVolumePlugin) CanSupport(spec *volume.Spec) bool { return sourceDriver == plugin.driverName } -func (plugin *flexVolumePlugin) IsMigratedToCSI() bool { +func (plugin *flexVolumePlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/flocker/flocker.go b/pkg/volume/flocker/flocker.go index a27ebe9571ffc..1819a5db5a286 100644 --- a/pkg/volume/flocker/flocker.go +++ b/pkg/volume/flocker/flocker.go @@ -108,7 +108,7 @@ func (p *flockerPlugin) CanSupport(spec *volume.Spec) bool { (spec.Volume != nil && spec.Volume.Flocker != nil) } -func (p *flockerPlugin) IsMigratedToCSI() bool { +func (p *flockerPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/gcepd/gce_pd.go b/pkg/volume/gcepd/gce_pd.go index f8e871d525968..c1f42f3a46946 100644 --- a/pkg/volume/gcepd/gce_pd.go +++ b/pkg/volume/gcepd/gce_pd.go @@ -98,7 +98,7 @@ func (plugin *gcePersistentDiskPlugin) CanSupport(spec *volume.Spec) bool { (spec.Volume != nil && spec.Volume.GCEPersistentDisk != nil) } -func (plugin *gcePersistentDiskPlugin) IsMigratedToCSI() bool { +func (plugin *gcePersistentDiskPlugin) IsMigratableToCSI() bool { return utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) && utilfeature.DefaultFeatureGate.Enabled(features.CSIMigrationGCE) } diff --git a/pkg/volume/git_repo/git_repo.go b/pkg/volume/git_repo/git_repo.go index bba6c719e0e5e..acbf47a803d5c 100644 --- a/pkg/volume/git_repo/git_repo.go +++ b/pkg/volume/git_repo/git_repo.go @@ -78,7 +78,7 @@ func (plugin *gitRepoPlugin) CanSupport(spec *volume.Spec) bool { return spec.Volume != nil && spec.Volume.GitRepo != nil } -func (plugin *gitRepoPlugin) IsMigratedToCSI() bool { +func (plugin *gitRepoPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/glusterfs/glusterfs.go b/pkg/volume/glusterfs/glusterfs.go index d29bc50686d6c..8a116e02018d7 100644 --- a/pkg/volume/glusterfs/glusterfs.go +++ b/pkg/volume/glusterfs/glusterfs.go @@ -114,7 +114,7 @@ func (plugin *glusterfsPlugin) CanSupport(spec *volume.Spec) bool { (spec.Volume != nil && spec.Volume.Glusterfs != nil) } -func (plugin *glusterfsPlugin) IsMigratedToCSI() bool { +func (plugin *glusterfsPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/host_path/host_path.go b/pkg/volume/host_path/host_path.go index dfbe01bf272f3..9cecf8adc7eab 100644 --- a/pkg/volume/host_path/host_path.go +++ b/pkg/volume/host_path/host_path.go @@ -83,7 +83,7 @@ func (plugin *hostPathPlugin) CanSupport(spec *volume.Spec) bool { (spec.Volume != nil && spec.Volume.HostPath != nil) } -func (plugin *hostPathPlugin) IsMigratedToCSI() bool { +func (plugin *hostPathPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/iscsi/iscsi.go b/pkg/volume/iscsi/iscsi.go index 00ea15ea23056..92b2674e87374 100644 --- a/pkg/volume/iscsi/iscsi.go +++ b/pkg/volume/iscsi/iscsi.go @@ -76,7 +76,7 @@ func (plugin *iscsiPlugin) CanSupport(spec *volume.Spec) bool { return (spec.Volume != nil && spec.Volume.ISCSI != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.ISCSI != nil) } -func (plugin *iscsiPlugin) IsMigratedToCSI() bool { +func (plugin *iscsiPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/local/local.go b/pkg/volume/local/local.go index f02082bdacaaf..5581e1ebb0504 100644 --- a/pkg/volume/local/local.go +++ b/pkg/volume/local/local.go @@ -82,7 +82,7 @@ func (plugin *localVolumePlugin) CanSupport(spec *volume.Spec) bool { return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.Local != nil) } -func (plugin *localVolumePlugin) IsMigratedToCSI() bool { +func (plugin *localVolumePlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/nfs/nfs.go b/pkg/volume/nfs/nfs.go index 29ab623fd2d11..d2d43833bed8f 100644 --- a/pkg/volume/nfs/nfs.go +++ b/pkg/volume/nfs/nfs.go @@ -84,7 +84,7 @@ func (plugin *nfsPlugin) CanSupport(spec *volume.Spec) bool { (spec.Volume != nil && spec.Volume.NFS != nil) } -func (plugin *nfsPlugin) IsMigratedToCSI() bool { +func (plugin *nfsPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/photon_pd/photon_pd.go b/pkg/volume/photon_pd/photon_pd.go index 6eda00efe9842..df92ab64c50dc 100644 --- a/pkg/volume/photon_pd/photon_pd.go +++ b/pkg/volume/photon_pd/photon_pd.go @@ -74,7 +74,7 @@ func (plugin *photonPersistentDiskPlugin) CanSupport(spec *volume.Spec) bool { (spec.Volume != nil && spec.Volume.PhotonPersistentDisk != nil) } -func (plugin *photonPersistentDiskPlugin) IsMigratedToCSI() bool { +func (plugin *photonPersistentDiskPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/plugins.go b/pkg/volume/plugins.go index d8b8114d2a5f8..07d529acaf3a4 100644 --- a/pkg/volume/plugins.go +++ b/pkg/volume/plugins.go @@ -118,9 +118,9 @@ type VolumePlugin interface { // const. CanSupport(spec *Spec) bool - // IsMigrated tests whether the plugin is migrated seamlessly to a CSI + // IsMigratable tests whether the plugin is migrated seamlessly to a CSI // Driver - IsMigratedToCSI() bool + IsMigratableToCSI() bool // RequiresRemount returns true if this plugin requires mount calls to be // reexecuted. Atomically updating volumes, like Downward API, depend on @@ -530,6 +530,9 @@ func (pm *VolumePluginMgr) initProbedPlugin(probedPlugin VolumePlugin) error { } func (pm *VolumePluginMgr) IsPluginMigratableBySpec(spec *Spec) (bool, error) { + pm.mutex.Lock() + defer pm.mutex.Unlock() + if spec == nil { return false, fmt.Errorf("could not find plugin migratable because volume spec is nil") } @@ -545,13 +548,37 @@ func (pm *VolumePluginMgr) IsPluginMigratableBySpec(spec *Spec) (bool, error) { } if len(matches) == 0 { - return false, fmt.Errorf("no volume plugin matched") + // Not a known plugin (flex) in which case it is not migratable + return false, nil } if len(matches) > 1 { return false, fmt.Errorf("multiple volume plugins matched: %s", strings.Join(matchedPluginNames, ",")) } - return matches[0].IsMigratedToCSI(), nil + return matches[0].IsMigratableToCSI(), nil +} + +func (pm *VolumePluginMgr) IsPluginMigratableByName(name string) (bool, error) { + pm.mutex.Lock() + defer pm.mutex.Unlock() + + // Once we can get rid of legacy names we can reduce this to a map lookup. + matchedPluginNames := []string{} + matches := []VolumePlugin{} + for k, v := range pm.plugins { + if v.GetPluginName() == name { + matchedPluginNames = append(matchedPluginNames, k) + matches = append(matches, v) + } + } + if len(matches) == 0 { + // Not a known plugin (flex) in which case it is not migratable + return false, nil + } + if len(matches) > 1 { + return false, fmt.Errorf("multiple volume plugins matched: %s", strings.Join(matchedPluginNames, ",")) + } + return matches[0].IsMigratableToCSI(), nil } // FindPluginBySpec looks for a plugin that can support a given volume diff --git a/pkg/volume/plugins_test.go b/pkg/volume/plugins_test.go index dd0a7397d8431..e5af86e471707 100644 --- a/pkg/volume/plugins_test.go +++ b/pkg/volume/plugins_test.go @@ -75,7 +75,7 @@ func (plugin *testPlugins) CanSupport(spec *Spec) bool { return true } -func (plugin *testPlugins) IsMigratedToCSI() bool { +func (plugin *testPlugins) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/portworx/portworx.go b/pkg/volume/portworx/portworx.go index 5ab592d0f0be3..583902ae9914c 100644 --- a/pkg/volume/portworx/portworx.go +++ b/pkg/volume/portworx/portworx.go @@ -84,7 +84,7 @@ func (plugin *portworxVolumePlugin) CanSupport(spec *volume.Spec) bool { (spec.Volume != nil && spec.Volume.PortworxVolume != nil) } -func (plugin *portworxVolumePlugin) IsMigratedToCSI() bool { +func (plugin *portworxVolumePlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/projected/projected.go b/pkg/volume/projected/projected.go index b4e6fc8655cea..9bf68d6d1c764 100644 --- a/pkg/volume/projected/projected.go +++ b/pkg/volume/projected/projected.go @@ -94,7 +94,7 @@ func (plugin *projectedPlugin) CanSupport(spec *volume.Spec) bool { return spec.Volume != nil && spec.Volume.Projected != nil } -func (plugin *projectedPlugin) IsMigratedToCSI() bool { +func (plugin *projectedPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/quobyte/quobyte.go b/pkg/volume/quobyte/quobyte.go index 11cfbff7966f1..a5affc2798dc3 100644 --- a/pkg/volume/quobyte/quobyte.go +++ b/pkg/volume/quobyte/quobyte.go @@ -110,7 +110,7 @@ func (plugin *quobytePlugin) CanSupport(spec *volume.Spec) bool { return false } -func (plugin *quobytePlugin) IsMigratedToCSI() bool { +func (plugin *quobytePlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/rbd/rbd.go b/pkg/volume/rbd/rbd.go index f045cfddcc89c..ce8feb78fe788 100644 --- a/pkg/volume/rbd/rbd.go +++ b/pkg/volume/rbd/rbd.go @@ -107,7 +107,7 @@ func (plugin *rbdPlugin) CanSupport(spec *volume.Spec) bool { return (spec.Volume != nil && spec.Volume.RBD != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.RBD != nil) } -func (plugin *rbdPlugin) IsMigratedToCSI() bool { +func (plugin *rbdPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/scaleio/sio_plugin.go b/pkg/volume/scaleio/sio_plugin.go index 29fe20a0bd3b4..d9d774085d3f2 100644 --- a/pkg/volume/scaleio/sio_plugin.go +++ b/pkg/volume/scaleio/sio_plugin.go @@ -71,7 +71,7 @@ func (p *sioPlugin) CanSupport(spec *volume.Spec) bool { (spec.Volume != nil && spec.Volume.ScaleIO != nil) } -func (plugin *sioPlugin) IsMigratedToCSI() bool { +func (plugin *sioPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/secret/secret.go b/pkg/volume/secret/secret.go index ec08ed780cb20..12c7a3249de37 100644 --- a/pkg/volume/secret/secret.go +++ b/pkg/volume/secret/secret.go @@ -80,7 +80,7 @@ func (plugin *secretPlugin) CanSupport(spec *volume.Spec) bool { return spec.Volume != nil && spec.Volume.Secret != nil } -func (plugin *secretPlugin) IsMigratedToCSI() bool { +func (plugin *secretPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/storageos/storageos.go b/pkg/volume/storageos/storageos.go index 71160411282a6..b8a5dd10202ad 100644 --- a/pkg/volume/storageos/storageos.go +++ b/pkg/volume/storageos/storageos.go @@ -91,7 +91,7 @@ func (plugin *storageosPlugin) CanSupport(spec *volume.Spec) bool { (spec.Volume != nil && spec.Volume.StorageOS != nil) } -func (plugin *storageosPlugin) IsMigratedToCSI() bool { +func (plugin *storageosPlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/testing/testing.go b/pkg/volume/testing/testing.go index 5377e9c2a4ef6..fd34bfe7a4d49 100644 --- a/pkg/volume/testing/testing.go +++ b/pkg/volume/testing/testing.go @@ -301,7 +301,7 @@ func (plugin *FakeVolumePlugin) CanSupport(spec *Spec) bool { return true } -func (plugin *FakeVolumePlugin) IsMigratedToCSI() bool { +func (plugin *FakeVolumePlugin) IsMigratableToCSI() bool { return false } @@ -511,7 +511,7 @@ func (plugin *FakeFileVolumePlugin) CanSupport(spec *Spec) bool { return true } -func (plugin *FakeFileVolumePlugin) IsMigratedToCSI() bool { +func (plugin *FakeFileVolumePlugin) IsMigratableToCSI() bool { return false } diff --git a/pkg/volume/util/operationexecutor/BUILD b/pkg/volume/util/operationexecutor/BUILD index 2499c57a3b5a0..aad3e11a122b9 100644 --- a/pkg/volume/util/operationexecutor/BUILD +++ b/pkg/volume/util/operationexecutor/BUILD @@ -29,9 +29,13 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library", + "//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library", + "//staging/src/k8s.io/csi-api/pkg/client/informers/externalversions:go_default_library", + "//staging/src/k8s.io/csi-api/pkg/client/listers/csi/v1alpha1:go_default_library", "//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library:go_default_library", ], diff --git a/pkg/volume/util/operationexecutor/operation_generator.go b/pkg/volume/util/operationexecutor/operation_generator.go index 457e7d28fdf00..4908a703aeea5 100644 --- a/pkg/volume/util/operationexecutor/operation_generator.go +++ b/pkg/volume/util/operationexecutor/operation_generator.go @@ -27,9 +27,13 @@ import ( "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/wait" utilfeature "k8s.io/apiserver/pkg/util/feature" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/record" + csiapi "k8s.io/csi-api/pkg/apis/csi/v1alpha1" + csiapiinformer "k8s.io/csi-api/pkg/client/informers/externalversions" + csiinformerlisters "k8s.io/csi-api/pkg/client/listers/csi/v1alpha1" expandcache "k8s.io/kubernetes/pkg/controller/volume/expand/cache" "k8s.io/kubernetes/pkg/features" kevents "k8s.io/kubernetes/pkg/kubelet/events" @@ -65,6 +69,16 @@ type operationGenerator struct { // blkUtil provides volume path related operations for block volume blkUtil volumepathhandler.BlockVolumePathHandler + + // csiNodeInfoLister is an informer for the CSINodeInfo CRs + // It currently can only be used on the attach/detach controller + // and only when the CSINodeInfo CRD is installed + csiNodeInfoLister csiinformerlisters.CSINodeInfoLister + + // csiNodeInfoHasSynced returns true if the informer is running and is synced + // It currently can only be used on the attach/detach controller + // and only when the CSINodeInfo CRD is installed + csiNodeInfoHasSynced func() bool } // NewOperationGenerator is returns instance of operationGenerator @@ -73,14 +87,29 @@ func NewOperationGenerator(kubeClient clientset.Interface, recorder record.EventRecorder, checkNodeCapabilitiesBeforeMount bool, blkUtil volumepathhandler.BlockVolumePathHandler) OperationGenerator { - - return &operationGenerator{ - kubeClient: kubeClient, - volumePluginMgr: volumePluginMgr, - recorder: recorder, + og := &operationGenerator{ + kubeClient: kubeClient, + volumePluginMgr: volumePluginMgr, + recorder: recorder, checkNodeCapabilitiesBeforeMount: checkNodeCapabilitiesBeforeMount, - blkUtil: blkUtil, + + blkUtil: blkUtil, + } + + if utilfeature.DefaultFeatureGate.Enabled(features.CSINodeInfo) { + csiKubeClient := volumePluginMgr.Host.GetCSIClient() + if csiKubeClient == nil { + glog.Warningf("The client for CSI Custom Resources is not available, skipping informer initialization") + } else { + factory := csiapiinformer.NewSharedInformerFactory(csiKubeClient, 1*time.Minute) + csiNodeInfos := factory.Csi().V1alpha1().CSINodeInfos() + og.csiNodeInfoHasSynced = csiNodeInfos.Informer().HasSynced + og.csiNodeInfoLister = csiNodeInfos.Lister() + go factory.Start(wait.NeverStop) + } } + + return og } // OperationGenerator interface that extracts out the functions from operation_executor to make it dependency injectable @@ -300,8 +329,13 @@ func (og *operationGenerator) GenerateAttachVolumeFunc( } originalSpec := volumeToAttach.VolumeSpec - // isMigrated will check both CSIMigration and the plugin specific feature gate - if isMigrated(og.volumePluginMgr, volumeToAttach.VolumeSpec) { + + // isMigratable will check both CSIMigration and the plugin specific feature gate and Node Migration + im, err := isMigratable(og, volumeToAttach.VolumeSpec, volumeToAttach.VolumeName, volumeToAttach.NodeName) + if err != nil { + return volumetypes.GeneratedOperations{}, volumeToAttach.GenerateErrorDetailed("AttachVolume.IsMigratable failed", err) + } + if im { // The volume represented by this spec is CSI and thus should be migrated attachableVolumePlugin, err = og.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName) if err != nil || attachableVolumePlugin == nil { @@ -392,17 +426,21 @@ func (og *operationGenerator) GenerateDetachVolumeFunc( if volumeToDetach.VolumeSpec != nil { // Get attacher plugin - // isMigrated will check both CSIMigration and the plugin specific feature gate - if isMigrated(og.volumePluginMgr, volumeToDetach.VolumeSpec) { + // isMigratable will check both CSIMigration and the plugin specific feature gate + im, err := isMigratable(og, volumeToDetach.VolumeSpec, volumeToDetach.VolumeName, volumeToDetach.NodeName) + if err != nil { + return volumetypes.GeneratedOperations{}, volumeToDetach.GenerateErrorDetailed("DetachVolume.IsMigratable failed", err) + } + if im { // The volume represented by this spec is CSI and thus should be migrated attachableVolumePlugin, err = og.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName) if err != nil || attachableVolumePlugin == nil { - return volumetypes.GeneratedOperations{}, volumeToDetach.GenerateErrorDetailed("AttachVolume.FindAttachablePluginBySpec failed", err) + return volumetypes.GeneratedOperations{}, volumeToDetach.GenerateErrorDetailed("DetachVolume.FindAttachablePluginBySpec failed", err) } csiSpec, err := translateSpec(volumeToDetach.VolumeSpec) if err != nil { - return volumetypes.GeneratedOperations{}, volumeToDetach.GenerateErrorDetailed("AttachVolume.TranslateSpec failed", err) + return volumetypes.GeneratedOperations{}, volumeToDetach.GenerateErrorDetailed("DetachVolume.TranslateSpec failed", err) } volumeToDetach.VolumeSpec = csiSpec @@ -430,8 +468,12 @@ func (og *operationGenerator) GenerateDetachVolumeFunc( // TODO(dyzz): This case can't distinguish between PV and In-line which is necessary because // if it was PV it may have been migrated, but the same plugin with in-line may not have been. - // Suggestions welcome... - if csiMigration.IsMigratedByName(pluginName) && utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) { + // fixing this depends on CSI in-line volumes implementation: PR #68232 + inm, err := isNodeMigratable(og, pluginName, volumeToDetach.NodeName) + if err != nil { + return volumetypes.GeneratedOperations{}, volumeToDetach.GenerateErrorDetailed("DetachVolume.IsNodeMigratable failed", err) + } + if csiMigration.IsMigratedByName(pluginName) && utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) && inm { // The volume represented by this spec is CSI and thus should be migrated attachableVolumePlugin, err = og.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName) if err != nil || attachableVolumePlugin == nil { @@ -1504,14 +1546,89 @@ func isDeviceOpened(deviceToDetach AttachedVolume, mounter mount.Interface) (boo return deviceOpened, nil } -func isMigrated(vpm *volume.VolumePluginMgr, spec *volume.Spec) bool { +func isNodeMigratable(og *operationGenerator, pluginName string, nodeName types.NodeName) (bool, error) { + // TODO(dyzz): Write a test that runs with feature flags on, tries to do an inline volume with a migratable volume but without + // driver installed. Should get the correct error message. Then clean up. Try to do a migratable volume but WITH driver installed, + // should succeed (even better if we can check that the driver did something). + var err error + var nodeInfo *csiapi.CSINodeInfo + + pm, err := og.volumePluginMgr.IsPluginMigratableByName(pluginName) + if err != nil { + return false, err + } + + if !pm { + // Feature flags aren't on so migration as a whole is just turned off + return false, nil + } + + if !utilfeature.DefaultFeatureGate.Enabled(features.CSINodeInfo) { + return false, fmt.Errorf("failed to check if node migrated, CSINodeInfo feature gate not enabled") + } + + if og.csiNodeInfoHasSynced() { + nodeInfo, err = og.csiNodeInfoLister.Get(string(nodeName)) + if err != nil { + return false, fmt.Errorf("failed to get CSI node info for node %v from informer: %v", string(nodeName), err) + } + } else { + glog.Warningf("CSINodeInfo informer not synced, please check that CSINodeInfo CRD is installed. If so, this warning should not appear again after ~1 minute") + // Fallback to a GET + nodeInfo, err = og.volumePluginMgr.Host.GetCSIClient().CsiV1alpha1().CSINodeInfos().Get(string(nodeName), metav1.GetOptions{}) + if err != nil { + return false, fmt.Errorf("failed to get CSI node info for node %v: %v", string(nodeName), err) + } + } + + driverName, err := csiMigration.GetCSINameFromIntreeName(pluginName) + if err != nil { + return false, err + } + + for _, driver := range nodeInfo.CSIDrivers { + if driver.Driver == driverName { + return driver.IsDriverMigratableOnNode, nil + } + } + // The plugin is migrated but the driver is not installed + return false, fmt.Errorf("plugin %v is migratable but driver %v is not installed. Please install the driver and retry", pluginName, driverName) +} + +func isMigratable(og *operationGenerator, spec *volume.Spec, uniqueVolumeName v1.UniqueVolumeName, nodeName types.NodeName) (bool, error) { + // IsPluginMigratableBySpec tests whether feature flags are on + pm, err := og.volumePluginMgr.IsPluginMigratableBySpec(spec) + if err != nil { + return false, err + } + + if !pm { + // Feature flags aren't on so migration as a whole is just turned off + return false, nil + } + + pluginName, _, err := util.SplitUniqueName(uniqueVolumeName) + if err != nil { + return false, fmt.Errorf("failed to split unique name %v: %v", uniqueVolumeName, err) + } + driverName, err := csiMigration.GetCSINameFromIntreeName(pluginName) + if err != nil { + return false, err + } + if csiMigration.IsPVMigrated(spec.PersistentVolume) || csiMigration.IsInlineMigrated(spec.Volume) { - migratable, err := vpm.IsPluginMigratableBySpec(spec) - if err == nil && migratable { - return true + inm, err := isNodeMigratable(og, pluginName, nodeName) + if err != nil { + return false, fmt.Errorf("failed to check if driver migrated on node: %v", err) + } + if inm { + return true, nil } } - return false + // If feature flags are on but we're not migratable for some other reason + // it is an error and a good error about installing the driver should be thrown + return false, fmt.Errorf("plugin %v is migratable but driver %v is not installed. Please install the driver and retry", pluginName, driverName) + } func translateSpec(spec *volume.Spec) (*volume.Spec, error) { diff --git a/pkg/volume/vsphere_volume/vsphere_volume.go b/pkg/volume/vsphere_volume/vsphere_volume.go index 4a9557cc71b02..9ab6ef650fa37 100644 --- a/pkg/volume/vsphere_volume/vsphere_volume.go +++ b/pkg/volume/vsphere_volume/vsphere_volume.go @@ -79,7 +79,7 @@ func (plugin *vsphereVolumePlugin) CanSupport(spec *volume.Spec) bool { (spec.Volume != nil && spec.Volume.VsphereVolume != nil) } -func (plugin *vsphereVolumePlugin) IsMigratedToCSI() bool { +func (plugin *vsphereVolumePlugin) IsMigratableToCSI() bool { return false } diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go index ef96322cad00a..4507e2c5d1a13 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go @@ -76,6 +76,9 @@ func buildControllerRoles() ([]rbacv1.ClusterRole, []rbacv1.ClusterRoleBinding) if utilfeature.DefaultFeatureGate.Enabled(features.CSIDriverRegistry) { role.Rules = append(role.Rules, rbacv1helpers.NewRule("get", "watch", "list").Groups("csi.storage.k8s.io").Resources("csidrivers").RuleOrDie()) } + if utilfeature.DefaultFeatureGate.Enabled(features.CSINodeInfo) { + role.Rules = append(role.Rules, rbacv1helpers.NewRule("get", "watch", "list").Groups("csi.storage.k8s.io").Resources("csinodeinfos").RuleOrDie()) + } } return role diff --git a/staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1/types.go b/staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1/types.go index 635f22af8dd56..1910a72142bda 100644 --- a/staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1/types.go +++ b/staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1/types.go @@ -124,6 +124,12 @@ type CSIDriverInfo struct { // determine which labels it should retrieve from the node object and pass // back to the driver. TopologyKeys []string `json:"topologyKeys"` + + // IsDriverMigratableOnNode is a boolean representing whether the node supports + // migration to CSI for this driver. It is used by storage controllers on + // the control plane to determine whether to use a migrated version of the + // plugin for this driver on this node. + IsDriverMigratableOnNode bool `json:"isDriverMigratableOnNode"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/.gitignore b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/.gitignore new file mode 100644 index 0000000000000..566bdf3ab39a7 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/.gitignore @@ -0,0 +1,2 @@ +# vim +*.swp diff --git a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/Gopkg.lock b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/Gopkg.lock index 92acda92c3207..3cc9dd08235ff 100644 --- a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/Gopkg.lock +++ b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/Gopkg.lock @@ -77,7 +77,6 @@ version = "kubernetes-1.12.1" [[projects]] - branch = "release-1.12" digest = "1:01926916f6f34e7cc6230e36e66f9690013adcfd32755aebf03ceb91f9c16864" name = "k8s.io/apimachinery" packages = [ @@ -105,6 +104,7 @@ ] pruneopts = "UT" revision = "6dd46049f39503a1fc8d65de4bd566829e95faff" + version = "kubernetes-1.12.0" [solve-meta] analyzer-name = "dep" diff --git a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/Gopkg.toml b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/Gopkg.toml index cf7f5b273aa3b..dd3170ca06deb 100644 --- a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/Gopkg.toml +++ b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/Gopkg.toml @@ -30,8 +30,8 @@ version = "kubernetes-1.12.1" [[constraint]] - branch = "release-1.12" name = "k8s.io/apimachinery" + version = "kubernetes-1.12.0" [prune] go-tests = true diff --git a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/BUILD b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/BUILD index 872913f55dc29..7da2158dbd04d 100644 --- a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/BUILD +++ b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/BUILD @@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "go_default_library", srcs = [ + "aws_ebs.go", "gce_pd.go", "in_tree_volume.go", ], diff --git a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/aws_ebs.go b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/aws_ebs.go new file mode 100644 index 0000000000000..1b48b57aa2683 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/aws_ebs.go @@ -0,0 +1,94 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package plugins + +import ( + "fmt" + "strconv" + + "k8s.io/api/core/v1" +) + +const ( + AWSEBSDriverName = "com.amazon.aws.csi.ebs" + AWSEBSInTreePluginName = "kubernetes.io/aws-ebs" +) + +type AWSEBS struct{} + +// TranslateToCSI takes a volume.Spec and will translate it to a +// CSIPersistentVolumeSource if the translation logic for that +// specific in-tree volume spec has been implemented +func (t *AWSEBS) TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { + if pv == nil || pv.Spec.AWSElasticBlockStore == nil { + return nil, fmt.Errorf("pv is nil or AWS EBS not defined on pv") + } + + ebsSource := pv.Spec.AWSElasticBlockStore + + csiSource := &v1.CSIPersistentVolumeSource{ + Driver: AWSEBSDriverName, + VolumeHandle: ebsSource.VolumeID, + ReadOnly: ebsSource.ReadOnly, + FSType: ebsSource.FSType, + VolumeAttributes: map[string]string{ + "partition": strconv.FormatInt(int64(ebsSource.Partition), 10), + }, + } + + pv.Spec.AWSElasticBlockStore = nil + pv.Spec.CSI = csiSource + return pv, nil +} + +// TranslateToIntree takes a CSIPersistentVolumeSource and will translate +// it to a volume.Spec for the specific in-tree volume specified by +//`inTreePlugin`, if that translation logic has been implemented +func (t *AWSEBS) TranslateCSIPVToInTree(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { + if pv == nil || pv.Spec.CSI == nil { + return nil, fmt.Errorf("pv is nil or CSI source not defined on pv") + } + + csiSource := pv.Spec.CSI + + ebsSource := &v1.AWSElasticBlockStoreVolumeSource{ + VolumeID: csiSource.VolumeHandle, + FSType: csiSource.FSType, + ReadOnly: csiSource.ReadOnly, + } + + if partition, ok := csiSource.VolumeAttributes["partition"]; ok { + partValue, err := strconv.Atoi(partition) + if err != nil { + return nil, fmt.Errorf("Failed to convert partition %v to integer: %v", partition, err) + } + ebsSource.Partition = int32(partValue) + } + + pv.Spec.CSI = nil + pv.Spec.AWSElasticBlockStore = ebsSource + return pv, nil +} + +// CanSupport tests whether the plugin supports a given volume +// specification from the API. The spec pointer should be considered +// const. +func (t *AWSEBS) CanSupport(pv *v1.PersistentVolume) bool { + return pv != nil && pv.Spec.AWSElasticBlockStore != nil +} + +func (t *AWSEBS) GetInTreePluginName() string { + return AWSEBSInTreePluginName +} diff --git a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/gce_pd.go b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/gce_pd.go index 6d3fab637bdd3..05fbb2c33ed7d 100644 --- a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/gce_pd.go +++ b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/gce_pd.go @@ -51,7 +51,7 @@ func (g *GCEPD) TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentV var volID string if pv == nil || pv.Spec.GCEPersistentDisk == nil { - return nil, fmt.Errorf("GCE Persistent Disk source not defined on pv") + return nil, fmt.Errorf("pv is nil or GCE Persistent Disk source not defined on pv") } zonesLabel := pv.Labels[LabelZoneFailureDomain] @@ -93,7 +93,7 @@ func (g *GCEPD) TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentV //`inTreePlugin`, if that translation logic has been implemented func (g *GCEPD) TranslateCSIPVToInTree(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { if pv == nil || pv.Spec.CSI == nil { - return nil, fmt.Errorf("CSI source not defined on pv") + return nil, fmt.Errorf("pv is nil or CSI source not defined on pv") } csiSource := pv.Spec.CSI diff --git a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/in_tree_volume.go b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/in_tree_volume.go index d61666b080be0..28882d2304296 100644 --- a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/in_tree_volume.go +++ b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/plugins/in_tree_volume.go @@ -14,9 +14,7 @@ limitations under the License. package plugins -import ( - "k8s.io/api/core/v1" -) +import "k8s.io/api/core/v1" type InTreePlugin interface { // TranslateToCSI takes a persistent volume and will translate diff --git a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/translate.go b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/translate.go index f725ff941e2f9..90de606cd312d 100644 --- a/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/translate.go +++ b/vendor/github.com/kubernetes-csi/kubernetes-csi-migration-library/translate.go @@ -23,7 +23,8 @@ import ( var ( inTreePlugins = map[string]plugins.InTreePlugin{ - plugins.GCEPDDriverName: &plugins.GCEPD{}, + plugins.GCEPDDriverName: &plugins.GCEPD{}, + plugins.AWSEBSDriverName: &plugins.AWSEBS{}, } ) @@ -71,6 +72,15 @@ func IsMigratedByName(pluginName string) bool { return false } +func GetCSINameFromIntreeName(pluginName string) (string, error) { + for csiDriverName, curPlugin := range inTreePlugins { + if curPlugin.GetInTreePluginName() == pluginName { + return csiDriverName, nil + } + } + return "", fmt.Errorf("Could not find CSI Driver name for plugin %v", pluginName) +} + // IsPVMigrated tests whether there is Migration logic for the given Persistent Volume func IsPVMigrated(pv *v1.PersistentVolume) bool { for _, curPlugin := range inTreePlugins {