diff --git a/pkg/api/types.go b/pkg/api/types.go index b937ed12da5..e04722adec4 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -624,9 +624,8 @@ type RBDVolumeSource struct { type CinderVolumeSource struct { // Unique id of the volume used to identify the cinder volume VolumeID string `json:"volumeID"` - // Required: Filesystem type to mount. + // Filesystem type to mount. // Must be a filesystem type supported by the host operating system. - // Only ext3 and ext4 are allowed FSType string `json:"fsType,omitempty"` // Optional: Defaults to false (read/write). ReadOnly here will force // the ReadOnly setting in VolumeMounts. diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index 52f31a76862..5cce6baa105 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -689,7 +689,7 @@ func validateCinderVolumeSource(cd *api.CinderVolumeSource, fldPath *field.Path) if len(cd.VolumeID) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("volumeID"), "")) } - if len(cd.FSType) == 0 || (cd.FSType != "ext3" && cd.FSType != "ext4") { + if len(cd.FSType) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("fsType"), "")) } return allErrs diff --git a/pkg/volume/cinder/cinder.go b/pkg/volume/cinder/cinder.go index b54c4b89a0a..8240fd707a0 100644 --- a/pkg/volume/cinder/cinder.go +++ b/pkg/volume/cinder/cinder.go @@ -97,7 +97,7 @@ func (plugin *cinderPlugin) newBuilderInternal(spec *volume.Spec, podUID types.U }, fsType: fsType, readOnly: readOnly, - blockDeviceMounter: &cinderSafeFormatAndMount{mounter, exec.New()}}, nil + blockDeviceMounter: &mount.SafeFormatAndMount{mounter, exec.New()}}, nil } func (plugin *cinderPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { @@ -181,7 +181,7 @@ type cinderVolumeBuilder struct { *cinderVolume fsType string readOnly bool - blockDeviceMounter mount.Interface + blockDeviceMounter *mount.SafeFormatAndMount } // cinderPersistentDisk volumes are disk resources provided by C3 diff --git a/pkg/volume/cinder/cinder_util.go b/pkg/volume/cinder/cinder_util.go index 69982e789d9..f449e09f095 100644 --- a/pkg/volume/cinder/cinder_util.go +++ b/pkg/volume/cinder/cinder_util.go @@ -18,7 +18,6 @@ package cinder import ( "errors" - "fmt" "io/ioutil" "os" "path" @@ -27,7 +26,6 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/util/exec" - "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" ) @@ -69,7 +67,6 @@ func (util *CinderDiskUtil) AttachDisk(b *cinderVolumeBuilder, globalPDPath stri } time.Sleep(time.Second * 6) } - notmnt, err := b.mounter.IsLikelyNotMountPoint(globalPDPath) if err != nil { if os.IsNotExist(err) { @@ -82,7 +79,7 @@ func (util *CinderDiskUtil) AttachDisk(b *cinderVolumeBuilder, globalPDPath stri } } if notmnt { - err = b.blockDeviceMounter.Mount(devicePath, globalPDPath, b.fsType, options) + err = b.blockDeviceMounter.FormatAndMount(devicePath, globalPDPath, b.fsType, options) if err != nil { os.Remove(globalPDPath) return err @@ -162,72 +159,6 @@ func (util *CinderDiskUtil) CreateVolume(c *cinderVolumeProvisioner) (volumeID s return name, volSizeGB, nil } -type cinderSafeFormatAndMount struct { - mount.Interface - runner exec.Interface -} - -/* -The functions below depend on the following executables; This will have to be ported to more generic implementations -/bin/lsblk -/sbin/mkfs.ext3 or /sbin/mkfs.ext4 -/usr/bin/udevadm -*/ -func (diskmounter *cinderSafeFormatAndMount) Mount(device string, target string, fstype string, options []string) error { - fmtRequired, err := isFormatRequired(device, fstype, diskmounter) - if err != nil { - glog.Warningf("Failed to determine if formating is required: %v\n", err) - //return err - } - if fmtRequired { - glog.V(2).Infof("Formatting of the vol required") - if _, err := formatVolume(device, fstype, diskmounter); err != nil { - glog.Warningf("Failed to format volume: %v\n", err) - return err - } - } - return diskmounter.Interface.Mount(device, target, fstype, options) -} - -func isFormatRequired(devicePath string, fstype string, exec *cinderSafeFormatAndMount) (bool, error) { - args := []string{"-f", devicePath} - glog.V(4).Infof("exec-ing: /bin/lsblk %v\n", args) - cmd := exec.runner.Command("/bin/lsblk", args...) - dataOut, err := cmd.CombinedOutput() - if err != nil { - glog.Warningf("error running /bin/lsblk\n%s", string(dataOut)) - return false, err - } - if len(string(dataOut)) > 0 { - if strings.Contains(string(dataOut), fstype) { - return false, nil - } else { - return true, nil - } - } else { - glog.Warningf("Failed to get any response from /bin/lsblk") - return false, errors.New("Failed to get reponse from /bin/lsblk") - } - glog.Warningf("Unknown error occured executing /bin/lsblk") - return false, errors.New("Unknown error occured executing /bin/lsblk") -} - -func formatVolume(devicePath string, fstype string, exec *cinderSafeFormatAndMount) (bool, error) { - if "ext4" != fstype && "ext3" != fstype { - glog.Warningf("Unsupported format type: %q\n", fstype) - return false, errors.New(fmt.Sprint("Unsupported format type: %q\n", fstype)) - } - args := []string{devicePath} - cmd := exec.runner.Command(fmt.Sprintf("/sbin/mkfs.%s", fstype), args...) - dataOut, err := cmd.CombinedOutput() - if err != nil { - glog.Warningf("error running /sbin/mkfs for fstype: %q \n%s", fstype, string(dataOut)) - return false, err - } - glog.V(2).Infof("Successfully formated device: %q with fstype %q; output:\n %q\n,", devicePath, fstype, string(dataOut)) - return true, err -} - func probeAttachedVolume() error { executor := exec.New() args := []string{"trigger"} diff --git a/pkg/volume/cinder/cinder_util_test.go b/pkg/volume/cinder/cinder_util_test.go deleted file mode 100644 index 44ea17c05a1..00000000000 --- a/pkg/volume/cinder/cinder_util_test.go +++ /dev/null @@ -1,82 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -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 cinder - -import ( - "testing" - - "k8s.io/kubernetes/pkg/util/exec" - "k8s.io/kubernetes/pkg/util/mount" -) - -func TestSafeFormatAndMount(t *testing.T) { - tests := []struct { - fstype string - expectedArgs []string - err error - }{ - { - fstype: "ext4", - expectedArgs: []string{"/dev/foo", "/mnt/bar"}, - }, - { - fstype: "ext3", - expectedArgs: []string{"/dev/foo/blah", "/mnt/bar/blah"}, - }, - } - for _, test := range tests { - - var cmdOut string - var argsOut []string - fake := exec.FakeExec{ - CommandScript: []exec.FakeCommandAction{ - func(cmd string, args ...string) exec.Cmd { - cmdOut = cmd - argsOut = args - fake := exec.FakeCmd{ - CombinedOutputScript: []exec.FakeCombinedOutputAction{ - func() ([]byte, error) { return []byte{}, test.err }, - }, - } - return exec.InitFakeCmd(&fake, cmd, args...) - }, - }, - } - - mounter := cinderSafeFormatAndMount{ - &mount.FakeMounter{}, - &fake, - } - - err := mounter.Mount("/dev/foo", "/mnt/bar", test.fstype, nil) - if test.err == nil && err != nil { - t.Errorf("unexpected error: %v", err) - } - if test.err != nil { - if err == nil { - t.Errorf("unexpected non-error") - } - return - } - if cmdOut != "/bin/lsblk" { - t.Errorf("unexpected command: %s", cmdOut) - } - if len(argsOut) != len(test.expectedArgs) { - t.Errorf("unexpected args: %v, expected: %v", argsOut, test.expectedArgs) - } - } -}