mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
Fresh dep ensure
This commit is contained in:
54
vendor/k8s.io/kubernetes/pkg/volume/local/BUILD
generated
vendored
54
vendor/k8s.io/kubernetes/pkg/volume/local/BUILD
generated
vendored
@ -16,54 +16,48 @@ go_library(
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//pkg/volume/validation:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1: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/client-go/tools/record:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = select({
|
||||
"@io_bazel_rules_go//go/platform:darwin": [
|
||||
"local_test.go",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:linux": [
|
||||
"local_linux_test.go",
|
||||
"local_test.go",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:windows": [
|
||||
"local_test.go",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
srcs = [
|
||||
"local_linux_test.go",
|
||||
"local_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = select({
|
||||
"@io_bazel_rules_go//go/platform:darwin": [
|
||||
"//pkg/util/mount:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/testing:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/testing:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1: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/client-go/util/testing:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:linux": [
|
||||
"//pkg/util/mount:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/testing:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/testing:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1: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/client-go/util/testing:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:windows": [
|
||||
"//pkg/util/mount:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/testing:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/testing:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1: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/client-go/util/testing:go_default_library",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
|
216
vendor/k8s.io/kubernetes/pkg/volume/local/local.go
generated
vendored
216
vendor/k8s.io/kubernetes/pkg/volume/local/local.go
generated
vendored
@ -23,7 +23,7 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -38,6 +38,10 @@ import (
|
||||
"k8s.io/kubernetes/pkg/volume/validation"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultFSType = "ext4"
|
||||
)
|
||||
|
||||
// This is the primary entrypoint for volume plugins.
|
||||
func ProbeVolumePlugins() []volume.VolumePlugin {
|
||||
return []volume.VolumePlugin{&localVolumePlugin{}}
|
||||
@ -59,7 +63,7 @@ const (
|
||||
|
||||
func (plugin *localVolumePlugin) Init(host volume.VolumeHost) error {
|
||||
plugin.host = host
|
||||
plugin.volumeLocks = keymutex.NewKeyMutex()
|
||||
plugin.volumeLocks = keymutex.NewHashed(0)
|
||||
plugin.recorder = host.GetEventRecorder()
|
||||
return nil
|
||||
}
|
||||
@ -83,7 +87,7 @@ func (plugin *localVolumePlugin) RequiresRemount() bool {
|
||||
}
|
||||
|
||||
func (plugin *localVolumePlugin) SupportsMountOption() bool {
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
func (plugin *localVolumePlugin) SupportsBulkVolumeVerification() bool {
|
||||
@ -106,7 +110,12 @@ func getVolumeSource(spec *volume.Spec) (*v1.LocalVolumeSource, bool, error) {
|
||||
}
|
||||
|
||||
func (plugin *localVolumePlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ volume.VolumeOptions) (volume.Mounter, error) {
|
||||
volumeSource, readOnly, err := getVolumeSource(spec)
|
||||
_, readOnly, err := getVolumeSource(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
globalLocalPath, err := plugin.getGlobalLocalPath(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -118,10 +127,11 @@ func (plugin *localVolumePlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ vo
|
||||
volName: spec.Name(),
|
||||
mounter: plugin.host.GetMounter(plugin.GetPluginName()),
|
||||
plugin: plugin,
|
||||
globalPath: volumeSource.Path,
|
||||
MetricsProvider: volume.NewMetricsStatFS(volumeSource.Path),
|
||||
globalPath: globalLocalPath,
|
||||
MetricsProvider: volume.NewMetricsStatFS(plugin.host.GetPodVolumeDir(pod.UID, stringsutil.EscapeQualifiedNameForDisk(localVolumePluginName), spec.Name())),
|
||||
},
|
||||
readOnly: readOnly,
|
||||
mountOptions: util.MountOptionFromSpec(spec),
|
||||
readOnly: readOnly,
|
||||
}, nil
|
||||
|
||||
}
|
||||
@ -169,6 +179,7 @@ func (plugin *localVolumePlugin) NewBlockVolumeUnmapper(volName string,
|
||||
|
||||
// TODO: check if no path and no topology constraints are ok
|
||||
func (plugin *localVolumePlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volume.Spec, error) {
|
||||
fs := v1.PersistentVolumeFilesystem
|
||||
localVolume := &v1.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: volumeName,
|
||||
@ -179,6 +190,7 @@ func (plugin *localVolumePlugin) ConstructVolumeSpec(volumeName, mountPath strin
|
||||
Path: "",
|
||||
},
|
||||
},
|
||||
VolumeMode: &fs,
|
||||
},
|
||||
}
|
||||
return volume.NewSpecFromPersistentVolume(localVolume, false), nil
|
||||
@ -205,6 +217,162 @@ func (plugin *localVolumePlugin) ConstructBlockVolumeSpec(podUID types.UID, volu
|
||||
return volume.NewSpecFromPersistentVolume(localVolume, false), nil
|
||||
}
|
||||
|
||||
func (plugin *localVolumePlugin) generateBlockDeviceBaseGlobalPath() string {
|
||||
return filepath.Join(plugin.host.GetPluginDir(localVolumePluginName), mount.MountsInGlobalPDPath)
|
||||
}
|
||||
|
||||
func (plugin *localVolumePlugin) getGlobalLocalPath(spec *volume.Spec) (string, error) {
|
||||
if spec.PersistentVolume.Spec.Local == nil || len(spec.PersistentVolume.Spec.Local.Path) == 0 {
|
||||
return "", fmt.Errorf("local volume source is nil or local path is not set")
|
||||
}
|
||||
|
||||
fileType, err := plugin.host.GetMounter(plugin.GetPluginName()).GetFileType(spec.PersistentVolume.Spec.Local.Path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
switch fileType {
|
||||
case mount.FileTypeDirectory:
|
||||
return spec.PersistentVolume.Spec.Local.Path, nil
|
||||
case mount.FileTypeBlockDev:
|
||||
return filepath.Join(plugin.generateBlockDeviceBaseGlobalPath(), spec.Name()), nil
|
||||
default:
|
||||
return "", fmt.Errorf("only directory and block device are supported")
|
||||
}
|
||||
}
|
||||
|
||||
var _ volume.DeviceMountableVolumePlugin = &localVolumePlugin{}
|
||||
|
||||
type deviceMounter struct {
|
||||
plugin *localVolumePlugin
|
||||
mounter *mount.SafeFormatAndMount
|
||||
}
|
||||
|
||||
var _ volume.DeviceMounter = &deviceMounter{}
|
||||
|
||||
func (plugin *localVolumePlugin) NewDeviceMounter() (volume.DeviceMounter, error) {
|
||||
return &deviceMounter{
|
||||
plugin: plugin,
|
||||
mounter: util.NewSafeFormatAndMountFromHost(plugin.GetPluginName(), plugin.host),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (dm *deviceMounter) mountLocalBlockDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
|
||||
klog.V(4).Infof("local: mounting device %s to %s", devicePath, deviceMountPath)
|
||||
notMnt, err := dm.mounter.IsLikelyNotMountPoint(deviceMountPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(deviceMountPath, 0750); err != nil {
|
||||
return err
|
||||
}
|
||||
notMnt = true
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !notMnt {
|
||||
return nil
|
||||
}
|
||||
fstype, err := getVolumeSourceFSType(spec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ro, err := getVolumeSourceReadOnly(spec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
options := []string{}
|
||||
if ro {
|
||||
options = append(options, "ro")
|
||||
}
|
||||
mountOptions := util.MountOptionFromSpec(spec, options...)
|
||||
err = dm.mounter.FormatAndMount(devicePath, deviceMountPath, fstype, mountOptions)
|
||||
if err != nil {
|
||||
os.Remove(deviceMountPath)
|
||||
return fmt.Errorf("local: failed to mount device %s at %s (fstype: %s), error %v", devicePath, deviceMountPath, fstype, err)
|
||||
}
|
||||
klog.V(3).Infof("local: successfully mount device %s at %s (fstype: %s)", devicePath, deviceMountPath, fstype)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dm *deviceMounter) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
|
||||
if spec.PersistentVolume.Spec.Local == nil || len(spec.PersistentVolume.Spec.Local.Path) == 0 {
|
||||
return fmt.Errorf("local volume source is nil or local path is not set")
|
||||
}
|
||||
fileType, err := dm.mounter.GetFileType(spec.PersistentVolume.Spec.Local.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch fileType {
|
||||
case mount.FileTypeBlockDev:
|
||||
// local volume plugin does not implement AttachableVolumePlugin interface, so set devicePath to Path in PV spec directly
|
||||
devicePath = spec.PersistentVolume.Spec.Local.Path
|
||||
return dm.mountLocalBlockDevice(spec, devicePath, deviceMountPath)
|
||||
case mount.FileTypeDirectory:
|
||||
// if the given local volume path is of already filesystem directory, return directly
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("only directory and block device are supported")
|
||||
}
|
||||
}
|
||||
|
||||
func getVolumeSourceFSType(spec *volume.Spec) (string, error) {
|
||||
if spec.PersistentVolume != nil &&
|
||||
spec.PersistentVolume.Spec.Local != nil {
|
||||
if spec.PersistentVolume.Spec.Local.FSType != nil {
|
||||
return *spec.PersistentVolume.Spec.Local.FSType, nil
|
||||
}
|
||||
// if the FSType is not set in local PV spec, setting it to default ("ext4")
|
||||
return defaultFSType, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("spec does not reference a Local volume type")
|
||||
}
|
||||
|
||||
func getVolumeSourceReadOnly(spec *volume.Spec) (bool, error) {
|
||||
if spec.PersistentVolume != nil &&
|
||||
spec.PersistentVolume.Spec.Local != nil {
|
||||
// local volumes used as a PersistentVolume gets the ReadOnly flag indirectly through
|
||||
// the persistent-claim volume used to mount the PV
|
||||
return spec.ReadOnly, nil
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("spec does not reference a Local volume type")
|
||||
}
|
||||
|
||||
func (dm *deviceMounter) GetDeviceMountPath(spec *volume.Spec) (string, error) {
|
||||
return dm.plugin.getGlobalLocalPath(spec)
|
||||
}
|
||||
|
||||
func (plugin *localVolumePlugin) NewDeviceUnmounter() (volume.DeviceUnmounter, error) {
|
||||
return &deviceMounter{
|
||||
plugin: plugin,
|
||||
mounter: util.NewSafeFormatAndMountFromHost(plugin.GetPluginName(), plugin.host),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (plugin *localVolumePlugin) GetDeviceMountRefs(deviceMountPath string) ([]string, error) {
|
||||
mounter := plugin.host.GetMounter(plugin.GetPluginName())
|
||||
return mounter.GetMountRefs(deviceMountPath)
|
||||
}
|
||||
|
||||
var _ volume.DeviceUnmounter = &deviceMounter{}
|
||||
|
||||
func (dm *deviceMounter) UnmountDevice(deviceMountPath string) error {
|
||||
// If the local PV is a block device,
|
||||
// The deviceMountPath is generated to the format like :/var/lib/kubelet/plugins/kubernetes.io/local-volume/mounts/localpv.spec.Name;
|
||||
// If it is a filesystem directory, then the deviceMountPath is set directly to pvSpec.Local.Path
|
||||
// We only need to unmount block device here, so we need to check if the deviceMountPath passed here
|
||||
// has base mount path: /var/lib/kubelet/plugins/kubernetes.io/local-volume/mounts
|
||||
basemountPath := dm.plugin.generateBlockDeviceBaseGlobalPath()
|
||||
if mount.PathWithinBase(deviceMountPath, basemountPath) {
|
||||
return util.UnmountPath(deviceMountPath, dm.mounter)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Local volumes represent a local directory on a node.
|
||||
// The directory at the globalPath will be bind-mounted to the pod's directory
|
||||
type localVolume struct {
|
||||
@ -225,7 +393,8 @@ func (l *localVolume) GetPath() string {
|
||||
|
||||
type localVolumeMounter struct {
|
||||
*localVolume
|
||||
readOnly bool
|
||||
readOnly bool
|
||||
mountOptions []string
|
||||
}
|
||||
|
||||
var _ volume.Mounter = &localVolumeMounter{}
|
||||
@ -265,9 +434,9 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
|
||||
}
|
||||
|
||||
notMnt, err := m.mounter.IsNotMountPoint(dir)
|
||||
glog.V(4).Infof("LocalVolume mount setup: PodDir(%s) VolDir(%s) Mounted(%t) Error(%v), ReadOnly(%t)", dir, m.globalPath, !notMnt, err, m.readOnly)
|
||||
klog.V(4).Infof("LocalVolume mount setup: PodDir(%s) VolDir(%s) Mounted(%t) Error(%v), ReadOnly(%t)", dir, m.globalPath, !notMnt, err, m.readOnly)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
glog.Errorf("cannot validate mount point: %s %v", dir, err)
|
||||
klog.Errorf("cannot validate mount point: %s %v", dir, err)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -277,7 +446,7 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
|
||||
refs, err := m.mounter.GetMountRefs(m.globalPath)
|
||||
if fsGroup != nil {
|
||||
if err != nil {
|
||||
glog.Errorf("cannot collect mounting information: %s %v", m.globalPath, err)
|
||||
klog.Errorf("cannot collect mounting information: %s %v", m.globalPath, err)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -299,7 +468,7 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
|
||||
if runtime.GOOS != "windows" {
|
||||
// skip below MkdirAll for windows since the "bind mount" logic is implemented differently in mount_wiondows.go
|
||||
if err := os.MkdirAll(dir, 0750); err != nil {
|
||||
glog.Errorf("mkdir failed on disk %s (%v)", dir, err)
|
||||
klog.Errorf("mkdir failed on disk %s (%v)", dir, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -308,30 +477,31 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
|
||||
if m.readOnly {
|
||||
options = append(options, "ro")
|
||||
}
|
||||
mountOptions := util.JoinMountOptions(options, m.mountOptions)
|
||||
|
||||
glog.V(4).Infof("attempting to mount %s", dir)
|
||||
klog.V(4).Infof("attempting to mount %s", dir)
|
||||
globalPath := util.MakeAbsolutePath(runtime.GOOS, m.globalPath)
|
||||
err = m.mounter.Mount(globalPath, dir, "", options)
|
||||
err = m.mounter.Mount(globalPath, dir, "", mountOptions)
|
||||
if err != nil {
|
||||
glog.Errorf("Mount of volume %s failed: %v", dir, err)
|
||||
klog.Errorf("Mount of volume %s failed: %v", dir, err)
|
||||
notMnt, mntErr := m.mounter.IsNotMountPoint(dir)
|
||||
if mntErr != nil {
|
||||
glog.Errorf("IsNotMountPoint check failed: %v", mntErr)
|
||||
klog.Errorf("IsNotMountPoint check failed: %v", mntErr)
|
||||
return err
|
||||
}
|
||||
if !notMnt {
|
||||
if mntErr = m.mounter.Unmount(dir); mntErr != nil {
|
||||
glog.Errorf("Failed to unmount: %v", mntErr)
|
||||
klog.Errorf("Failed to unmount: %v", mntErr)
|
||||
return err
|
||||
}
|
||||
notMnt, mntErr = m.mounter.IsNotMountPoint(dir)
|
||||
if mntErr != nil {
|
||||
glog.Errorf("IsNotMountPoint check failed: %v", mntErr)
|
||||
klog.Errorf("IsNotMountPoint check failed: %v", mntErr)
|
||||
return err
|
||||
}
|
||||
if !notMnt {
|
||||
// This is very odd, we don't expect it. We'll try again next sync loop.
|
||||
glog.Errorf("%s is still mounted, despite call to unmount(). Will try again next sync loop.", dir)
|
||||
klog.Errorf("%s is still mounted, despite call to unmount(). Will try again next sync loop.", dir)
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -371,7 +541,7 @@ func (u *localVolumeUnmounter) TearDown() error {
|
||||
|
||||
// TearDownAt unmounts the bind mount
|
||||
func (u *localVolumeUnmounter) TearDownAt(dir string) error {
|
||||
glog.V(4).Infof("Unmounting volume %q at path %q\n", u.volName, dir)
|
||||
klog.V(4).Infof("Unmounting volume %q at path %q\n", u.volName, dir)
|
||||
return util.UnmountMountPoint(dir, u.mounter, true) /* extensiveMountPointCheck = true */
|
||||
}
|
||||
|
||||
@ -386,7 +556,7 @@ var _ volume.BlockVolumeMapper = &localVolumeMapper{}
|
||||
// SetUpDevice provides physical device path for the local PV.
|
||||
func (m *localVolumeMapper) SetUpDevice() (string, error) {
|
||||
globalPath := util.MakeAbsolutePath(runtime.GOOS, m.globalPath)
|
||||
glog.V(4).Infof("SetupDevice returning path %s", globalPath)
|
||||
klog.V(4).Infof("SetupDevice returning path %s", globalPath)
|
||||
return globalPath, nil
|
||||
}
|
||||
|
||||
@ -402,8 +572,8 @@ type localVolumeUnmapper struct {
|
||||
var _ volume.BlockVolumeUnmapper = &localVolumeUnmapper{}
|
||||
|
||||
// TearDownDevice will undo SetUpDevice procedure. In local PV, all of this already handled by operation_generator.
|
||||
func (u *localVolumeUnmapper) TearDownDevice(mapPath, devicePath string) error {
|
||||
glog.V(4).Infof("local: TearDownDevice completed for: %s", mapPath)
|
||||
func (u *localVolumeUnmapper) TearDownDevice(mapPath, _ string) error {
|
||||
klog.V(4).Infof("local: TearDownDevice completed for: %s", mapPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
177
vendor/k8s.io/kubernetes/pkg/volume/local/local_test.go
generated
vendored
177
vendor/k8s.io/kubernetes/pkg/volume/local/local_test.go
generated
vendored
@ -31,16 +31,17 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utiltesting "k8s.io/client-go/util/testing"
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||
)
|
||||
|
||||
const (
|
||||
testPVName = "pvA"
|
||||
testMountPath = "pods/poduid/volumes/kubernetes.io~local-volume/pvA"
|
||||
testGlobalPath = "plugins/kubernetes.io~local-volume/volumeDevices/pvA"
|
||||
testPodPath = "pods/poduid/volumeDevices/kubernetes.io~local-volume"
|
||||
testNodeName = "fakeNodeName"
|
||||
testPVName = "pvA"
|
||||
testMountPath = "pods/poduid/volumes/kubernetes.io~local-volume/pvA"
|
||||
testGlobalPath = "plugins/kubernetes.io~local-volume/volumeDevices/pvA"
|
||||
testPodPath = "pods/poduid/volumeDevices/kubernetes.io~local-volume"
|
||||
testBlockFormattingToFSGlobalPath = "plugins/kubernetes.io/local-volume/mounts/pvA"
|
||||
)
|
||||
|
||||
func getPlugin(t *testing.T) (string, volume.VolumePlugin) {
|
||||
@ -102,7 +103,34 @@ func getPersistentPlugin(t *testing.T) (string, volume.PersistentVolumePlugin) {
|
||||
return tmpDir, plug
|
||||
}
|
||||
|
||||
func getTestVolume(readOnly bool, path string, isBlock bool) *volume.Spec {
|
||||
func getDeviceMountablePluginWithBlockPath(t *testing.T, isBlockDevice bool) (string, volume.DeviceMountableVolumePlugin) {
|
||||
tmpDir, err := utiltesting.MkTmpdir("localVolumeTest")
|
||||
if err != nil {
|
||||
t.Fatalf("can't make a temp dir: %v", err)
|
||||
}
|
||||
|
||||
plugMgr := volume.VolumePluginMgr{}
|
||||
var pathToFSType map[string]mount.FileType
|
||||
if isBlockDevice {
|
||||
pathToFSType = map[string]mount.FileType{
|
||||
tmpDir: mount.FileTypeBlockDev,
|
||||
}
|
||||
}
|
||||
|
||||
plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHostWithMounterFSType(tmpDir, nil, nil, pathToFSType))
|
||||
|
||||
plug, err := plugMgr.FindDeviceMountablePluginByName(localVolumePluginName)
|
||||
if err != nil {
|
||||
os.RemoveAll(tmpDir)
|
||||
t.Fatalf("Can't find the plugin by name")
|
||||
}
|
||||
if plug.GetPluginName() != localVolumePluginName {
|
||||
t.Errorf("Wrong name: %s", plug.GetPluginName())
|
||||
}
|
||||
return tmpDir, plug
|
||||
}
|
||||
|
||||
func getTestVolume(readOnly bool, path string, isBlock bool, mountOptions []string) *volume.Spec {
|
||||
pv := &v1.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: testPVName,
|
||||
@ -113,6 +141,7 @@ func getTestVolume(readOnly bool, path string, isBlock bool) *volume.Spec {
|
||||
Path: path,
|
||||
},
|
||||
},
|
||||
MountOptions: mountOptions,
|
||||
},
|
||||
}
|
||||
|
||||
@ -127,7 +156,7 @@ func TestCanSupport(t *testing.T) {
|
||||
tmpDir, plug := getPlugin(t)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
if !plug.CanSupport(getTestVolume(false, tmpDir, false)) {
|
||||
if !plug.CanSupport(getTestVolume(false, tmpDir, false, nil)) {
|
||||
t.Errorf("Expected true")
|
||||
}
|
||||
}
|
||||
@ -153,7 +182,7 @@ func TestGetVolumeName(t *testing.T) {
|
||||
tmpDir, plug := getPersistentPlugin(t)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
volName, err := plug.GetVolumeName(getTestVolume(false, tmpDir, false))
|
||||
volName, err := plug.GetVolumeName(getTestVolume(false, tmpDir, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Failed to get volume name: %v", err)
|
||||
}
|
||||
@ -167,7 +196,7 @@ func TestInvalidLocalPath(t *testing.T) {
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||
mounter, err := plug.NewMounter(getTestVolume(false, "/no/backsteps/allowed/..", false), pod, volume.VolumeOptions{})
|
||||
mounter, err := plug.NewMounter(getTestVolume(false, "/no/backsteps/allowed/..", false, nil), pod, volume.VolumeOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -179,12 +208,93 @@ func TestInvalidLocalPath(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlockDeviceGlobalPathAndMountDevice(t *testing.T) {
|
||||
// Block device global mount path testing
|
||||
tmpBlockDir, plug := getDeviceMountablePluginWithBlockPath(t, true)
|
||||
defer os.RemoveAll(tmpBlockDir)
|
||||
|
||||
dm, err := plug.NewDeviceMounter()
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new device mounter: %v", err)
|
||||
}
|
||||
|
||||
pvSpec := getTestVolume(false, tmpBlockDir, false, nil)
|
||||
|
||||
expectedGlobalPath := filepath.Join(tmpBlockDir, testBlockFormattingToFSGlobalPath)
|
||||
actualPath, err := dm.GetDeviceMountPath(pvSpec)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to get device mount path: %v", err)
|
||||
}
|
||||
if expectedGlobalPath != actualPath {
|
||||
t.Fatalf("Expected device mount global path:%s, got: %s", expectedGlobalPath, actualPath)
|
||||
}
|
||||
|
||||
fmt.Println("expected global path is:", expectedGlobalPath)
|
||||
|
||||
err = dm.MountDevice(pvSpec, tmpBlockDir, expectedGlobalPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := os.Stat(actualPath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
t.Errorf("DeviceMounter.MountDevice() failed, device mount path not created: %s", actualPath)
|
||||
} else {
|
||||
t.Errorf("DeviceMounter.MountDevice() failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
du, err := plug.NewDeviceUnmounter()
|
||||
if err != nil {
|
||||
t.Fatalf("Create device unmounter error: %v", err)
|
||||
}
|
||||
|
||||
err = du.UnmountDevice(actualPath)
|
||||
if err != nil {
|
||||
t.Fatalf("Unmount device error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFSGlobalPathAndMountDevice(t *testing.T) {
|
||||
// FS global path testing
|
||||
tmpFSDir, plug := getDeviceMountablePluginWithBlockPath(t, false)
|
||||
defer os.RemoveAll(tmpFSDir)
|
||||
|
||||
dm, err := plug.NewDeviceMounter()
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new device mounter: %v", err)
|
||||
}
|
||||
|
||||
pvSpec := getTestVolume(false, tmpFSDir, false, nil)
|
||||
|
||||
expectedGlobalPath := tmpFSDir
|
||||
actualPath, err := dm.GetDeviceMountPath(pvSpec)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to get device mount path: %v", err)
|
||||
}
|
||||
if expectedGlobalPath != actualPath {
|
||||
t.Fatalf("Expected device mount global path:%s, got: %s", expectedGlobalPath, actualPath)
|
||||
}
|
||||
|
||||
// Actually, we will do nothing if the local path is FS type
|
||||
err = dm.MountDevice(pvSpec, tmpFSDir, expectedGlobalPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := os.Stat(expectedGlobalPath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
t.Errorf("DeviceMounter.MountDevice() failed, device mount path not created: %s", expectedGlobalPath)
|
||||
} else {
|
||||
t.Errorf("DeviceMounter.MountDevice() failed: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMountUnmount(t *testing.T) {
|
||||
tmpDir, plug := getPlugin(t)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false), pod, volume.VolumeOptions{})
|
||||
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false, nil), pod, volume.VolumeOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||
}
|
||||
@ -237,7 +347,7 @@ func TestMapUnmap(t *testing.T) {
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||
volSpec := getTestVolume(false, tmpDir, true /*isBlock*/)
|
||||
volSpec := getTestVolume(false, tmpDir, true /*isBlock*/, nil)
|
||||
mapper, err := plug.NewBlockVolumeMapper(volSpec, pod, volume.VolumeOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||
@ -289,7 +399,7 @@ func TestMapUnmap(t *testing.T) {
|
||||
}
|
||||
|
||||
func testFSGroupMount(plug volume.VolumePlugin, pod *v1.Pod, tmpDir string, fsGroup int64) error {
|
||||
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false), pod, volume.VolumeOptions{})
|
||||
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false, nil), pod, volume.VolumeOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -336,6 +446,14 @@ func TestConstructVolumeSpec(t *testing.T) {
|
||||
t.Fatalf("PersistentVolume object nil")
|
||||
}
|
||||
|
||||
if spec.PersistentVolume.Spec.VolumeMode == nil {
|
||||
t.Fatalf("Volume mode has not been set.")
|
||||
}
|
||||
|
||||
if *spec.PersistentVolume.Spec.VolumeMode != v1.PersistentVolumeFilesystem {
|
||||
t.Errorf("Unexpected volume mode %q", *spec.PersistentVolume.Spec.VolumeMode)
|
||||
}
|
||||
|
||||
ls := pv.Spec.PersistentVolumeSource.Local
|
||||
if ls == nil {
|
||||
t.Fatalf("LocalVolumeSource object nil")
|
||||
@ -383,13 +501,40 @@ func TestConstructBlockVolumeSpec(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMountOptions(t *testing.T) {
|
||||
tmpDir, plug := getPlugin(t)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false, []string{"test-option"}), pod, volume.VolumeOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||
}
|
||||
if mounter == nil {
|
||||
t.Fatalf("Got a nil Mounter")
|
||||
}
|
||||
|
||||
// Wrap with FakeMounter.
|
||||
fakeMounter := &mount.FakeMounter{}
|
||||
mounter.(*localVolumeMounter).mounter = fakeMounter
|
||||
|
||||
if err := mounter.SetUp(nil); err != nil {
|
||||
t.Errorf("Expected success, got: %v", err)
|
||||
}
|
||||
mountOptions := fakeMounter.MountPoints[0].Opts
|
||||
expectedMountOptions := []string{"bind", "test-option"}
|
||||
if !reflect.DeepEqual(mountOptions, expectedMountOptions) {
|
||||
t.Errorf("Expected mount options to be %v got %v", expectedMountOptions, mountOptions)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPersistentClaimReadOnlyFlag(t *testing.T) {
|
||||
tmpDir, plug := getPlugin(t)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Read only == true
|
||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||
mounter, err := plug.NewMounter(getTestVolume(true, tmpDir, false), pod, volume.VolumeOptions{})
|
||||
mounter, err := plug.NewMounter(getTestVolume(true, tmpDir, false, nil), pod, volume.VolumeOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||
}
|
||||
@ -401,7 +546,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
|
||||
}
|
||||
|
||||
// Read only == false
|
||||
mounter, err = plug.NewMounter(getTestVolume(false, tmpDir, false), pod, volume.VolumeOptions{})
|
||||
mounter, err = plug.NewMounter(getTestVolume(false, tmpDir, false, nil), pod, volume.VolumeOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||
}
|
||||
@ -422,7 +567,7 @@ func TestUnsupportedPlugins(t *testing.T) {
|
||||
|
||||
plugMgr := volume.VolumePluginMgr{}
|
||||
plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(tmpDir, nil, nil))
|
||||
spec := getTestVolume(false, tmpDir, false)
|
||||
spec := getTestVolume(false, tmpDir, false, nil)
|
||||
|
||||
recyclePlug, err := plugMgr.FindRecyclablePluginBySpec(spec)
|
||||
if err == nil && recyclePlug != nil {
|
||||
@ -455,7 +600,7 @@ func TestFilterPodMounts(t *testing.T) {
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false), pod, volume.VolumeOptions{})
|
||||
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false, nil), pod, volume.VolumeOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user