From 3d3e44e77ed19a00713d48520de81b100490e146 Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Tue, 15 Nov 2016 11:54:50 -0800 Subject: [PATCH] fix issue in converting aws volume id from mount paths This PR is to fix the issue in converting aws volume id from mount paths. Currently there are three aws volume id formats supported. The following lists example of those three formats and their corresponding global mount paths: 1. aws:///vol-123456 (/var/lib/kubelet/plugins/kubernetes.io/aws-ebs/mounts/aws/vol-123456) 2. aws://us-east-1/vol-123456 (/var/lib/kubelet/plugins/kubernetes.io/mounts/aws/us-est-1/vol-123455) 3. vol-123456 (/var/lib/kubelet/plugins/kubernetes.io/mounts/aws/us-est-1/vol-123455) For the first two cases, we need to check the mount path and convert them back to the original format. --- .../attachdetach/reconciler/reconciler.go | 4 +-- pkg/util/mount/mount.go | 13 ++++++-- pkg/volume/aws_ebs/aws_ebs.go | 33 +++++++++++++++++-- pkg/volume/azure_dd/azure_dd.go | 2 +- pkg/volume/cinder/cinder.go | 2 +- pkg/volume/gce_pd/gce_pd.go | 2 +- pkg/volume/photon_pd/photon_pd.go | 2 +- pkg/volume/vsphere_volume/vsphere_volume.go | 2 +- 8 files changed, 47 insertions(+), 13 deletions(-) diff --git a/pkg/controller/volume/attachdetach/reconciler/reconciler.go b/pkg/controller/volume/attachdetach/reconciler/reconciler.go index 74c330cd75d..b12bd113eb3 100644 --- a/pkg/controller/volume/attachdetach/reconciler/reconciler.go +++ b/pkg/controller/volume/attachdetach/reconciler/reconciler.go @@ -192,11 +192,11 @@ func (rc *reconciler) reconcile() { if rc.actualStateOfWorld.VolumeNodeExists( volumeToAttach.VolumeName, volumeToAttach.NodeName) { // Volume/Node exists, touch it to reset detachRequestedTime - glog.V(1).Infof("Volume %q/Node %q is attached--touching.", volumeToAttach.VolumeName, volumeToAttach.NodeName) + glog.V(5).Infof("Volume %q/Node %q is attached--touching.", volumeToAttach.VolumeName, volumeToAttach.NodeName) rc.actualStateOfWorld.ResetDetachRequestTime(volumeToAttach.VolumeName, volumeToAttach.NodeName) } else { // Volume/Node doesn't exist, spawn a goroutine to attach it - glog.V(1).Infof("Attempting to start AttachVolume for volume %q to node %q", volumeToAttach.VolumeName, volumeToAttach.NodeName) + glog.V(5).Infof("Attempting to start AttachVolume for volume %q to node %q", volumeToAttach.VolumeName, volumeToAttach.NodeName) err := rc.attacherDetacher.AttachVolume(volumeToAttach.VolumeToAttach, rc.actualStateOfWorld) if err == nil { glog.Infof("Started AttachVolume for volume %q to node %q", volumeToAttach.VolumeName, volumeToAttach.NodeName) diff --git a/pkg/util/mount/mount.go b/pkg/util/mount/mount.go index 02ef476b1f5..8796d6a52d5 100644 --- a/pkg/util/mount/mount.go +++ b/pkg/util/mount/mount.go @@ -30,7 +30,8 @@ import ( const ( // Default mount command if mounter path is not specified - defaultMountCommand = "mount" + defaultMountCommand = "mount" + MountsInGlobalPDPath = "mounts" ) type Interface interface { @@ -189,9 +190,15 @@ func getDeviceNameFromMount(mounter Interface, mountPath, pluginDir string) (str glog.V(4).Infof("Directory %s is not mounted", mountPath) return "", fmt.Errorf("directory %s is not mounted", mountPath) } + basemountPath := path.Join(pluginDir, MountsInGlobalPDPath) for _, ref := range refs { - if strings.HasPrefix(ref, pluginDir) { - return path.Base(ref), nil + if strings.HasPrefix(ref, basemountPath) { + volumeID, err := filepath.Rel(basemountPath, ref) + if err != nil { + glog.Errorf("Failed to get volume id from mount %s - %v", mountPath, err) + return "", err + } + return volumeID, nil } } diff --git a/pkg/volume/aws_ebs/aws_ebs.go b/pkg/volume/aws_ebs/aws_ebs.go index c9bf5f7265c..1b786bad27d 100644 --- a/pkg/volume/aws_ebs/aws_ebs.go +++ b/pkg/volume/aws_ebs/aws_ebs.go @@ -51,6 +51,7 @@ var _ volume.ProvisionableVolumePlugin = &awsElasticBlockStorePlugin{} const ( awsElasticBlockStorePluginName = "kubernetes.io/aws-ebs" + awsURLNamePrefix = "aws://" ) func getPath(uid types.UID, volName string, host volume.VolumeHost) string { @@ -189,10 +190,36 @@ func getVolumeSource( func (plugin *awsElasticBlockStorePlugin) ConstructVolumeSpec(volName, mountPath string) (*volume.Spec, error) { mounter := plugin.host.GetMounter() pluginDir := plugin.host.GetPluginDir(plugin.GetPluginName()) - sourceName, err := mounter.GetDeviceNameFromMount(mountPath, pluginDir) + volumeID, err := mounter.GetDeviceNameFromMount(mountPath, pluginDir) if err != nil { return nil, err } + // This is a workaround to fix the issue in converting aws volume id from globalPDPath + // There are three aws volume id formats and their volumeID from GetDeviceNameFromMount() are: + // aws:///vol-1234 (aws/vol-1234) + // aws://us-east-1/vol-1234 (aws/us-east-1/vol-1234) + // vol-1234 (vol-1234) + // This code is for converting volume id to aws style volume id for the first two cases. + sourceName := volumeID + if strings.HasPrefix(volumeID, "aws/") { + names := strings.Split(volumeID, "/") + length := len(names) + if length < 2 || length > 3 { + return nil, fmt.Errorf("Failed to get AWS volume id from mount path %q: invalid volume name format %q", mountPath, volumeID) + } + volName := names[length-1] + if !strings.HasPrefix(volName, "vol-") { + return nil, fmt.Errorf("Invalid volume name format for AWS volume (%q) retrieved from mount path %q", volName, mountPath) + } + if length == 2 { + sourceName = awsURLNamePrefix + "" + "/" + volName // empty zone label + } + if length == 3 { + sourceName = awsURLNamePrefix + names[1] + "/" + volName // names[1] is the zone label + } + glog.V(4).Info("Convert aws volume name from %q to %q ", volumeID, sourceName) + } + awsVolume := &api.Volume{ Name: volName, VolumeSource: api.VolumeSource{ @@ -324,12 +351,12 @@ func makeGlobalPDPath(host volume.VolumeHost, volumeID aws.KubernetesVolumeID) s // Clean up the URI to be more fs-friendly name := string(volumeID) name = strings.Replace(name, "://", "/", -1) - return path.Join(host.GetPluginDir(awsElasticBlockStorePluginName), "mounts", name) + return path.Join(host.GetPluginDir(awsElasticBlockStorePluginName), mount.MountsInGlobalPDPath, name) } // Reverses the mapping done in makeGlobalPDPath func getVolumeIDFromGlobalMount(host volume.VolumeHost, globalPath string) (string, error) { - basePath := path.Join(host.GetPluginDir(awsElasticBlockStorePluginName), "mounts") + basePath := path.Join(host.GetPluginDir(awsElasticBlockStorePluginName), mount.MountsInGlobalPDPath) rel, err := filepath.Rel(basePath, globalPath) if err != nil { glog.Errorf("Failed to get volume id from global mount %s - %v", globalPath, err) diff --git a/pkg/volume/azure_dd/azure_dd.go b/pkg/volume/azure_dd/azure_dd.go index d8ca6886ddf..a7f97ca59e6 100644 --- a/pkg/volume/azure_dd/azure_dd.go +++ b/pkg/volume/azure_dd/azure_dd.go @@ -293,7 +293,7 @@ func (b *azureDiskMounter) SetUpAt(dir string, fsGroup *int64) error { } func makeGlobalPDPath(host volume.VolumeHost, volume string) string { - return path.Join(host.GetPluginDir(azureDataDiskPluginName), "mounts", volume) + return path.Join(host.GetPluginDir(azureDataDiskPluginName), mount.MountsInGlobalPDPath, volume) } func (azure *azureDisk) GetPath() string { diff --git a/pkg/volume/cinder/cinder.go b/pkg/volume/cinder/cinder.go index 093cc04d877..41a4b146edd 100644 --- a/pkg/volume/cinder/cinder.go +++ b/pkg/volume/cinder/cinder.go @@ -365,7 +365,7 @@ func (b *cinderVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { } func makeGlobalPDName(host volume.VolumeHost, devName string) string { - return path.Join(host.GetPluginDir(cinderVolumePluginName), "mounts", devName) + return path.Join(host.GetPluginDir(cinderVolumePluginName), mount.MountsInGlobalPDPath, devName) } func (cd *cinderVolume) GetPath() string { diff --git a/pkg/volume/gce_pd/gce_pd.go b/pkg/volume/gce_pd/gce_pd.go index d17543b1e80..b9fca2c2659 100644 --- a/pkg/volume/gce_pd/gce_pd.go +++ b/pkg/volume/gce_pd/gce_pd.go @@ -314,7 +314,7 @@ func (b *gcePersistentDiskMounter) SetUpAt(dir string, fsGroup *int64) error { } func makeGlobalPDName(host volume.VolumeHost, devName string) string { - return path.Join(host.GetPluginDir(gcePersistentDiskPluginName), "mounts", devName) + return path.Join(host.GetPluginDir(gcePersistentDiskPluginName), mount.MountsInGlobalPDPath, devName) } func (b *gcePersistentDiskMounter) GetPath() string { diff --git a/pkg/volume/photon_pd/photon_pd.go b/pkg/volume/photon_pd/photon_pd.go index 809498750e9..b100080da3c 100644 --- a/pkg/volume/photon_pd/photon_pd.go +++ b/pkg/volume/photon_pd/photon_pd.go @@ -283,7 +283,7 @@ func (c *photonPersistentDiskUnmounter) TearDownAt(dir string) error { } func makeGlobalPDPath(host volume.VolumeHost, devName string) string { - return path.Join(host.GetPluginDir(photonPersistentDiskPluginName), "mounts", devName) + return path.Join(host.GetPluginDir(photonPersistentDiskPluginName), mount.MountsInGlobalPDPath, devName) } func (ppd *photonPersistentDisk) GetPath() string { diff --git a/pkg/volume/vsphere_volume/vsphere_volume.go b/pkg/volume/vsphere_volume/vsphere_volume.go index d2dd86a1a49..218b022780f 100644 --- a/pkg/volume/vsphere_volume/vsphere_volume.go +++ b/pkg/volume/vsphere_volume/vsphere_volume.go @@ -276,7 +276,7 @@ func (v *vsphereVolumeUnmounter) TearDownAt(dir string) error { } func makeGlobalPDPath(host volume.VolumeHost, devName string) string { - return path.Join(host.GetPluginDir(vsphereVolumePluginName), "mounts", devName) + return path.Join(host.GetPluginDir(vsphereVolumePluginName), mount.MountsInGlobalPDPath, devName) } func (vv *vsphereVolume) GetPath() string {