diff --git a/pkg/volume/glusterfs/glusterfs.go b/pkg/volume/glusterfs/glusterfs.go index e5c658dafd..7589da50f9 100644 --- a/pkg/volume/glusterfs/glusterfs.go +++ b/pkg/volume/glusterfs/glusterfs.go @@ -17,6 +17,7 @@ limitations under the License. package glusterfs import ( + "fmt" "os" "path" @@ -31,11 +32,12 @@ import ( // This is the primary entrypoint for volume plugins. func ProbeVolumePlugins() []volume.VolumePlugin { - return []volume.VolumePlugin{&glusterfsPlugin{nil}} + return []volume.VolumePlugin{&glusterfsPlugin{nil, exec.New()}} } type glusterfsPlugin struct { host volume.VolumeHost + exe exec.Interface } var _ volume.VolumePlugin = &glusterfsPlugin{} @@ -54,8 +56,20 @@ func (plugin *glusterfsPlugin) Name() string { } func (plugin *glusterfsPlugin) CanSupport(spec *volume.Spec) bool { - return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.Glusterfs != nil) || - (spec.Volume != nil && spec.Volume.Glusterfs != nil) + if (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.Glusterfs == nil) || + (spec.Volume != nil && spec.Volume.Glusterfs == nil) { + return false + } + // see if glusterfs mount helper is there + // this needs a ls because the plugin container may be on a filesystem + // that is not visible to the volume plugin process. + _, err := plugin.execCommand("ls", []string{"/sbin/mount.glusterfs"}) + if err == nil { + return true + } + + return false + } func (plugin *glusterfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { @@ -72,10 +86,10 @@ func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ vol ns := pod.Namespace ep, err := plugin.host.GetKubeClient().Endpoints(ns).Get(ep_name) if err != nil { - glog.Errorf("Glusterfs: failed to get endpoints %s[%v]", ep_name, err) + glog.Errorf("glusterfs: failed to get endpoints %s[%v]", ep_name, err) return nil, err } - glog.V(1).Infof("Glusterfs: endpoints %v", ep) + glog.V(1).Infof("glusterfs: endpoints %v", ep) return plugin.newBuilderInternal(spec, ep, pod, plugin.host.GetMounter(), exec.New()) } @@ -117,6 +131,11 @@ func (plugin *glusterfsPlugin) newCleanerInternal(volName string, podUID types.U }}, nil } +func (plugin *glusterfsPlugin) execCommand(command string, args []string) ([]byte, error) { + cmd := plugin.exe.Command(command, args...) + return cmd.CombinedOutput() +} + // Glusterfs volumes represent a bare host file or directory mount of an Glusterfs export. type glusterfs struct { volName string @@ -142,7 +161,7 @@ func (b *glusterfsBuilder) SetUp() error { func (b *glusterfsBuilder) SetUpAt(dir string) error { notMnt, err := b.mounter.IsLikelyNotMountPoint(dir) - glog.V(4).Infof("Glusterfs: mount set up: %s %v %v", dir, !notMnt, err) + glog.V(4).Infof("glusterfs: mount set up: %s %v %v", dir, !notMnt, err) if err != nil && !os.IsNotExist(err) { return err } @@ -188,25 +207,22 @@ func (c *glusterfsCleaner) TearDownAt(dir string) error { func (c *glusterfsCleaner) cleanup(dir string) error { notMnt, err := c.mounter.IsLikelyNotMountPoint(dir) if err != nil { - glog.Errorf("Glusterfs: Error checking IsLikelyNotMountPoint: %v", err) - return err + return fmt.Errorf("glusterfs: Error checking IsLikelyNotMountPoint: %v", err) } if notMnt { return os.RemoveAll(dir) } if err := c.mounter.Unmount(dir); err != nil { - glog.Errorf("Glusterfs: Unmounting failed: %v", err) - return err + return fmt.Errorf("glusterfs: Unmounting failed: %v", err) } notMnt, mntErr := c.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { - glog.Errorf("Glusterfs: IsLikelyNotMountPoint check failed: %v", mntErr) - return mntErr + return fmt.Errorf("glusterfs: IsLikelyNotMountPoint check failed: %v", mntErr) } if notMnt { if err := os.RemoveAll(dir); err != nil { - return err + return fmt.Errorf("glusterfs: RemoveAll failed: %v", err) } } @@ -223,7 +239,7 @@ func (b *glusterfsBuilder) setUpAtInternal(dir string) error { p := path.Join(b.glusterfs.plugin.host.GetPluginDir(glusterfsPluginName), b.glusterfs.volName) if err := os.MkdirAll(p, 0750); err != nil { - return err + return fmt.Errorf("glusterfs: mkdir failed: %v", err) } log := path.Join(p, "glusterfs.log") options = append(options, "log-file="+log) @@ -243,6 +259,5 @@ func (b *glusterfsBuilder) setUpAtInternal(dir string) error { return nil } } - glog.Errorf("Glusterfs: mount failed: %v", errs) - return errs + return fmt.Errorf("glusterfs: mount failed: %v", errs) } diff --git a/pkg/volume/glusterfs/glusterfs_test.go b/pkg/volume/glusterfs/glusterfs_test.go index 74250e59e8..4d7f55938a 100644 --- a/pkg/volume/glusterfs/glusterfs_test.go +++ b/pkg/volume/glusterfs/glusterfs_test.go @@ -39,11 +39,8 @@ func TestCanSupport(t *testing.T) { if plug.Name() != "kubernetes.io/glusterfs" { t.Errorf("Wrong name: %s", plug.Name()) } - if !plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{Glusterfs: &api.GlusterfsVolumeSource{}}}}) { - t.Errorf("Expected true") - } - if !plug.CanSupport(&volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{Glusterfs: &api.GlusterfsVolumeSource{}}}}}) { - t.Errorf("Expected true") + if plug.CanSupport(&volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{}}}}) { + t.Errorf("Expected false") } if plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{}}}) { t.Errorf("Expected false")