Merge pull request #17650 from jsafrane/devel/cinder-format

Auto commit by PR queue bot
This commit is contained in:
k8s-merge-robot 2016-01-20 22:18:25 -08:00
commit 8ed248021e
5 changed files with 5 additions and 157 deletions

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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"}

View File

@ -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)
}
}
}