Use typed errors for special casing volume progress

Use typed errors rather than operation status for
indicating operation progress
This commit is contained in:
Hemant Kumar 2019-11-14 18:55:46 -05:00
parent 0741f6fa29
commit 4b8e552a88
100 changed files with 418 additions and 578 deletions

View File

@ -53,6 +53,7 @@ pkg/volume/flexvolume
pkg/volume/flocker pkg/volume/flocker
pkg/volume/hostpath pkg/volume/hostpath
pkg/volume/iscsi pkg/volume/iscsi
pkg/volume/local
pkg/volume/portworx pkg/volume/portworx
pkg/volume/quobyte pkg/volume/quobyte
pkg/volume/rbd pkg/volume/rbd

View File

@ -12,7 +12,6 @@ go_library(
deps = [ deps = [
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/api/storage/v1:go_default_library", "//staging/src/k8s.io/api/storage/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

View File

@ -32,7 +32,6 @@ import (
"k8s.io/klog" "k8s.io/klog"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
const TestPluginName = "kubernetes.io/testPlugin" const TestPluginName = "kubernetes.io/testPlugin"
@ -435,15 +434,15 @@ func (attacher *testPluginAttacher) GetDeviceMountPath(spec *volume.Spec) (strin
return "", nil return "", nil
} }
func (attacher *testPluginAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) { func (attacher *testPluginAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
attacher.pluginLock.Lock() attacher.pluginLock.Lock()
defer attacher.pluginLock.Unlock() defer attacher.pluginLock.Unlock()
if spec == nil { if spec == nil {
*attacher.ErrorEncountered = true *attacher.ErrorEncountered = true
klog.Errorf("MountDevice called with nil volume spec") klog.Errorf("MountDevice called with nil volume spec")
return volumetypes.OperationFinished, fmt.Errorf("MountDevice called with nil volume spec") return fmt.Errorf("MountDevice called with nil volume spec")
} }
return volumetypes.OperationFinished, nil return nil
} }
// Detacher // Detacher

View File

@ -224,7 +224,6 @@ go_test(
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/hostutil:go_default_library",
"//pkg/volume/util/subpath:go_default_library", "//pkg/volume/util/subpath:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",

View File

@ -29,7 +29,6 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumetest "k8s.io/kubernetes/pkg/volume/testing" volumetest "k8s.io/kubernetes/pkg/volume/testing"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
func TestListVolumesForPod(t *testing.T) { func TestListVolumesForPod(t *testing.T) {
@ -531,8 +530,8 @@ func (f *stubVolume) CanMount() error {
return nil return nil
} }
func (f *stubVolume) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (f *stubVolume) SetUp(mounterArgs volume.MounterArgs) error {
return volumetypes.OperationFinished, nil return nil
} }
func (f *stubVolume) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { func (f *stubVolume) SetUpAt(dir string, mounterArgs volume.MounterArgs) error {

View File

@ -23,7 +23,6 @@ go_library(
"//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/hostutil:go_default_library",
"//pkg/volume/util/recyclerclient:go_default_library", "//pkg/volume/util/recyclerclient:go_default_library",
"//pkg/volume/util/subpath:go_default_library", "//pkg/volume/util/subpath:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/authentication/v1:go_default_library", "//staging/src/k8s.io/api/authentication/v1:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",

View File

@ -23,7 +23,6 @@ go_library(
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",

View File

@ -34,7 +34,6 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/legacy-cloud-providers/aws" "k8s.io/legacy-cloud-providers/aws"
) )
@ -207,7 +206,7 @@ func (attacher *awsElasticBlockStoreAttacher) GetDeviceMountPath(
} }
// FIXME: this method can be further pruned. // FIXME: this method can be further pruned.
func (attacher *awsElasticBlockStoreAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) { func (attacher *awsElasticBlockStoreAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
mounter := attacher.host.GetMounter(awsElasticBlockStorePluginName) mounter := attacher.host.GetMounter(awsElasticBlockStorePluginName)
notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath) notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath)
if err != nil { if err != nil {
@ -222,17 +221,17 @@ func (attacher *awsElasticBlockStoreAttacher) MountDevice(spec *volume.Spec, dev
dir = filepath.Dir(deviceMountPath) dir = filepath.Dir(deviceMountPath)
} }
if err := os.MkdirAll(dir, 0750); err != nil { if err := os.MkdirAll(dir, 0750); err != nil {
return volumetypes.OperationFinished, fmt.Errorf("making dir %s failed with %s", dir, err) return fmt.Errorf("making dir %s failed with %s", dir, err)
} }
notMnt = true notMnt = true
} else { } else {
return volumetypes.OperationFinished, err return err
} }
} }
volumeSource, readOnly, err := getVolumeSource(spec) volumeSource, readOnly, err := getVolumeSource(spec)
if err != nil { if err != nil {
return volumetypes.OperationFinished, err return err
} }
options := []string{} options := []string{}
@ -245,10 +244,10 @@ func (attacher *awsElasticBlockStoreAttacher) MountDevice(spec *volume.Spec, dev
err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions) err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions)
if err != nil { if err != nil {
os.Remove(deviceMountPath) os.Remove(deviceMountPath)
return volumetypes.OperationFinished, err return err
} }
} }
return volumetypes.OperationFinished, nil return nil
} }
type awsElasticBlockStoreDetacher struct { type awsElasticBlockStoreDetacher struct {

View File

@ -39,7 +39,6 @@ import (
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/legacy-cloud-providers/aws" "k8s.io/legacy-cloud-providers/aws"
utilstrings "k8s.io/utils/strings" utilstrings "k8s.io/utils/strings"
) )
@ -366,9 +365,8 @@ func (b *awsElasticBlockStoreMounter) CanMount() error {
} }
// SetUp attaches the disk and bind mounts to the volume path. // SetUp attaches the disk and bind mounts to the volume path.
func (b *awsElasticBlockStoreMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *awsElasticBlockStoreMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
// SetUpAt attaches the disk and bind mounts to the volume path. // SetUpAt attaches the disk and bind mounts to the volume path.

View File

@ -141,7 +141,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Got unexpected path: %s", path) t.Errorf("Got unexpected path: %s", path)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
if _, err := os.Stat(path); err != nil { if _, err := os.Stat(path); err != nil {
@ -372,7 +372,7 @@ func TestMountOptions(t *testing.T) {
t.Errorf("Got a nil Mounter") t.Errorf("Got a nil Mounter")
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
mountOptions := fakeMounter.MountPoints[0].Opts mountOptions := fakeMounter.MountPoints[0].Opts

View File

@ -27,7 +27,6 @@ go_library(
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",

View File

@ -37,7 +37,6 @@ import (
cloudprovider "k8s.io/cloud-provider" cloudprovider "k8s.io/cloud-provider"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/legacy-cloud-providers/azure" "k8s.io/legacy-cloud-providers/azure"
) )
@ -199,11 +198,7 @@ func (a *azureDiskAttacher) GetDeviceMountPath(spec *volume.Spec) (string, error
return makeGlobalPDPath(a.plugin.host, volumeSource.DataDiskURI, isManagedDisk) return makeGlobalPDPath(a.plugin.host, volumeSource.DataDiskURI, isManagedDisk)
} }
func (attacher *azureDiskAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) { func (attacher *azureDiskAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
return volumetypes.OperationFinished, attacher.mountDeviceInternal(spec, devicePath, deviceMountPath)
}
func (attacher *azureDiskAttacher) mountDeviceInternal(spec *volume.Spec, devicePath string, deviceMountPath string) error {
mounter := attacher.plugin.host.GetMounter(azureDataDiskPluginName) mounter := attacher.plugin.host.GetMounter(azureDataDiskPluginName)
notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath) notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath)

View File

@ -29,7 +29,6 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
type azureDiskMounter struct { type azureDiskMounter struct {
@ -66,9 +65,8 @@ func (m *azureDiskMounter) CanMount() error {
return nil return nil
} }
func (m *azureDiskMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (m *azureDiskMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := m.SetUpAt(m.GetPath(), mounterArgs) return m.SetUpAt(m.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
func (m *azureDiskMounter) GetPath() string { func (m *azureDiskMounter) GetPath() string {

View File

@ -13,7 +13,6 @@ go_library(
deps = [ deps = [
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",

View File

@ -36,7 +36,6 @@ import (
volumehelpers "k8s.io/cloud-provider/volume/helpers" volumehelpers "k8s.io/cloud-provider/volume/helpers"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volutil "k8s.io/kubernetes/pkg/volume/util" volutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/legacy-cloud-providers/azure" "k8s.io/legacy-cloud-providers/azure"
) )
@ -236,9 +235,8 @@ func (b *azureFileMounter) CanMount() error {
} }
// SetUp attaches the disk and bind mounts to the volume path. // SetUp attaches the disk and bind mounts to the volume path.
func (b *azureFileMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *azureFileMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
func (b *azureFileMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { func (b *azureFileMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error {

View File

@ -154,7 +154,7 @@ func testPlugin(t *testing.T, tmpDir string, volumeHost volume.VolumeHost) {
t.Errorf("Got unexpected path: %s", path) t.Errorf("Got unexpected path: %s", path)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
if _, err := os.Stat(path); err != nil { if _, err := os.Stat(path); err != nil {

View File

@ -16,7 +16,6 @@ go_library(
deps = [ deps = [
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1: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/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",

View File

@ -33,7 +33,6 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
// ProbeVolumePlugins is the primary entrypoint for volume plugins. // ProbeVolumePlugins is the primary entrypoint for volume plugins.
@ -220,9 +219,8 @@ func (cephfsVolume *cephfsMounter) CanMount() error {
} }
// SetUp attaches the disk and bind mounts to the volume path. // SetUp attaches the disk and bind mounts to the volume path.
func (cephfsVolume *cephfsMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (cephfsVolume *cephfsMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := cephfsVolume.SetUpAt(cephfsVolume.GetPath(), mounterArgs) return cephfsVolume.SetUpAt(cephfsVolume.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
// SetUpAt attaches the disk and bind mounts to the volume path. // SetUpAt attaches the disk and bind mounts to the volume path.

View File

@ -88,7 +88,7 @@ func TestPlugin(t *testing.T) {
if volumePath != volpath { if volumePath != volpath {
t.Errorf("Got unexpected path: %s", volumePath) t.Errorf("Got unexpected path: %s", volumePath)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
if _, err := os.Stat(volumePath); err != nil { if _, err := os.Stat(volumePath); err != nil {

View File

@ -20,7 +20,6 @@ go_library(
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",

View File

@ -34,7 +34,6 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
type cinderDiskAttacher struct { type cinderDiskAttacher struct {
@ -269,7 +268,7 @@ func (attacher *cinderDiskAttacher) GetDeviceMountPath(
} }
// FIXME: this method can be further pruned. // FIXME: this method can be further pruned.
func (attacher *cinderDiskAttacher) mountDeviceInternal(spec *volume.Spec, devicePath string, deviceMountPath string) error { func (attacher *cinderDiskAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
mounter := attacher.host.GetMounter(cinderVolumePluginName) mounter := attacher.host.GetMounter(cinderVolumePluginName)
notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath) notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath)
if err != nil { if err != nil {
@ -304,11 +303,6 @@ func (attacher *cinderDiskAttacher) mountDeviceInternal(spec *volume.Spec, devic
return nil return nil
} }
func (attacher *cinderDiskAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) {
err := attacher.mountDeviceInternal(spec, devicePath, deviceMountPath)
return volumetypes.OperationFinished, err
}
type cinderDiskDetacher struct { type cinderDiskDetacher struct {
mounter mount.Interface mounter mount.Interface
cinderProvider BlockStorageProvider cinderProvider BlockStorageProvider

View File

@ -39,7 +39,6 @@ import (
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/legacy-cloud-providers/openstack" "k8s.io/legacy-cloud-providers/openstack"
) )
@ -390,9 +389,8 @@ func (b *cinderVolumeMounter) CanMount() error {
return nil return nil
} }
func (b *cinderVolumeMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *cinderVolumeMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
// SetUp bind mounts to the volume path. // SetUp bind mounts to the volume path.

View File

@ -169,7 +169,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Got unexpected path: %s", path) t.Errorf("Got unexpected path: %s", path)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
if _, err := os.Stat(path); err != nil { if _, err := os.Stat(path); err != nil {

View File

@ -16,7 +16,6 @@ go_library(
deps = [ deps = [
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

View File

@ -29,7 +29,6 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
// ProbeVolumePlugins is the entry point for plugin detection in a package. // ProbeVolumePlugins is the entry point for plugin detection in a package.
@ -181,9 +180,8 @@ func (b *configMapVolumeMounter) CanMount() error {
return nil return nil
} }
func (b *configMapVolumeMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *configMapVolumeMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
func (b *configMapVolumeMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { func (b *configMapVolumeMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error {

View File

@ -368,7 +368,7 @@ func TestPlugin(t *testing.T) {
var mounterArgs volume.MounterArgs var mounterArgs volume.MounterArgs
group := int64(1001) group := int64(1001)
mounterArgs.FsGroup = &group mounterArgs.FsGroup = &group
_, err = mounter.SetUp(mounterArgs) err = mounter.SetUp(mounterArgs)
if err != nil { if err != nil {
t.Errorf("Failed to setup volume: %v", err) t.Errorf("Failed to setup volume: %v", err)
} }
@ -428,7 +428,7 @@ func TestPluginReboot(t *testing.T) {
var mounterArgs volume.MounterArgs var mounterArgs volume.MounterArgs
group := int64(1001) group := int64(1001)
mounterArgs.FsGroup = &group mounterArgs.FsGroup = &group
_, err = mounter.SetUp(mounterArgs) err = mounter.SetUp(mounterArgs)
if err != nil { if err != nil {
t.Errorf("Failed to setup volume: %v", err) t.Errorf("Failed to setup volume: %v", err)
} }
@ -492,7 +492,7 @@ func TestPluginOptional(t *testing.T) {
var mounterArgs volume.MounterArgs var mounterArgs volume.MounterArgs
group := int64(1001) group := int64(1001)
mounterArgs.FsGroup = &group mounterArgs.FsGroup = &group
_, err = mounter.SetUp(mounterArgs) err = mounter.SetUp(mounterArgs)
if err != nil { if err != nil {
t.Errorf("Failed to setup volume: %v", err) t.Errorf("Failed to setup volume: %v", err)
} }
@ -591,7 +591,7 @@ func TestPluginKeysOptional(t *testing.T) {
var mounterArgs volume.MounterArgs var mounterArgs volume.MounterArgs
group := int64(1001) group := int64(1001)
mounterArgs.FsGroup = &group mounterArgs.FsGroup = &group
_, err = mounter.SetUp(mounterArgs) err = mounter.SetUp(mounterArgs)
if err != nil { if err != nil {
t.Errorf("Failed to setup volume: %v", err) t.Errorf("Failed to setup volume: %v", err)
} }
@ -671,7 +671,7 @@ func TestInvalidConfigMapSetup(t *testing.T) {
var mounterArgs volume.MounterArgs var mounterArgs volume.MounterArgs
group := int64(1001) group := int64(1001)
mounterArgs.FsGroup = &group mounterArgs.FsGroup = &group
_, err = mounter.SetUp(mounterArgs) err = mounter.SetUp(mounterArgs)
if err == nil { if err == nil {
t.Errorf("Expected setup to fail") t.Errorf("Expected setup to fail")
} }

View File

@ -220,40 +220,38 @@ func (c *csiAttacher) GetDeviceMountPath(spec *volume.Spec) (string, error) {
return deviceMountPath, nil return deviceMountPath, nil
} }
func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) { func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
klog.V(4).Infof(log("attacher.MountDevice(%s, %s)", devicePath, deviceMountPath)) klog.V(4).Infof(log("attacher.MountDevice(%s, %s)", devicePath, deviceMountPath))
// lets default to operation as finished state
opExitStatus := volumetypes.OperationFinished
if deviceMountPath == "" { if deviceMountPath == "" {
return opExitStatus, errors.New(log("attacher.MountDevice failed, deviceMountPath is empty")) return errors.New(log("attacher.MountDevice failed, deviceMountPath is empty"))
} }
mounted, err := isDirMounted(c.plugin, deviceMountPath) mounted, err := isDirMounted(c.plugin, deviceMountPath)
if err != nil { if err != nil {
klog.Error(log("attacher.MountDevice failed while checking mount status for dir [%s]", deviceMountPath)) klog.Error(log("attacher.MountDevice failed while checking mount status for dir [%s]", deviceMountPath))
return opExitStatus, err return err
} }
if mounted { if mounted {
klog.V(4).Info(log("attacher.MountDevice skipping mount, dir already mounted [%s]", deviceMountPath)) klog.V(4).Info(log("attacher.MountDevice skipping mount, dir already mounted [%s]", deviceMountPath))
return opExitStatus, nil return nil
} }
// Setup // Setup
if spec == nil { if spec == nil {
return opExitStatus, errors.New(log("attacher.MountDevice failed, spec is nil")) return errors.New(log("attacher.MountDevice failed, spec is nil"))
} }
csiSource, err := getPVSourceFromSpec(spec) csiSource, err := getPVSourceFromSpec(spec)
if err != nil { if err != nil {
return opExitStatus, errors.New(log("attacher.MountDevice failed to get CSIPersistentVolumeSource: %v", err)) return errors.New(log("attacher.MountDevice failed to get CSIPersistentVolumeSource: %v", err))
} }
// lets check if node/unstage is supported // lets check if node/unstage is supported
if c.csiClient == nil { if c.csiClient == nil {
c.csiClient, err = newCsiDriverClient(csiDriverName(csiSource.Driver)) c.csiClient, err = newCsiDriverClient(csiDriverName(csiSource.Driver))
if err != nil { if err != nil {
return opExitStatus, errors.New(log("attacher.MountDevice failed to create newCsiDriverClient: %v", err)) return errors.New(log("attacher.MountDevice failed to create newCsiDriverClient: %v", err))
} }
} }
csi := c.csiClient csi := c.csiClient
@ -263,7 +261,7 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo
// Check whether "STAGE_UNSTAGE_VOLUME" is set // Check whether "STAGE_UNSTAGE_VOLUME" is set
stageUnstageSet, err := csi.NodeSupportsStageUnstage(ctx) stageUnstageSet, err := csi.NodeSupportsStageUnstage(ctx)
if err != nil { if err != nil {
return opExitStatus, err return err
} }
// Get secrets and publish context required for mountDevice // Get secrets and publish context required for mountDevice
@ -271,8 +269,7 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo
publishContext, err := c.plugin.getPublishContext(c.k8s, csiSource.VolumeHandle, csiSource.Driver, nodeName) publishContext, err := c.plugin.getPublishContext(c.k8s, csiSource.VolumeHandle, csiSource.Driver, nodeName)
if err != nil { if err != nil {
opExitStatus = volumetypes.OperationStateNoChange return volumetypes.NewTransientOperationFailure(err.Error())
return opExitStatus, err
} }
nodeStageSecrets := map[string]string{} nodeStageSecrets := map[string]string{}
@ -283,15 +280,14 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo
err = fmt.Errorf("fetching NodeStageSecretRef %s/%s failed: %v", err = fmt.Errorf("fetching NodeStageSecretRef %s/%s failed: %v",
csiSource.NodeStageSecretRef.Namespace, csiSource.NodeStageSecretRef.Name, err) csiSource.NodeStageSecretRef.Namespace, csiSource.NodeStageSecretRef.Name, err)
// if we failed to fetch secret then that could be a transient error // if we failed to fetch secret then that could be a transient error
opExitStatus = volumetypes.OperationStateNoChange return volumetypes.NewTransientOperationFailure(err.Error())
return opExitStatus, err
} }
} }
// Store volume metadata for UnmountDevice. Keep it around even if the // Store volume metadata for UnmountDevice. Keep it around even if the
// driver does not support NodeStage, UnmountDevice still needs it. // driver does not support NodeStage, UnmountDevice still needs it.
if err = os.MkdirAll(deviceMountPath, 0750); err != nil { if err = os.MkdirAll(deviceMountPath, 0750); err != nil {
return opExitStatus, errors.New(log("attacher.MountDevice failed to create dir %#v: %v", deviceMountPath, err)) return errors.New(log("attacher.MountDevice failed to create dir %#v: %v", deviceMountPath, err))
} }
klog.V(4).Info(log("created target path successfully [%s]", deviceMountPath)) klog.V(4).Info(log("created target path successfully [%s]", deviceMountPath))
dataDir := filepath.Dir(deviceMountPath) dataDir := filepath.Dir(deviceMountPath)
@ -304,12 +300,12 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo
if cleanErr := os.RemoveAll(dataDir); cleanErr != nil { if cleanErr := os.RemoveAll(dataDir); cleanErr != nil {
klog.Error(log("failed to remove dir after error [%s]: %v", dataDir, cleanErr)) klog.Error(log("failed to remove dir after error [%s]: %v", dataDir, cleanErr))
} }
return opExitStatus, err return err
} }
defer func() { defer func() {
// Only if there was an error and volume operation was considered // Only if there was an error and volume operation was considered
// finished, we should remove the directory. // finished, we should remove the directory.
if err != nil && opExitStatus == volumetypes.OperationFinished { if err != nil && volumetypes.IsOperationFinishedError(err) {
// clean up metadata // clean up metadata
klog.Errorf(log("attacher.MountDevice failed: %v", err)) klog.Errorf(log("attacher.MountDevice failed: %v", err))
if err := removeMountDir(c.plugin, deviceMountPath); err != nil { if err := removeMountDir(c.plugin, deviceMountPath); err != nil {
@ -321,7 +317,7 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo
if !stageUnstageSet { if !stageUnstageSet {
klog.Infof(log("attacher.MountDevice STAGE_UNSTAGE_VOLUME capability not set. Skipping MountDevice...")) klog.Infof(log("attacher.MountDevice STAGE_UNSTAGE_VOLUME capability not set. Skipping MountDevice..."))
// defer does *not* remove the metadata file and it's correct - UnmountDevice needs it there. // defer does *not* remove the metadata file and it's correct - UnmountDevice needs it there.
return opExitStatus, nil return nil
} }
//TODO (vladimirvivien) implement better AccessModes mapping between k8s and CSI //TODO (vladimirvivien) implement better AccessModes mapping between k8s and CSI
@ -347,14 +343,11 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo
mountOptions) mountOptions)
if err != nil { if err != nil {
if volumetypes.IsOperationTimeOutError(err) { return err
opExitStatus = volumetypes.OperationInProgress
}
return opExitStatus, err
} }
klog.V(4).Infof(log("attacher.MountDevice successfully requested NodeStageVolume [%s]", deviceMountPath)) klog.V(4).Infof(log("attacher.MountDevice successfully requested NodeStageVolume [%s]", deviceMountPath))
return opExitStatus, err return err
} }
var _ volume.Detacher = &csiAttacher{} var _ volume.Detacher = &csiAttacher{}

View File

@ -1056,6 +1056,9 @@ func TestAttacherGetDeviceMountPath(t *testing.T) {
func TestAttacherMountDevice(t *testing.T) { func TestAttacherMountDevice(t *testing.T) {
pvName := "test-pv" pvName := "test-pv"
nonFinalError := volumetypes.NewUncertainProgressError("")
transientError := volumetypes.NewTransientOperationFailure("")
testCases := []struct { testCases := []struct {
testName string testName string
volName string volName string
@ -1064,7 +1067,7 @@ func TestAttacherMountDevice(t *testing.T) {
stageUnstageSet bool stageUnstageSet bool
shouldFail bool shouldFail bool
createAttachment bool createAttachment bool
exitStatus volumetypes.OperationStatus exitError error
spec *volume.Spec spec *volume.Spec
}{ }{
{ {
@ -1075,7 +1078,6 @@ func TestAttacherMountDevice(t *testing.T) {
stageUnstageSet: true, stageUnstageSet: true,
createAttachment: true, createAttachment: true,
spec: volume.NewSpecFromPersistentVolume(makeTestPV(pvName, 10, testDriver, "test-vol1"), false), spec: volume.NewSpecFromPersistentVolume(makeTestPV(pvName, 10, testDriver, "test-vol1"), false),
exitStatus: volumetypes.OperationFinished,
}, },
{ {
testName: "normal PV with mount options", testName: "normal PV with mount options",
@ -1084,7 +1086,6 @@ func TestAttacherMountDevice(t *testing.T) {
deviceMountPath: "path2", deviceMountPath: "path2",
stageUnstageSet: true, stageUnstageSet: true,
createAttachment: true, createAttachment: true,
exitStatus: volumetypes.OperationFinished,
spec: volume.NewSpecFromPersistentVolume(makeTestPVWithMountOptions(pvName, 10, testDriver, "test-vol1", []string{"test-op"}), false), spec: volume.NewSpecFromPersistentVolume(makeTestPVWithMountOptions(pvName, 10, testDriver, "test-vol1", []string{"test-op"}), false),
}, },
{ {
@ -1095,7 +1096,7 @@ func TestAttacherMountDevice(t *testing.T) {
stageUnstageSet: true, stageUnstageSet: true,
createAttachment: false, createAttachment: false,
shouldFail: true, shouldFail: true,
exitStatus: volumetypes.OperationStateNoChange, exitError: transientError,
spec: volume.NewSpecFromPersistentVolume(makeTestPVWithMountOptions(pvName, 10, testDriver, "test-vol1", []string{"test-op"}), false), spec: volume.NewSpecFromPersistentVolume(makeTestPVWithMountOptions(pvName, 10, testDriver, "test-vol1", []string{"test-op"}), false),
}, },
{ {
@ -1106,7 +1107,6 @@ func TestAttacherMountDevice(t *testing.T) {
stageUnstageSet: true, stageUnstageSet: true,
shouldFail: true, shouldFail: true,
createAttachment: true, createAttachment: true,
exitStatus: volumetypes.OperationFinished,
spec: volume.NewSpecFromPersistentVolume(makeTestPV(pvName, 10, testDriver, ""), false), spec: volume.NewSpecFromPersistentVolume(makeTestPV(pvName, 10, testDriver, ""), false),
}, },
{ {
@ -1117,7 +1117,6 @@ func TestAttacherMountDevice(t *testing.T) {
stageUnstageSet: true, stageUnstageSet: true,
shouldFail: false, shouldFail: false,
createAttachment: true, createAttachment: true,
exitStatus: volumetypes.OperationFinished,
spec: volume.NewSpecFromPersistentVolume(makeTestPV(pvName, 10, testDriver, "test-vol1"), false), spec: volume.NewSpecFromPersistentVolume(makeTestPV(pvName, 10, testDriver, "test-vol1"), false),
}, },
{ {
@ -1128,7 +1127,6 @@ func TestAttacherMountDevice(t *testing.T) {
stageUnstageSet: true, stageUnstageSet: true,
shouldFail: true, shouldFail: true,
createAttachment: true, createAttachment: true,
exitStatus: volumetypes.OperationFinished,
spec: volume.NewSpecFromPersistentVolume(makeTestPV(pvName, 10, testDriver, "test-vol1"), false), spec: volume.NewSpecFromPersistentVolume(makeTestPV(pvName, 10, testDriver, "test-vol1"), false),
}, },
{ {
@ -1138,7 +1136,6 @@ func TestAttacherMountDevice(t *testing.T) {
deviceMountPath: "path2", deviceMountPath: "path2",
stageUnstageSet: false, stageUnstageSet: false,
createAttachment: true, createAttachment: true,
exitStatus: volumetypes.OperationFinished,
spec: volume.NewSpecFromPersistentVolume(makeTestPV(pvName, 10, testDriver, "test-vol1"), false), spec: volume.NewSpecFromPersistentVolume(makeTestPV(pvName, 10, testDriver, "test-vol1"), false),
}, },
{ {
@ -1148,7 +1145,6 @@ func TestAttacherMountDevice(t *testing.T) {
deviceMountPath: "path2", deviceMountPath: "path2",
shouldFail: true, shouldFail: true,
createAttachment: true, createAttachment: true,
exitStatus: volumetypes.OperationFinished,
spec: volume.NewSpecFromVolume(makeTestVol(pvName, testDriver)), spec: volume.NewSpecFromVolume(makeTestVol(pvName, testDriver)),
}, },
{ {
@ -1159,7 +1155,7 @@ func TestAttacherMountDevice(t *testing.T) {
stageUnstageSet: true, stageUnstageSet: true,
createAttachment: true, createAttachment: true,
spec: volume.NewSpecFromPersistentVolume(makeTestPV(pvName, 10, testDriver, fakecsi.NodeStageTimeOut_VolumeID), false), spec: volume.NewSpecFromPersistentVolume(makeTestPV(pvName, 10, testDriver, fakecsi.NodeStageTimeOut_VolumeID), false),
exitStatus: volumetypes.OperationInProgress, exitError: nonFinalError,
shouldFail: true, shouldFail: true,
}, },
} }
@ -1199,7 +1195,7 @@ func TestAttacherMountDevice(t *testing.T) {
} }
// Run // Run
exitStatus, err := csiAttacher.MountDevice(tc.spec, tc.devicePath, tc.deviceMountPath) err := csiAttacher.MountDevice(tc.spec, tc.devicePath, tc.deviceMountPath)
// Verify // Verify
if err != nil { if err != nil {
@ -1212,8 +1208,8 @@ func TestAttacherMountDevice(t *testing.T) {
t.Errorf("test should fail, but no error occurred") t.Errorf("test should fail, but no error occurred")
} }
if exitStatus != tc.exitStatus { if tc.exitError != nil && reflect.TypeOf(tc.exitError) != reflect.TypeOf(err) {
t.Fatalf("expected exitStatus: %v got: %v", tc.exitStatus, exitStatus) t.Fatalf("expected exitError: %v got: %v", tc.exitError, err)
} }
// Verify call goes through all the way // Verify call goes through all the way
@ -1348,7 +1344,7 @@ func TestAttacherMountDeviceWithInline(t *testing.T) {
}() }()
// Run // Run
_, err = csiAttacher.MountDevice(tc.spec, tc.devicePath, tc.deviceMountPath) err = csiAttacher.MountDevice(tc.spec, tc.devicePath, tc.deviceMountPath)
// Verify // Verify
if err != nil { if err != nil {

View File

@ -260,7 +260,7 @@ func (c *csiDriverClient) NodePublishVolume(
_, err = nodeClient.NodePublishVolume(ctx, req) _, err = nodeClient.NodePublishVolume(ctx, req)
if err != nil && !isFinalError(err) { if err != nil && !isFinalError(err) {
return volumetypes.NewOperationTimedOutError(err.Error()) return volumetypes.NewUncertainProgressError(err.Error())
} }
return nil return nil
} }
@ -382,7 +382,7 @@ func (c *csiDriverClient) NodeStageVolume(ctx context.Context,
_, err = nodeClient.NodeStageVolume(ctx, req) _, err = nodeClient.NodeStageVolume(ctx, req)
if err != nil && !isFinalError(err) { if err != nil && !isFinalError(err) {
return volumetypes.NewOperationTimedOutError(err.Error()) return volumetypes.NewUncertainProgressError(err.Error())
} }
return err return err
} }

View File

@ -157,11 +157,8 @@ func (c *fakeCsiDriverClient) NodePublishVolume(
} }
_, err := c.nodeClient.NodePublishVolume(ctx, req) _, err := c.nodeClient.NodePublishVolume(ctx, req)
if err != nil { if err != nil && !isFinalError(err) {
if isFinalError(err) { return volumetypes.NewUncertainProgressError(err.Error())
return err
}
return volumetypes.NewOperationTimedOutError(err.Error())
} }
return err return err
} }
@ -208,11 +205,8 @@ func (c *fakeCsiDriverClient) NodeStageVolume(ctx context.Context,
} }
_, err := c.nodeClient.NodeStageVolume(ctx, req) _, err := c.nodeClient.NodeStageVolume(ctx, req)
if err != nil { if err != nil && !isFinalError(err) {
if isFinalError(err) { return volumetypes.NewUncertainProgressError(err.Error())
return err
}
return volumetypes.NewOperationTimedOutError(err.Error())
} }
return err return err
} }

View File

@ -99,42 +99,34 @@ func (c *csiMountMgr) CanMount() error {
return nil return nil
} }
func (c *csiMountMgr) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (c *csiMountMgr) SetUp(mounterArgs volume.MounterArgs) error {
opExitStatus, err := c.setupInternal(c.GetPath(), mounterArgs) return c.SetUpAt(c.GetPath(), mounterArgs)
return opExitStatus, err
} }
func (c *csiMountMgr) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { func (c *csiMountMgr) SetUpAt(dir string, mounterArgs volume.MounterArgs) error {
_, err := c.setupInternal(dir, mounterArgs)
return err
}
func (c *csiMountMgr) setupInternal(dir string, mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) {
klog.V(4).Infof(log("Mounter.SetUpAt(%s)", dir)) klog.V(4).Infof(log("Mounter.SetUpAt(%s)", dir))
// default to finished operation status
opExitStatus := volumetypes.OperationFinished
mounted, err := isDirMounted(c.plugin, dir) mounted, err := isDirMounted(c.plugin, dir)
if err != nil { if err != nil {
return opExitStatus, errors.New(log("mounter.SetUpAt failed while checking mount status for dir [%s]: %v", dir, err)) return errors.New(log("mounter.SetUpAt failed while checking mount status for dir [%s]: %v", dir, err))
} }
if mounted { if mounted {
klog.V(4).Info(log("mounter.SetUpAt skipping mount, dir already mounted [%s]", dir)) klog.V(4).Info(log("mounter.SetUpAt skipping mount, dir already mounted [%s]", dir))
return opExitStatus, nil return nil
} }
csi, err := c.csiClientGetter.Get() csi, err := c.csiClientGetter.Get()
if err != nil { if err != nil {
opExitStatus = volumetypes.OperationStateNoChange return volumetypes.NewTransientOperationFailure(log("mounter.SetUpAt failed to get CSI client: %v", err))
return opExitStatus, errors.New(log("mounter.SetUpAt failed to get CSI client: %v", err))
} }
ctx, cancel := context.WithTimeout(context.Background(), csiTimeout) ctx, cancel := context.WithTimeout(context.Background(), csiTimeout)
defer cancel() defer cancel()
volSrc, pvSrc, err := getSourceFromSpec(c.spec) volSrc, pvSrc, err := getSourceFromSpec(c.spec)
if err != nil { if err != nil {
return opExitStatus, errors.New(log("mounter.SetupAt failed to get CSI persistent source: %v", err)) return errors.New(log("mounter.SetupAt failed to get CSI persistent source: %v", err))
} }
driverName := c.driverName driverName := c.driverName
@ -155,10 +147,10 @@ func (c *csiMountMgr) setupInternal(dir string, mounterArgs volume.MounterArgs)
switch { switch {
case volSrc != nil: case volSrc != nil:
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) { if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
return opExitStatus, fmt.Errorf("CSIInlineVolume feature required") return fmt.Errorf("CSIInlineVolume feature required")
} }
if c.volumeLifecycleMode != storage.VolumeLifecycleEphemeral { if c.volumeLifecycleMode != storage.VolumeLifecycleEphemeral {
return opExitStatus, fmt.Errorf("unexpected volume mode: %s", c.volumeLifecycleMode) return fmt.Errorf("unexpected volume mode: %s", c.volumeLifecycleMode)
} }
if volSrc.FSType != nil { if volSrc.FSType != nil {
fsType = *volSrc.FSType fsType = *volSrc.FSType
@ -173,7 +165,7 @@ func (c *csiMountMgr) setupInternal(dir string, mounterArgs volume.MounterArgs)
} }
case pvSrc != nil: case pvSrc != nil:
if c.volumeLifecycleMode != storage.VolumeLifecyclePersistent { if c.volumeLifecycleMode != storage.VolumeLifecyclePersistent {
return opExitStatus, fmt.Errorf("unexpected driver mode: %s", c.volumeLifecycleMode) return fmt.Errorf("unexpected driver mode: %s", c.volumeLifecycleMode)
} }
fsType = pvSrc.FSType fsType = pvSrc.FSType
@ -194,13 +186,13 @@ func (c *csiMountMgr) setupInternal(dir string, mounterArgs volume.MounterArgs)
// Check for STAGE_UNSTAGE_VOLUME set and populate deviceMountPath if so // Check for STAGE_UNSTAGE_VOLUME set and populate deviceMountPath if so
stageUnstageSet, err := csi.NodeSupportsStageUnstage(ctx) stageUnstageSet, err := csi.NodeSupportsStageUnstage(ctx)
if err != nil { if err != nil {
return opExitStatus, errors.New(log("mounter.SetUpAt failed to check for STAGE_UNSTAGE_VOLUME capability: %v", err)) return errors.New(log("mounter.SetUpAt failed to check for STAGE_UNSTAGE_VOLUME capability: %v", err))
} }
if stageUnstageSet { if stageUnstageSet {
deviceMountPath, err = makeDeviceMountPath(c.plugin, c.spec) deviceMountPath, err = makeDeviceMountPath(c.plugin, c.spec)
if err != nil { if err != nil {
return opExitStatus, errors.New(log("mounter.SetUpAt failed to make device mount path: %v", err)) return errors.New(log("mounter.SetUpAt failed to make device mount path: %v", err))
} }
} }
@ -210,19 +202,18 @@ func (c *csiMountMgr) setupInternal(dir string, mounterArgs volume.MounterArgs)
c.publishContext, err = c.plugin.getPublishContext(c.k8s, volumeHandle, string(driverName), nodeName) c.publishContext, err = c.plugin.getPublishContext(c.k8s, volumeHandle, string(driverName), nodeName)
if err != nil { if err != nil {
// we could have a transient error associated with fetching publish context // we could have a transient error associated with fetching publish context
opExitStatus = volumetypes.OperationStateNoChange return volumetypes.NewTransientOperationFailure(log("mounter.SetUpAt failed to fetch publishContext: %v", err))
return opExitStatus, err
} }
publishContext = c.publishContext publishContext = c.publishContext
} }
default: default:
return opExitStatus, fmt.Errorf("volume source not found in volume.Spec") return fmt.Errorf("volume source not found in volume.Spec")
} }
// create target_dir before call to NodePublish // create target_dir before call to NodePublish
if err := os.MkdirAll(dir, 0750); err != nil { if err := os.MkdirAll(dir, 0750); err != nil {
return opExitStatus, errors.New(log("mounter.SetUpAt failed to create dir %#v: %v", dir, err)) return errors.New(log("mounter.SetUpAt failed to create dir %#v: %v", dir, err))
} }
klog.V(4).Info(log("created target path successfully [%s]", dir)) klog.V(4).Info(log("created target path successfully [%s]", dir))
@ -230,9 +221,8 @@ func (c *csiMountMgr) setupInternal(dir string, mounterArgs volume.MounterArgs)
if secretRef != nil { if secretRef != nil {
nodePublishSecrets, err = getCredentialsFromSecret(c.k8s, secretRef) nodePublishSecrets, err = getCredentialsFromSecret(c.k8s, secretRef)
if err != nil { if err != nil {
opExitStatus = volumetypes.OperationStateNoChange return volumetypes.NewTransientOperationFailure(fmt.Sprintf("fetching NodePublishSecretRef %s/%s failed: %v",
return opExitStatus, fmt.Errorf("fetching NodePublishSecretRef %s/%s failed: %v", secretRef.Namespace, secretRef.Name, err))
secretRef.Namespace, secretRef.Name, err)
} }
} }
@ -240,8 +230,7 @@ func (c *csiMountMgr) setupInternal(dir string, mounterArgs volume.MounterArgs)
// Inject pod information into volume_attributes // Inject pod information into volume_attributes
podAttrs, err := c.podAttributes() podAttrs, err := c.podAttributes()
if err != nil { if err != nil {
opExitStatus = volumetypes.OperationStateNoChange return volumetypes.NewTransientOperationFailure(log("mounter.SetUpAt failed to assemble volume attributes: %v", err))
return opExitStatus, errors.New(log("mounter.SetUpAt failed to assemble volume attributes: %v", err))
} }
if podAttrs != nil { if podAttrs != nil {
if volAttribs == nil { if volAttribs == nil {
@ -268,16 +257,13 @@ func (c *csiMountMgr) setupInternal(dir string, mounterArgs volume.MounterArgs)
) )
if err != nil { if err != nil {
if volumetypes.IsOperationTimeOutError(err) {
opExitStatus = volumetypes.OperationInProgress
}
// If operation finished with error then we can remove the mount directory. // If operation finished with error then we can remove the mount directory.
if opExitStatus == volumetypes.OperationFinished { if volumetypes.IsOperationFinishedError(err) {
if removeMountDirErr := removeMountDir(c.plugin, dir); removeMountDirErr != nil { if removeMountDirErr := removeMountDir(c.plugin, dir); removeMountDirErr != nil {
klog.Error(log("mounter.SetupAt failed to remove mount dir after a NodePublish() error [%s]: %v", dir, removeMountDirErr)) klog.Error(log("mounter.SetupAt failed to remove mount dir after a NodePublish() error [%s]: %v", dir, removeMountDirErr))
} }
} }
return opExitStatus, errors.New(log("mounter.SetupAt failed: %v", err)) return err
} }
c.supportsSELinux, err = c.kubeVolHost.GetHostUtil().GetSELinuxSupport(dir) c.supportsSELinux, err = c.kubeVolHost.GetHostUtil().GetSELinuxSupport(dir)
@ -289,19 +275,17 @@ func (c *csiMountMgr) setupInternal(dir string, mounterArgs volume.MounterArgs)
// The following logic is derived from https://github.com/kubernetes/kubernetes/issues/66323 // The following logic is derived from https://github.com/kubernetes/kubernetes/issues/66323
// if fstype is "", then skip fsgroup (could be indication of non-block filesystem) // if fstype is "", then skip fsgroup (could be indication of non-block filesystem)
// if fstype is provided and pv.AccessMode == ReadWriteOnly, then apply fsgroup // if fstype is provided and pv.AccessMode == ReadWriteOnly, then apply fsgroup
err = c.applyFSGroup(fsType, mounterArgs.FsGroup) err = c.applyFSGroup(fsType, mounterArgs.FsGroup)
if err != nil { if err != nil {
// If we are here that means volume was mounted correctly and it must at least be unmounted // At this point mount operation is successful:
// before it can be used by someone else. // 1. Since volume can not be used by the pod because of invalid permissions, we must return error
opExitStatus = volumetypes.OperationInProgress // 2. Since mount is successful, we must record volume as mounted in uncertain state, so it can be
// attempt to rollback mount. // cleaned up.
fsGrpErr := fmt.Errorf("applyFSGroup failed for vol %s: %v", c.volumeID, err) return volumetypes.NewUncertainProgressError(fmt.Sprintf("applyFSGroup failed for vol %s: %v", c.volumeID, err))
return opExitStatus, fsGrpErr
} }
klog.V(4).Infof(log("mounter.SetUp successfully requested NodePublish [%s]", dir)) klog.V(4).Infof(log("mounter.SetUp successfully requested NodePublish [%s]", dir))
return opExitStatus, nil return nil
} }
func (c *csiMountMgr) podAttributes() (map[string]string, error) { func (c *csiMountMgr) podAttributes() (map[string]string, error) {

View File

@ -221,7 +221,7 @@ func MounterSetUpTests(t *testing.T, podInfoEnabled bool) {
var mounterArgs volume.MounterArgs var mounterArgs volume.MounterArgs
fsGroup := int64(2000) fsGroup := int64(2000)
mounterArgs.FsGroup = &fsGroup mounterArgs.FsGroup = &fsGroup
if _, err := csiMounter.SetUp(mounterArgs); err != nil { if err := csiMounter.SetUp(mounterArgs); err != nil {
t.Fatalf("mounter.Setup failed: %v", err) t.Fatalf("mounter.Setup failed: %v", err)
} }
@ -361,7 +361,7 @@ func TestMounterSetUpSimple(t *testing.T) {
} }
// Mounter.SetUp() // Mounter.SetUp()
if _, err := csiMounter.SetUp(volume.MounterArgs{}); err != nil { if err := csiMounter.SetUp(volume.MounterArgs{}); err != nil {
t.Fatalf("mounter.Setup failed: %v", err) t.Fatalf("mounter.Setup failed: %v", err)
} }
@ -402,13 +402,15 @@ func TestMounterSetupWithStatusTracking(t *testing.T) {
fakeClient := fakeclient.NewSimpleClientset() fakeClient := fakeclient.NewSimpleClientset()
plug, tmpDir := newTestPlugin(t, fakeClient) plug, tmpDir := newTestPlugin(t, fakeClient)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
nonFinalError := volumetypes.NewUncertainProgressError("non-final-error")
transientError := volumetypes.NewTransientOperationFailure("transient-error")
testCases := []struct { testCases := []struct {
name string name string
podUID types.UID podUID types.UID
spec func(string, []string) *volume.Spec spec func(string, []string) *volume.Spec
shouldFail bool shouldFail bool
exitStatus volumetypes.OperationStatus exitError error
createAttachment bool createAttachment bool
}{ }{
{ {
@ -420,7 +422,6 @@ func TestMounterSetupWithStatusTracking(t *testing.T) {
pvSrc.Spec.MountOptions = options pvSrc.Spec.MountOptions = options
return volume.NewSpecFromPersistentVolume(pvSrc, false) return volume.NewSpecFromPersistentVolume(pvSrc, false)
}, },
exitStatus: volumetypes.OperationFinished,
createAttachment: true, createAttachment: true,
}, },
{ {
@ -429,7 +430,7 @@ func TestMounterSetupWithStatusTracking(t *testing.T) {
spec: func(fsType string, options []string) *volume.Spec { spec: func(fsType string, options []string) *volume.Spec {
return volume.NewSpecFromPersistentVolume(makeTestPV("pv3", 20, testDriver, "vol4"), false) return volume.NewSpecFromPersistentVolume(makeTestPV("pv3", 20, testDriver, "vol4"), false)
}, },
exitStatus: volumetypes.OperationStateNoChange, exitError: transientError,
createAttachment: false, createAttachment: false,
shouldFail: true, shouldFail: true,
}, },
@ -440,7 +441,7 @@ func TestMounterSetupWithStatusTracking(t *testing.T) {
return volume.NewSpecFromPersistentVolume(makeTestPV("pv4", 20, testDriver, fakecsi.NodePublishTimeOut_VolumeID), false) return volume.NewSpecFromPersistentVolume(makeTestPV("pv4", 20, testDriver, fakecsi.NodePublishTimeOut_VolumeID), false)
}, },
createAttachment: true, createAttachment: true,
exitStatus: volumetypes.OperationInProgress, exitError: nonFinalError,
shouldFail: true, shouldFail: true,
}, },
{ {
@ -454,7 +455,7 @@ func TestMounterSetupWithStatusTracking(t *testing.T) {
} }
return volume.NewSpecFromPersistentVolume(pv, false) return volume.NewSpecFromPersistentVolume(pv, false)
}, },
exitStatus: volumetypes.OperationStateNoChange, exitError: transientError,
createAttachment: true, createAttachment: true,
shouldFail: true, shouldFail: true,
}, },
@ -487,11 +488,10 @@ func TestMounterSetupWithStatusTracking(t *testing.T) {
t.Fatalf("failed to setup VolumeAttachment: %v", err) t.Fatalf("failed to setup VolumeAttachment: %v", err)
} }
} }
err = csiMounter.SetUp(volume.MounterArgs{})
opExistStatus, err := csiMounter.SetUp(volume.MounterArgs{}) if tc.exitError != nil && reflect.TypeOf(tc.exitError) != reflect.TypeOf(err) {
t.Fatalf("expected exitError: %+v got: %+v", tc.exitError, err)
if opExistStatus != tc.exitStatus {
t.Fatalf("expected exitStatus: %v but got %v", tc.exitStatus, opExistStatus)
} }
if tc.shouldFail && err == nil { if tc.shouldFail && err == nil {
@ -604,7 +604,7 @@ func TestMounterSetUpWithInline(t *testing.T) {
} }
// Mounter.SetUp() // Mounter.SetUp()
if _, err := csiMounter.SetUp(volume.MounterArgs{}); err != nil { if err := csiMounter.SetUp(volume.MounterArgs{}); err != nil {
t.Fatalf("mounter.Setup failed: %v", err) t.Fatalf("mounter.Setup failed: %v", err)
} }
@ -757,7 +757,7 @@ func TestMounterSetUpWithFSGroup(t *testing.T) {
fsGroupPtr = &fsGroup fsGroupPtr = &fsGroup
} }
mounterArgs.FsGroup = fsGroupPtr mounterArgs.FsGroup = fsGroupPtr
if _, err := csiMounter.SetUp(mounterArgs); err != nil { if err := csiMounter.SetUp(mounterArgs); err != nil {
t.Fatalf("mounter.Setup failed: %v", err) t.Fatalf("mounter.Setup failed: %v", err)
} }

View File

@ -360,7 +360,7 @@ func TestCSI_VolumeAll(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("csiTest.VolumeAll deviceMounter.GetdeviceMountPath failed %s", err) t.Fatalf("csiTest.VolumeAll deviceMounter.GetdeviceMountPath failed %s", err)
} }
if _, err := csiDevMounter.MountDevice(volSpec, devicePath, devMountPath); err != nil { if err := csiDevMounter.MountDevice(volSpec, devicePath, devMountPath); err != nil {
t.Fatalf("csiTest.VolumeAll deviceMounter.MountDevice failed: %v", err) t.Fatalf("csiTest.VolumeAll deviceMounter.MountDevice failed: %v", err)
} }
t.Log("csiTest.VolumeAll device mounted at path:", devMountPath) t.Log("csiTest.VolumeAll device mounted at path:", devMountPath)
@ -417,7 +417,7 @@ func TestCSI_VolumeAll(t *testing.T) {
csiMounter.csiClient = csiClient csiMounter.csiClient = csiClient
var mounterArgs volume.MounterArgs var mounterArgs volume.MounterArgs
mounterArgs.FsGroup = fsGroup mounterArgs.FsGroup = fsGroup
if _, err := csiMounter.SetUp(mounterArgs); err != nil { if err := csiMounter.SetUp(mounterArgs); err != nil {
t.Fatalf("csiTest.VolumeAll mounter.Setup(fsGroup) failed: %s", err) t.Fatalf("csiTest.VolumeAll mounter.Setup(fsGroup) failed: %s", err)
} }
t.Log("csiTest.VolumeAll mounter.Setup(fsGroup) done OK") t.Log("csiTest.VolumeAll mounter.Setup(fsGroup) done OK")

View File

@ -15,7 +15,6 @@ go_library(
"//pkg/fieldpath:go_default_library", "//pkg/fieldpath:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",

View File

@ -28,7 +28,6 @@ import (
"k8s.io/kubernetes/pkg/fieldpath" "k8s.io/kubernetes/pkg/fieldpath"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
utilstrings "k8s.io/utils/strings" utilstrings "k8s.io/utils/strings"
) )
@ -171,9 +170,8 @@ func (b *downwardAPIVolumeMounter) CanMount() error {
// This function is not idempotent by design. We want the data to be refreshed periodically. // This function is not idempotent by design. We want the data to be refreshed periodically.
// The internal sync interval of kubelet will drive the refresh of data. // The internal sync interval of kubelet will drive the refresh of data.
// TODO: Add volume specific ticker and refresh loop // TODO: Add volume specific ticker and refresh loop
func (b *downwardAPIVolumeMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *downwardAPIVolumeMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
func (b *downwardAPIVolumeMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { func (b *downwardAPIVolumeMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error {

View File

@ -253,7 +253,7 @@ func newDownwardAPITest(t *testing.T, name string, volumeFiles, podLabels, podAn
volumePath := mounter.GetPath() volumePath := mounter.GetPath()
_, err = mounter.SetUp(volume.MounterArgs{}) err = mounter.SetUp(volume.MounterArgs{})
if err != nil { if err != nil {
t.Errorf("Failed to setup volume: %v", err) t.Errorf("Failed to setup volume: %v", err)
} }
@ -380,7 +380,7 @@ func (step reSetUp) run(test *downwardAPITest) {
} }
// now re-run Setup // now re-run Setup
if _, err = test.mounter.SetUp(volume.MounterArgs{}); err != nil { if err = test.mounter.SetUp(volume.MounterArgs{}); err != nil {
test.t.Errorf("Failed to re-setup volume: %v", err) test.t.Errorf("Failed to re-setup volume: %v", err)
} }

View File

@ -20,7 +20,6 @@ go_library(
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/fsquota:go_default_library", "//pkg/volume/util/fsquota:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

View File

@ -33,7 +33,6 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/fsquota" "k8s.io/kubernetes/pkg/volume/util/fsquota"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
// TODO: in the near future, this will be changed to be more restrictive // TODO: in the near future, this will be changed to be more restrictive
@ -193,9 +192,8 @@ func (ed *emptyDir) CanMount() error {
} }
// SetUp creates new directory. // SetUp creates new directory.
func (ed *emptyDir) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (ed *emptyDir) SetUp(mounterArgs volume.MounterArgs) error {
err := ed.SetUpAt(ed.GetPath(), mounterArgs) return ed.SetUpAt(ed.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
// SetUpAt creates new directory. // SetUpAt creates new directory.

View File

@ -164,7 +164,7 @@ func doTestPlugin(t *testing.T, config pluginTestConfig) {
t.Errorf("Got unexpected path: %s", volPath) t.Errorf("Got unexpected path: %s", volPath)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }

View File

@ -20,7 +20,6 @@ go_library(
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library",
"//staging/src/k8s.io/api/core/v1: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/apis/meta/v1:go_default_library",

View File

@ -32,7 +32,6 @@ import (
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
type fcAttacher struct { type fcAttacher struct {
@ -97,42 +96,39 @@ func (attacher *fcAttacher) GetDeviceMountPath(
return attacher.manager.MakeGlobalPDName(*mounter.fcDisk), nil return attacher.manager.MakeGlobalPDName(*mounter.fcDisk), nil
} }
func (attacher *fcAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) { func (attacher *fcAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
mountInternal := func() error { mounter := attacher.host.GetMounter(fcPluginName)
mounter := attacher.host.GetMounter(fcPluginName) notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath)
notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath) if err != nil {
if err != nil { if os.IsNotExist(err) {
if os.IsNotExist(err) { if err := os.MkdirAll(deviceMountPath, 0750); err != nil {
if err := os.MkdirAll(deviceMountPath, 0750); err != nil {
return err
}
notMnt = true
} else {
return err return err
} }
} notMnt = true
} else {
volumeSource, readOnly, err := getVolumeSource(spec)
if err != nil {
return err return err
} }
options := []string{}
if readOnly {
options = append(options, "ro")
}
if notMnt {
diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Exec: attacher.host.GetExec(fcPluginName)}
mountOptions := volumeutil.MountOptionFromSpec(spec, options...)
err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions)
if err != nil {
os.Remove(deviceMountPath)
return err
}
}
return nil
} }
return volumetypes.OperationFinished, mountInternal()
volumeSource, readOnly, err := getVolumeSource(spec)
if err != nil {
return err
}
options := []string{}
if readOnly {
options = append(options, "ro")
}
if notMnt {
diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Exec: attacher.host.GetExec(fcPluginName)}
mountOptions := volumeutil.MountOptionFromSpec(spec, options...)
err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions)
if err != nil {
os.Remove(deviceMountPath)
return err
}
}
return nil
} }
type fcDetacher struct { type fcDetacher struct {

View File

@ -35,7 +35,6 @@ import (
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler" "k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
) )
@ -370,9 +369,8 @@ func (b *fcDiskMounter) CanMount() error {
return nil return nil
} }
func (b *fcDiskMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *fcDiskMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
func (b *fcDiskMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { func (b *fcDiskMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error {

View File

@ -181,7 +181,7 @@ func doTestPlugin(t *testing.T, spec *volume.Spec) {
t.Errorf("Unexpected path, expected %q, got: %q", expectedPath, path) t.Errorf("Unexpected path, expected %q, got: %q", expectedPath, path)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
if _, err := os.Stat(path); err != nil { if _, err := os.Stat(path); err != nil {

View File

@ -32,7 +32,6 @@ go_library(
"//pkg/util/filesystem:go_default_library", "//pkg/util/filesystem:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",

View File

@ -23,7 +23,6 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/klog" "k8s.io/klog"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
type flexVolumeAttacher struct { type flexVolumeAttacher struct {
@ -71,34 +70,31 @@ func (a *flexVolumeAttacher) GetDeviceMountPath(spec *volume.Spec) (string, erro
} }
// MountDevice is part of the volume.Attacher interface // MountDevice is part of the volume.Attacher interface
func (a *flexVolumeAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) { func (a *flexVolumeAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
mountInternal := func() error { // Mount only once.
// Mount only once. alreadyMounted, err := prepareForMount(a.plugin.host.GetMounter(a.plugin.GetPluginName()), deviceMountPath)
alreadyMounted, err := prepareForMount(a.plugin.host.GetMounter(a.plugin.GetPluginName()), deviceMountPath) if err != nil {
if err != nil {
return err
}
if alreadyMounted {
return nil
}
call := a.plugin.NewDriverCall(mountDeviceCmd)
call.Append(deviceMountPath)
call.Append(devicePath)
call.AppendSpec(spec, a.plugin.host, nil)
_, err = call.Run()
if isCmdNotSupportedErr(err) {
// Devicepath is empty if the plugin does not support attach calls. Ignore mountDevice calls if the
// plugin does not implement attach interface.
if devicePath != "" {
return (*attacherDefaults)(a).MountDevice(spec, devicePath, deviceMountPath, a.plugin.host.GetMounter(a.plugin.GetPluginName()))
}
return nil
}
return err return err
} }
return volumetypes.OperationFinished, mountInternal() if alreadyMounted {
return nil
}
call := a.plugin.NewDriverCall(mountDeviceCmd)
call.Append(deviceMountPath)
call.Append(devicePath)
call.AppendSpec(spec, a.plugin.host, nil)
_, err = call.Run()
if isCmdNotSupportedErr(err) {
// Devicepath is empty if the plugin does not support attach calls. Ignore mountDevice calls if the
// plugin does not implement attach interface.
if devicePath != "" {
return (*attacherDefaults)(a).MountDevice(spec, devicePath, deviceMountPath, a.plugin.host.GetMounter(a.plugin.GetPluginName()))
}
return nil
}
return err
} }
func (a *flexVolumeAttacher) VolumesAreAttached(specs []*volume.Spec, nodeName types.NodeName) (map[*volume.Spec]bool, error) { func (a *flexVolumeAttacher) VolumesAreAttached(specs []*volume.Spec, nodeName types.NodeName) (map[*volume.Spec]bool, error) {

View File

@ -21,7 +21,6 @@ import (
"strconv" "strconv"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/utils/exec" "k8s.io/utils/exec"
) )
@ -40,9 +39,8 @@ var _ volume.Mounter = &flexVolumeMounter{}
// Mounter interface // Mounter interface
// SetUp creates new directory. // SetUp creates new directory.
func (f *flexVolumeMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (f *flexVolumeMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := f.SetUpAt(f.GetPath(), mounterArgs) return f.SetUpAt(f.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
// SetUpAt creates new directory. // SetUpAt creates new directory.

View File

@ -19,7 +19,6 @@ go_library(
"//pkg/util/env:go_default_library", "//pkg/util/env:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

View File

@ -31,7 +31,6 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/util/env" "k8s.io/kubernetes/pkg/util/env"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
// ProbeVolumePlugins is the primary entrypoint for volume plugins. // ProbeVolumePlugins is the primary entrypoint for volume plugins.
@ -232,9 +231,8 @@ func (b *flockerVolumeMounter) GetPath() string {
} }
// SetUp bind mounts the disk global mount to the volume path. // SetUp bind mounts the disk global mount to the volume path.
func (b *flockerVolumeMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *flockerVolumeMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
// newFlockerClient uses environment variables and pod attributes to return a // newFlockerClient uses environment variables and pod attributes to return a

View File

@ -20,7 +20,6 @@ go_library(
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",

View File

@ -38,7 +38,6 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/legacy-cloud-providers/gce" "k8s.io/legacy-cloud-providers/gce"
) )
@ -287,7 +286,7 @@ func (attacher *gcePersistentDiskAttacher) GetDeviceMountPath(
return makeGlobalPDName(attacher.host, volumeSource.PDName), nil return makeGlobalPDName(attacher.host, volumeSource.PDName), nil
} }
func (attacher *gcePersistentDiskAttacher) mountDeviceInternal(spec *volume.Spec, devicePath string, deviceMountPath string) error { func (attacher *gcePersistentDiskAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
// Only mount the PD globally once. // Only mount the PD globally once.
mounter := attacher.host.GetMounter(gcePersistentDiskPluginName) mounter := attacher.host.GetMounter(gcePersistentDiskPluginName)
notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath) notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath)
@ -329,11 +328,6 @@ func (attacher *gcePersistentDiskAttacher) mountDeviceInternal(spec *volume.Spec
return nil return nil
} }
func (attacher *gcePersistentDiskAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) {
err := attacher.mountDeviceInternal(spec, devicePath, deviceMountPath)
return volumetypes.OperationFinished, err
}
type gcePersistentDiskDetacher struct { type gcePersistentDiskDetacher struct {
host volume.VolumeHost host volume.VolumeHost
gceDisks gce.Disks gceDisks gce.Disks

View File

@ -40,7 +40,6 @@ import (
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
gcecloud "k8s.io/legacy-cloud-providers/gce" gcecloud "k8s.io/legacy-cloud-providers/gce"
) )
@ -369,9 +368,8 @@ func (b *gcePersistentDiskMounter) CanMount() error {
} }
// SetUp bind mounts the disk global mount to the volume path. // SetUp bind mounts the disk global mount to the volume path.
func (b *gcePersistentDiskMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *gcePersistentDiskMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
// SetUp bind mounts the disk global mount to the give volume path. // SetUp bind mounts the disk global mount to the give volume path.

View File

@ -144,7 +144,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Got unexpected path: %s", path) t.Errorf("Got unexpected path: %s", path)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
if _, err := os.Stat(path); err != nil { if _, err := os.Stat(path); err != nil {
@ -282,7 +282,7 @@ func TestMountOptions(t *testing.T) {
t.Errorf("Got a nil Mounter") t.Errorf("Got a nil Mounter")
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
mountOptions := fakeMounter.MountPoints[0].Opts mountOptions := fakeMounter.MountPoints[0].Opts

View File

@ -16,7 +16,6 @@ go_library(
deps = [ deps = [
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library",

View File

@ -26,7 +26,6 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/utils/exec" "k8s.io/utils/exec"
utilstrings "k8s.io/utils/strings" utilstrings "k8s.io/utils/strings"
) )
@ -176,9 +175,8 @@ func (b *gitRepoVolumeMounter) CanMount() error {
} }
// SetUp creates new directory and clones a git repo. // SetUp creates new directory and clones a git repo.
func (b *gitRepoVolumeMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *gitRepoVolumeMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
// SetUpAt creates new directory and clones a git repo. // SetUpAt creates new directory and clones a git repo.

View File

@ -19,7 +19,6 @@ go_library(
"//pkg/apis/core/v1/helper:go_default_library", "//pkg/apis/core/v1/helper:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",

View File

@ -47,7 +47,6 @@ import (
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volutil "k8s.io/kubernetes/pkg/volume/util" volutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
// ProbeVolumePlugins is the primary entrypoint for volume plugins. // ProbeVolumePlugins is the primary entrypoint for volume plugins.
@ -270,9 +269,8 @@ func (b *glusterfsMounter) CanMount() error {
} }
// SetUp attaches the disk and bind mounts to the volume path. // SetUp attaches the disk and bind mounts to the volume path.
func (b *glusterfsMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *glusterfsMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
func (b *glusterfsMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { func (b *glusterfsMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error {

View File

@ -119,7 +119,7 @@ func doTestPlugin(t *testing.T, spec *volume.Spec) {
if volumePath != expectedPath { if volumePath != expectedPath {
t.Errorf("Unexpected path, expected %q, got: %q", expectedPath, volumePath) t.Errorf("Unexpected path, expected %q, got: %q", expectedPath, volumePath)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
if _, err := os.Stat(volumePath); err != nil { if _, err := os.Stat(volumePath); err != nil {

View File

@ -18,7 +18,6 @@ go_library(
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/hostutil:go_default_library",
"//pkg/volume/util/recyclerclient:go_default_library", "//pkg/volume/util/recyclerclient:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//pkg/volume/validation:go_default_library", "//pkg/volume/validation:go_default_library",
"//staging/src/k8s.io/api/core/v1: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/apis/meta/v1:go_default_library",

View File

@ -31,7 +31,6 @@ import (
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/hostutil"
"k8s.io/kubernetes/pkg/volume/util/recyclerclient" "k8s.io/kubernetes/pkg/volume/util/recyclerclient"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/kubernetes/pkg/volume/validation" "k8s.io/kubernetes/pkg/volume/validation"
) )
@ -227,20 +226,16 @@ func (b *hostPathMounter) CanMount() error {
} }
// SetUp does nothing. // SetUp does nothing.
func (b *hostPathMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *hostPathMounter) SetUp(mounterArgs volume.MounterArgs) error {
internalSetup := func() error { err := validation.ValidatePathNoBacksteps(b.GetPath())
err := validation.ValidatePathNoBacksteps(b.GetPath()) if err != nil {
if err != nil { return fmt.Errorf("invalid HostPath `%s`: %v", b.GetPath(), err)
return fmt.Errorf("invalid HostPath `%s`: %v", b.GetPath(), err)
}
if *b.pathType == v1.HostPathUnset {
return nil
}
return checkType(b.GetPath(), b.pathType, b.hu)
} }
return volumetypes.OperationFinished, internalSetup()
if *b.pathType == v1.HostPathUnset {
return nil
}
return checkType(b.GetPath(), b.pathType, b.hu)
} }
// SetUpAt does not make sense for host paths - probably programmer error. // SetUpAt does not make sense for host paths - probably programmer error.

View File

@ -219,7 +219,7 @@ func TestInvalidHostPath(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
_, err = mounter.SetUp(volume.MounterArgs{}) err = mounter.SetUp(volume.MounterArgs{})
expectedMsg := "invalid HostPath `/no/backsteps/allowed/..`: must not contain '..'" expectedMsg := "invalid HostPath `/no/backsteps/allowed/..`: must not contain '..'"
if err.Error() != expectedMsg { if err.Error() != expectedMsg {
t.Fatalf("expected error `%s` but got `%s`", expectedMsg, err) t.Fatalf("expected error `%s` but got `%s`", expectedMsg, err)
@ -255,7 +255,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Got unexpected path: %s", path) t.Errorf("Got unexpected path: %s", path)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }

View File

@ -21,7 +21,6 @@ go_library(
"//pkg/kubelet/config:go_default_library", "//pkg/kubelet/config:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library",
"//staging/src/k8s.io/api/core/v1: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/apis/meta/v1:go_default_library",

View File

@ -31,8 +31,6 @@ import (
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/utils/keymutex"
) )
type iscsiAttacher struct { type iscsiAttacher struct {
@ -102,7 +100,7 @@ func (attacher *iscsiAttacher) GetDeviceMountPath(
return attacher.manager.MakeGlobalPDName(*mounter.iscsiDisk), nil return attacher.manager.MakeGlobalPDName(*mounter.iscsiDisk), nil
} }
func (attacher *iscsiAttacher) mountDeviceInternal(spec *volume.Spec, devicePath string, deviceMountPath string) error { func (attacher *iscsiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
mounter := attacher.host.GetMounter(iscsiPluginName) mounter := attacher.host.GetMounter(iscsiPluginName)
notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath) notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath)
if err != nil { if err != nil {
@ -136,11 +134,6 @@ func (attacher *iscsiAttacher) mountDeviceInternal(spec *volume.Spec, devicePath
return nil return nil
} }
func (attacher *iscsiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) {
err := attacher.mountDeviceInternal(spec, devicePath, deviceMountPath)
return volumetypes.OperationFinished, err
}
type iscsiDetacher struct { type iscsiDetacher struct {
host volume.VolumeHost host volume.VolumeHost
mounter mount.Interface mounter mount.Interface

View File

@ -34,7 +34,6 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
ioutil "k8s.io/kubernetes/pkg/volume/util" ioutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler" "k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
) )
@ -339,9 +338,8 @@ func (b *iscsiDiskMounter) CanMount() error {
return nil return nil
} }
func (b *iscsiDiskMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *iscsiDiskMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
func (b *iscsiDiskMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { func (b *iscsiDiskMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error {

View File

@ -177,7 +177,7 @@ func doTestPlugin(t *testing.T, spec *volume.Spec) {
t.Errorf("Unexpected path, expected %q, got: %q", expectedPath, path) t.Errorf("Unexpected path, expected %q, got: %q", expectedPath, path)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
if _, err := os.Stat(path); err != nil { if _, err := os.Stat(path); err != nil {

View File

@ -13,7 +13,6 @@ go_library(
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/hostutil:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//pkg/volume/validation:go_default_library", "//pkg/volume/validation:go_default_library",
"//staging/src/k8s.io/api/core/v1: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/apis/meta/v1:go_default_library",

View File

@ -33,7 +33,6 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/hostutil"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/kubernetes/pkg/volume/validation" "k8s.io/kubernetes/pkg/volume/validation"
"k8s.io/utils/keymutex" "k8s.io/utils/keymutex"
"k8s.io/utils/mount" "k8s.io/utils/mount"
@ -349,29 +348,26 @@ func (dm *deviceMounter) mountLocalBlockDevice(spec *volume.Spec, devicePath str
return nil return nil
} }
func (dm *deviceMounter) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) { func (dm *deviceMounter) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
mountInternal := func() error { if spec.PersistentVolume.Spec.Local == nil || len(spec.PersistentVolume.Spec.Local.Path) == 0 {
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")
return fmt.Errorf("local volume source is nil or local path is not set") }
} fileType, err := dm.hostUtil.GetFileType(spec.PersistentVolume.Spec.Local.Path)
fileType, err := dm.hostUtil.GetFileType(spec.PersistentVolume.Spec.Local.Path) if err != nil {
if err != nil { return err
return err }
}
switch fileType {
switch fileType { case hostutil.FileTypeBlockDev:
case hostutil.FileTypeBlockDev: // local volume plugin does not implement AttachableVolumePlugin interface, so set devicePath to Path in PV spec directly
// local volume plugin does not implement AttachableVolumePlugin interface, so set devicePath to Path in PV spec directly devicePath = spec.PersistentVolume.Spec.Local.Path
devicePath = spec.PersistentVolume.Spec.Local.Path return dm.mountLocalBlockDevice(spec, devicePath, deviceMountPath)
return dm.mountLocalBlockDevice(spec, devicePath, deviceMountPath) case hostutil.FileTypeDirectory:
case hostutil.FileTypeDirectory: // if the given local volume path is of already filesystem directory, return directly
// if the given local volume path is of already filesystem directory, return directly return nil
return nil default:
default: return fmt.Errorf("only directory and block device are supported")
return fmt.Errorf("only directory and block device are supported")
}
} }
return volumetypes.OperationFinished, mountInternal()
} }
func getVolumeSourceFSType(spec *volume.Spec) (string, error) { func getVolumeSourceFSType(spec *volume.Spec) (string, error) {
@ -473,9 +469,8 @@ func (m *localVolumeMounter) CanMount() error {
} }
// SetUp bind mounts the directory to the volume path // SetUp bind mounts the directory to the volume path
func (m *localVolumeMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (m *localVolumeMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := m.SetUpAt(m.GetPath(), mounterArgs) return m.SetUpAt(m.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
// SetUpAt bind mounts the directory to the volume path and sets up volume ownership // SetUpAt bind mounts the directory to the volume path and sets up volume ownership

View File

@ -201,7 +201,7 @@ func TestInvalidLocalPath(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
_, err = mounter.SetUp(volume.MounterArgs{}) err = mounter.SetUp(volume.MounterArgs{})
expectedMsg := "invalid path: /no/backsteps/allowed/.. must not contain '..'" expectedMsg := "invalid path: /no/backsteps/allowed/.. must not contain '..'"
if err.Error() != expectedMsg { if err.Error() != expectedMsg {
t.Fatalf("expected error `%s` but got `%s`", expectedMsg, err) t.Fatalf("expected error `%s` but got `%s`", expectedMsg, err)
@ -231,7 +231,7 @@ func TestBlockDeviceGlobalPathAndMountDevice(t *testing.T) {
fmt.Println("expected global path is:", expectedGlobalPath) fmt.Println("expected global path is:", expectedGlobalPath)
_, err = dm.MountDevice(pvSpec, tmpBlockDir, expectedGlobalPath) err = dm.MountDevice(pvSpec, tmpBlockDir, expectedGlobalPath)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -276,7 +276,7 @@ func TestFSGlobalPathAndMountDevice(t *testing.T) {
} }
// Actually, we will do nothing if the local path is FS type // Actually, we will do nothing if the local path is FS type
_, err = dm.MountDevice(pvSpec, tmpFSDir, expectedGlobalPath) err = dm.MountDevice(pvSpec, tmpFSDir, expectedGlobalPath)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -308,7 +308,7 @@ func TestMountUnmount(t *testing.T) {
t.Errorf("Got unexpected path: %s", path) t.Errorf("Got unexpected path: %s", path)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
@ -429,7 +429,7 @@ func testFSGroupMount(plug volume.VolumePlugin, pod *v1.Pod, tmpDir string, fsGr
var mounterArgs volume.MounterArgs var mounterArgs volume.MounterArgs
mounterArgs.FsGroup = &fsGroup mounterArgs.FsGroup = &fsGroup
if _, err := mounter.SetUp(mounterArgs); err != nil { if err := mounter.SetUp(mounterArgs); err != nil {
return err return err
} }
return nil return nil
@ -587,7 +587,7 @@ func TestMountOptions(t *testing.T) {
fakeMounter := mount.NewFakeMounter(nil) fakeMounter := mount.NewFakeMounter(nil)
mounter.(*localVolumeMounter).mounter = fakeMounter mounter.(*localVolumeMounter).mounter = fakeMounter
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
mountOptions := fakeMounter.MountPoints[0].Opts mountOptions := fakeMounter.MountPoints[0].Opts

View File

@ -17,7 +17,6 @@ go_library(
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/recyclerclient:go_default_library", "//pkg/volume/util/recyclerclient:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1: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/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",

View File

@ -31,7 +31,6 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/recyclerclient" "k8s.io/kubernetes/pkg/volume/util/recyclerclient"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
func getPath(uid types.UID, volName string, host volume.VolumeHost) string { func getPath(uid types.UID, volName string, host volume.VolumeHost) string {
@ -238,9 +237,8 @@ func (nfsMounter *nfsMounter) GetAttributes() volume.Attributes {
} }
// SetUp attaches the disk and bind mounts to the volume path. // SetUp attaches the disk and bind mounts to the volume path.
func (nfsMounter *nfsMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (nfsMounter *nfsMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := nfsMounter.SetUpAt(nfsMounter.GetPath(), mounterArgs) return nfsMounter.SetUpAt(nfsMounter.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
func (nfsMounter *nfsMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { func (nfsMounter *nfsMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error {

View File

@ -123,7 +123,7 @@ func doTestPlugin(t *testing.T, spec *volume.Spec) {
if volumePath != expectedPath { if volumePath != expectedPath {
t.Errorf("Unexpected path, expected %q, got: %q", expectedPath, volumePath) t.Errorf("Unexpected path, expected %q, got: %q", expectedPath, volumePath)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
if _, err := os.Stat(volumePath); err != nil { if _, err := os.Stat(volumePath); err != nil {

View File

@ -33,7 +33,6 @@ go_library(
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

View File

@ -31,7 +31,6 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
const ( const (
@ -296,9 +295,8 @@ func (b *portworxVolumeMounter) CanMount() error {
} }
// SetUp attaches the disk and bind mounts to the volume path. // SetUp attaches the disk and bind mounts to the volume path.
func (b *portworxVolumeMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *portworxVolumeMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
// SetUpAt attaches the disk and bind mounts to the volume path. // SetUpAt attaches the disk and bind mounts to the volume path.

View File

@ -164,7 +164,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Got unexpected path: %s", path) t.Errorf("Got unexpected path: %s", path)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
if _, err := os.Stat(path); err != nil { if _, err := os.Stat(path); err != nil {

View File

@ -41,7 +41,6 @@ go_library(
"//pkg/volume/downwardapi:go_default_library", "//pkg/volume/downwardapi:go_default_library",
"//pkg/volume/secret:go_default_library", "//pkg/volume/secret:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/authentication/v1:go_default_library", "//staging/src/k8s.io/api/authentication/v1:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",

View File

@ -33,7 +33,6 @@ import (
"k8s.io/kubernetes/pkg/volume/downwardapi" "k8s.io/kubernetes/pkg/volume/downwardapi"
"k8s.io/kubernetes/pkg/volume/secret" "k8s.io/kubernetes/pkg/volume/secret"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
utilstrings "k8s.io/utils/strings" utilstrings "k8s.io/utils/strings"
) )
@ -185,9 +184,8 @@ func (s *projectedVolumeMounter) CanMount() error {
return nil return nil
} }
func (s *projectedVolumeMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (s *projectedVolumeMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := s.SetUpAt(s.GetPath(), mounterArgs) return s.SetUpAt(s.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
func (s *projectedVolumeMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { func (s *projectedVolumeMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error {

View File

@ -887,7 +887,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Got unexpected path: %s", volumePath) t.Errorf("Got unexpected path: %s", volumePath)
} }
_, err = mounter.SetUp(volume.MounterArgs{}) err = mounter.SetUp(volume.MounterArgs{})
if err != nil { if err != nil {
t.Errorf("Failed to setup volume: %v", err) t.Errorf("Failed to setup volume: %v", err)
} }
@ -953,7 +953,7 @@ func TestInvalidPathProjected(t *testing.T) {
} }
var mounterArgs volume.MounterArgs var mounterArgs volume.MounterArgs
_, err = mounter.SetUp(mounterArgs) err = mounter.SetUp(mounterArgs)
if err == nil { if err == nil {
t.Errorf("Expected error while setting up secret") t.Errorf("Expected error while setting up secret")
} }
@ -1004,7 +1004,7 @@ func TestPluginReboot(t *testing.T) {
t.Errorf("Got unexpected path: %s", volumePath) t.Errorf("Got unexpected path: %s", volumePath)
} }
_, err = mounter.SetUp(volume.MounterArgs{}) err = mounter.SetUp(volume.MounterArgs{})
if err != nil { if err != nil {
t.Errorf("Failed to setup volume: %v", err) t.Errorf("Failed to setup volume: %v", err)
} }
@ -1056,7 +1056,7 @@ func TestPluginOptional(t *testing.T) {
t.Errorf("Got unexpected path: %s", volumePath) t.Errorf("Got unexpected path: %s", volumePath)
} }
_, err = mounter.SetUp(volume.MounterArgs{}) err = mounter.SetUp(volume.MounterArgs{})
if err != nil { if err != nil {
t.Errorf("Failed to setup volume: %v", err) t.Errorf("Failed to setup volume: %v", err)
} }
@ -1154,7 +1154,7 @@ func TestPluginOptionalKeys(t *testing.T) {
t.Errorf("Got unexpected path: %s", volumePath) t.Errorf("Got unexpected path: %s", volumePath)
} }
_, err = mounter.SetUp(volume.MounterArgs{}) err = mounter.SetUp(volume.MounterArgs{})
if err != nil { if err != nil {
t.Errorf("Failed to setup volume: %v", err) t.Errorf("Failed to setup volume: %v", err)
} }

View File

@ -17,7 +17,6 @@ go_library(
deps = [ deps = [
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

View File

@ -33,7 +33,6 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
// ProbeVolumePlugins is the primary entrypoint for volume plugins. // ProbeVolumePlugins is the primary entrypoint for volume plugins.
@ -235,10 +234,9 @@ func (mounter *quobyteMounter) CanMount() error {
} }
// SetUp attaches the disk and bind mounts to the volume path. // SetUp attaches the disk and bind mounts to the volume path.
func (mounter *quobyteMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (mounter *quobyteMounter) SetUp(mounterArgs volume.MounterArgs) error {
pluginDir := mounter.plugin.host.GetPluginDir(utilstrings.EscapeQualifiedName(quobytePluginName)) pluginDir := mounter.plugin.host.GetPluginDir(utilstrings.EscapeQualifiedName(quobytePluginName))
err := mounter.SetUpAt(pluginDir, mounterArgs) return mounter.SetUpAt(pluginDir, mounterArgs)
return volumetypes.OperationFinished, err
} }
func (mounter *quobyteMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { func (mounter *quobyteMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error {

View File

@ -102,7 +102,7 @@ func doTestPlugin(t *testing.T, spec *volume.Spec) {
if volumePath != fmt.Sprintf("%s/plugins/kubernetes.io~quobyte/root#root@vol", tmpDir) { if volumePath != fmt.Sprintf("%s/plugins/kubernetes.io~quobyte/root#root@vol", tmpDir) {
t.Errorf("Got unexpected path: %s expected: %s", volumePath, fmt.Sprintf("%s/plugins/kubernetes.io~quobyte/root#root@vol", tmpDir)) t.Errorf("Got unexpected path: %s expected: %s", volumePath, fmt.Sprintf("%s/plugins/kubernetes.io~quobyte/root#root@vol", tmpDir))
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
unmounter, err := plug.(*quobytePlugin).newUnmounterInternal("vol", types.UID("poduid"), mount.NewFakeMounter(nil)) unmounter, err := plug.(*quobytePlugin).newUnmounterInternal("vol", types.UID("poduid"), mount.NewFakeMounter(nil))

View File

@ -21,7 +21,6 @@ go_library(
"//pkg/util/node:go_default_library", "//pkg/util/node:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",

View File

@ -28,7 +28,6 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volutil "k8s.io/kubernetes/pkg/volume/util" volutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
// NewAttacher implements AttachableVolumePlugin.NewAttacher. // NewAttacher implements AttachableVolumePlugin.NewAttacher.
@ -144,7 +143,10 @@ func (attacher *rbdAttacher) GetDeviceMountPath(spec *volume.Spec) (string, erro
return makePDNameInternal(attacher.plugin.host, pool, img), nil return makePDNameInternal(attacher.plugin.host, pool, img), nil
} }
func (attacher *rbdAttacher) mountDeviceInternal(spec *volume.Spec, devicePath string, deviceMountPath string) error { // MountDevice implements Attacher.MountDevice. It is called by the kubelet to
// mount device at the given mount path.
// This method is idempotent, callers are responsible for retrying on failure.
func (attacher *rbdAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
klog.V(4).Infof("rbd: mouting device %s to %s", devicePath, deviceMountPath) klog.V(4).Infof("rbd: mouting device %s to %s", devicePath, deviceMountPath)
notMnt, err := attacher.mounter.IsLikelyNotMountPoint(deviceMountPath) notMnt, err := attacher.mounter.IsLikelyNotMountPoint(deviceMountPath)
if err != nil { if err != nil {
@ -182,14 +184,6 @@ func (attacher *rbdAttacher) mountDeviceInternal(spec *volume.Spec, devicePath s
return nil return nil
} }
// MountDevice implements Attacher.MountDevice. It is called by the kubelet to
// mount device at the given mount path.
// This method is idempotent, callers are responsible for retrying on failure.
func (attacher *rbdAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) {
err := attacher.mountDeviceInternal(spec, devicePath, deviceMountPath)
return volumetypes.OperationFinished, err
}
// rbdDetacher implements volume.Detacher interface. // rbdDetacher implements volume.Detacher interface.
type rbdDetacher struct { type rbdDetacher struct {
plugin *rbdPlugin plugin *rbdPlugin

View File

@ -40,7 +40,6 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volutil "k8s.io/kubernetes/pkg/volume/util" volutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler" "k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
) )
@ -837,9 +836,8 @@ func (b *rbdMounter) CanMount() error {
return nil return nil
} }
func (b *rbdMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *rbdMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
func (b *rbdMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { func (b *rbdMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error {

View File

@ -281,7 +281,7 @@ func doTestPlugin(t *testing.T, c *testcase) {
if deviceMountPath != c.expectedDeviceMountPath { if deviceMountPath != c.expectedDeviceMountPath {
t.Errorf("Unexpected mount path, expected %q, not: %q", c.expectedDeviceMountPath, deviceMountPath) t.Errorf("Unexpected mount path, expected %q, not: %q", c.expectedDeviceMountPath, deviceMountPath)
} }
_, err = attacher.MountDevice(c.spec, devicePath, deviceMountPath) err = attacher.MountDevice(c.spec, devicePath, deviceMountPath)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -307,7 +307,7 @@ func doTestPlugin(t *testing.T, c *testcase) {
t.Errorf("Unexpected path, expected %q, got: %q", c.expectedPodMountPath, path) t.Errorf("Unexpected path, expected %q, got: %q", c.expectedPodMountPath, path)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
if _, err := os.Stat(path); err != nil { if _, err := os.Stat(path); err != nil {

View File

@ -42,7 +42,6 @@ go_library(
deps = [ deps = [
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

View File

@ -35,7 +35,6 @@ import (
volumehelpers "k8s.io/cloud-provider/volume/helpers" volumehelpers "k8s.io/cloud-provider/volume/helpers"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
type sioVolume struct { type sioVolume struct {
@ -79,9 +78,8 @@ func (v *sioVolume) CanMount() error {
return nil return nil
} }
func (v *sioVolume) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (v *sioVolume) SetUp(mounterArgs volume.MounterArgs) error {
err := v.SetUpAt(v.GetPath(), mounterArgs) return v.SetUpAt(v.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
// SetUp bind mounts the disk global mount to the volume path. // SetUp bind mounts the disk global mount to the volume path.

View File

@ -190,7 +190,7 @@ func TestVolumeMounterUnmounter(t *testing.T) {
t.Errorf("Got unexpected path: %s", path) t.Errorf("Got unexpected path: %s", path)
} }
if _, err := sioMounter.SetUp(volume.MounterArgs{}); err != nil { if err := sioMounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
if _, err := os.Stat(path); err != nil { if _, err := os.Stat(path); err != nil {
@ -344,7 +344,7 @@ func TestVolumeProvisioner(t *testing.T) {
t.Fatalf("failed to create sio mgr: %v", err) t.Fatalf("failed to create sio mgr: %v", err)
} }
sioVol.sioMgr.client = sio sioVol.sioMgr.client = sio
if _, err := sioMounter.SetUp(volume.MounterArgs{}); err != nil { if err := sioMounter.SetUp(volume.MounterArgs{}); err != nil {
t.Fatalf("Expected success, got: %v", err) t.Fatalf("Expected success, got: %v", err)
} }

View File

@ -16,7 +16,6 @@ go_library(
deps = [ deps = [
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

View File

@ -29,7 +29,6 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
// ProbeVolumePlugins is the entry point for plugin detection in a package. // ProbeVolumePlugins is the entry point for plugin detection in a package.
@ -176,9 +175,8 @@ func (b *secretVolumeMounter) CanMount() error {
return nil return nil
} }
func (b *secretVolumeMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *secretVolumeMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
func (b *secretVolumeMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { func (b *secretVolumeMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error {

View File

@ -327,7 +327,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Got unexpected path: %s", volumePath) t.Errorf("Got unexpected path: %s", volumePath)
} }
_, err = mounter.SetUp(volume.MounterArgs{}) err = mounter.SetUp(volume.MounterArgs{})
if err != nil { if err != nil {
t.Errorf("Failed to setup volume: %v", err) t.Errorf("Failed to setup volume: %v", err)
} }
@ -402,7 +402,7 @@ func TestInvalidPathSecret(t *testing.T) {
} }
var mounterArgs volume.MounterArgs var mounterArgs volume.MounterArgs
_, err = mounter.SetUp(mounterArgs) err = mounter.SetUp(mounterArgs)
if err == nil { if err == nil {
t.Errorf("Expected error while setting up secret") t.Errorf("Expected error while setting up secret")
} }
@ -453,7 +453,7 @@ func TestPluginReboot(t *testing.T) {
t.Errorf("Got unexpected path: %s", volumePath) t.Errorf("Got unexpected path: %s", volumePath)
} }
_, err = mounter.SetUp(volume.MounterArgs{}) err = mounter.SetUp(volume.MounterArgs{})
if err != nil { if err != nil {
t.Errorf("Failed to setup volume: %v", err) t.Errorf("Failed to setup volume: %v", err)
} }
@ -505,7 +505,7 @@ func TestPluginOptional(t *testing.T) {
t.Errorf("Got unexpected path: %s", volumePath) t.Errorf("Got unexpected path: %s", volumePath)
} }
_, err = mounter.SetUp(volume.MounterArgs{}) err = mounter.SetUp(volume.MounterArgs{})
if err != nil { if err != nil {
t.Errorf("Failed to setup volume: %v", err) t.Errorf("Failed to setup volume: %v", err)
} }
@ -603,7 +603,7 @@ func TestPluginOptionalKeys(t *testing.T) {
t.Errorf("Got unexpected path: %s", volumePath) t.Errorf("Got unexpected path: %s", volumePath)
} }
_, err = mounter.SetUp(volume.MounterArgs{}) err = mounter.SetUp(volume.MounterArgs{})
if err != nil { if err != nil {
t.Errorf("Failed to setup volume: %v", err) t.Errorf("Failed to setup volume: %v", err)
} }

View File

@ -17,7 +17,6 @@ go_library(
deps = [ deps = [
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

View File

@ -36,7 +36,6 @@ import (
volumehelpers "k8s.io/cloud-provider/volume/helpers" volumehelpers "k8s.io/cloud-provider/volume/helpers"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
// ProbeVolumePlugins is the primary entrypoint for volume plugins. // ProbeVolumePlugins is the primary entrypoint for volume plugins.
@ -344,40 +343,37 @@ func (b *storageosMounter) CanMount() error {
} }
// SetUp attaches the disk and bind mounts to the volume path. // SetUp attaches the disk and bind mounts to the volume path.
func (b *storageosMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *storageosMounter) SetUp(mounterArgs volume.MounterArgs) error {
internalSetup := func() error { // Need a namespace to find the volume, try pod's namespace if not set.
// Need a namespace to find the volume, try pod's namespace if not set. if b.volNamespace == "" {
if b.volNamespace == "" { klog.V(2).Infof("Setting StorageOS volume namespace to pod namespace: %s", b.podNamespace)
klog.V(2).Infof("Setting StorageOS volume namespace to pod namespace: %s", b.podNamespace) b.volNamespace = b.podNamespace
b.volNamespace = b.podNamespace
}
targetPath := makeGlobalPDName(b.plugin.host, b.pvName, b.volNamespace, b.volName)
// Attach the device to the host.
if err := b.manager.AttachDevice(b, targetPath); err != nil {
klog.Errorf("Failed to attach device at %s: %s", targetPath, err.Error())
return err
}
// Attach the StorageOS volume as a block device
devicePath, err := b.manager.AttachVolume(b)
if err != nil {
klog.Errorf("Failed to attach StorageOS volume %s: %s", b.volName, err.Error())
return err
}
// Mount the loop device into the plugin's disk global mount dir.
err = b.manager.MountVolume(b, devicePath, targetPath)
if err != nil {
return err
}
klog.V(4).Infof("Successfully mounted StorageOS volume %s into global mount directory", b.volName)
// Bind mount the volume into the pod
return b.SetUpAt(b.GetPath(), mounterArgs)
} }
return volumetypes.OperationFinished, internalSetup()
targetPath := makeGlobalPDName(b.plugin.host, b.pvName, b.volNamespace, b.volName)
// Attach the device to the host.
if err := b.manager.AttachDevice(b, targetPath); err != nil {
klog.Errorf("Failed to attach device at %s: %s", targetPath, err.Error())
return err
}
// Attach the StorageOS volume as a block device
devicePath, err := b.manager.AttachVolume(b)
if err != nil {
klog.Errorf("Failed to attach StorageOS volume %s: %s", b.volName, err.Error())
return err
}
// Mount the loop device into the plugin's disk global mount dir.
err = b.manager.MountVolume(b, devicePath, targetPath)
if err != nil {
return err
}
klog.V(4).Infof("Successfully mounted StorageOS volume %s into global mount directory", b.volName)
// Bind mount the volume into the pod
return b.SetUpAt(b.GetPath(), mounterArgs)
} }
// SetUp bind mounts the disk global mount to the give volume path. // SetUp bind mounts the disk global mount to the give volume path.

View File

@ -210,7 +210,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Expected path: '%s' got: '%s'", expectedPath, volPath) t.Errorf("Expected path: '%s' got: '%s'", expectedPath, volPath)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }
if _, err := os.Stat(volPath); err != nil { if _, err := os.Stat(volPath); err != nil {

View File

@ -88,6 +88,14 @@ const (
SuccessAndTimeoutDeviceName = "success-and-timeout-device-name" SuccessAndTimeoutDeviceName = "success-and-timeout-device-name"
// SuccessAndFailOnMountDeviceName will cause first mount operation to succeed but subsequent attempts to fail // SuccessAndFailOnMountDeviceName will cause first mount operation to succeed but subsequent attempts to fail
SuccessAndFailOnMountDeviceName = "success-and-failed-mount-device-name" SuccessAndFailOnMountDeviceName = "success-and-failed-mount-device-name"
deviceNotMounted = "deviceNotMounted"
deviceMountUncertain = "deviceMountUncertain"
deviceMounted = "deviceMounted"
volumeNotMounted = "volumeNotMounted"
volumeMountUncertain = "volumeMountUncertain"
volumeMounted = "volumeMounted"
) )
// fakeVolumeHost is useful for testing volume plugins. // fakeVolumeHost is useful for testing volume plugins.
@ -406,8 +414,8 @@ func (plugin *FakeVolumePlugin) getFakeVolume(list *[]*FakeVolume) *FakeVolume {
UnmountDeviceHook: plugin.UnmountDeviceHook, UnmountDeviceHook: plugin.UnmountDeviceHook,
} }
volume.VolumesAttached = make(map[string]types.NodeName) volume.VolumesAttached = make(map[string]types.NodeName)
volume.DeviceMountState = make(map[string]volumetypes.OperationStatus) volume.DeviceMountState = make(map[string]string)
volume.VolumeMountState = make(map[string]volumetypes.OperationStatus) volume.VolumeMountState = make(map[string]string)
*list = append(*list, volume) *list = append(*list, volume)
return volume return volume
} }
@ -810,8 +818,8 @@ type FakeVolume struct {
Plugin *FakeVolumePlugin Plugin *FakeVolumePlugin
MetricsNil MetricsNil
VolumesAttached map[string]types.NodeName VolumesAttached map[string]types.NodeName
DeviceMountState map[string]volumetypes.OperationStatus DeviceMountState map[string]string
VolumeMountState map[string]volumetypes.OperationStatus VolumeMountState map[string]string
// Add callbacks as needed // Add callbacks as needed
WaitForAttachHook func(spec *Spec, devicePath string, pod *v1.Pod, spectimeout time.Duration) (string, error) WaitForAttachHook func(spec *Spec, devicePath string, pod *v1.Pod, spectimeout time.Duration) (string, error)
@ -859,34 +867,32 @@ func (fv *FakeVolume) CanMount() error {
return nil return nil
} }
func (fv *FakeVolume) SetUp(mounterArgs MounterArgs) (volumetypes.OperationStatus, error) { func (fv *FakeVolume) SetUp(mounterArgs MounterArgs) error {
fv.Lock() fv.Lock()
defer fv.Unlock() defer fv.Unlock()
err := fv.setupInternal(mounterArgs) err := fv.setupInternal(mounterArgs)
fv.SetUpCallCount++ fv.SetUpCallCount++
if volumetypes.IsOperationTimeOutError(err) { return err
return volumetypes.OperationInProgress, err
}
return volumetypes.OperationFinished, err
} }
func (fv *FakeVolume) setupInternal(mounterArgs MounterArgs) error { func (fv *FakeVolume) setupInternal(mounterArgs MounterArgs) error {
if fv.VolName == TimeoutOnSetupVolumeName { if fv.VolName == TimeoutOnSetupVolumeName {
fv.VolumeMountState[fv.VolName] = volumetypes.OperationInProgress fv.VolumeMountState[fv.VolName] = volumeMountUncertain
return volumetypes.NewOperationTimedOutError("time out on setup") return volumetypes.NewUncertainProgressError("time out on setup")
} }
if fv.VolName == FailOnSetupVolumeName { if fv.VolName == FailOnSetupVolumeName {
fv.VolumeMountState[fv.VolName] = volumeNotMounted
return fmt.Errorf("mounting volume failed") return fmt.Errorf("mounting volume failed")
} }
if fv.VolName == TimeoutAndFailOnSetupVolumeName { if fv.VolName == TimeoutAndFailOnSetupVolumeName {
_, ok := fv.VolumeMountState[fv.VolName] _, ok := fv.VolumeMountState[fv.VolName]
if !ok { if !ok {
fv.VolumeMountState[fv.VolName] = volumetypes.OperationInProgress fv.VolumeMountState[fv.VolName] = volumeMountUncertain
return volumetypes.NewOperationTimedOutError("time out on setup") return volumetypes.NewUncertainProgressError("time out on setup")
} }
fv.VolumeMountState[fv.VolName] = volumetypes.OperationFinished fv.VolumeMountState[fv.VolName] = volumeNotMounted
return fmt.Errorf("mounting volume failed") return fmt.Errorf("mounting volume failed")
} }
@ -894,7 +900,7 @@ func (fv *FakeVolume) setupInternal(mounterArgs MounterArgs) error {
if fv.VolName == SuccessAndFailOnSetupVolumeName { if fv.VolName == SuccessAndFailOnSetupVolumeName {
_, ok := fv.VolumeMountState[fv.VolName] _, ok := fv.VolumeMountState[fv.VolName]
if ok { if ok {
fv.VolumeMountState[fv.VolName] = volumetypes.OperationFinished fv.VolumeMountState[fv.VolName] = volumeNotMounted
return fmt.Errorf("mounting volume failed") return fmt.Errorf("mounting volume failed")
} }
} }
@ -902,13 +908,12 @@ func (fv *FakeVolume) setupInternal(mounterArgs MounterArgs) error {
if fv.VolName == SuccessAndTimeoutSetupVolumeName { if fv.VolName == SuccessAndTimeoutSetupVolumeName {
_, ok := fv.VolumeMountState[fv.VolName] _, ok := fv.VolumeMountState[fv.VolName]
if ok { if ok {
fv.VolumeMountState[fv.VolName] = volumetypes.OperationInProgress fv.VolumeMountState[fv.VolName] = volumeMountUncertain
return volumetypes.NewOperationTimedOutError("time out on setup") return volumetypes.NewUncertainProgressError("time out on setup")
} }
} }
fv.VolumeMountState[fv.VolName] = volumetypes.OperationFinished fv.VolumeMountState[fv.VolName] = volumeNotMounted
return fv.SetUpAt(fv.getPath(), mounterArgs) return fv.SetUpAt(fv.getPath(), mounterArgs)
} }
@ -1113,30 +1118,30 @@ func (fv *FakeVolume) mountDeviceInternal(spec *Spec, devicePath string, deviceM
fv.Lock() fv.Lock()
defer fv.Unlock() defer fv.Unlock()
if spec.Name() == TimeoutOnMountDeviceVolumeName { if spec.Name() == TimeoutOnMountDeviceVolumeName {
fv.DeviceMountState[spec.Name()] = volumetypes.OperationInProgress fv.DeviceMountState[spec.Name()] = deviceMountUncertain
return volumetypes.NewOperationTimedOutError("error mounting device") return volumetypes.NewUncertainProgressError("mount failed")
} }
if spec.Name() == FailMountDeviceVolumeName { if spec.Name() == FailMountDeviceVolumeName {
fv.DeviceMountState[spec.Name()] = volumetypes.OperationFinished fv.DeviceMountState[spec.Name()] = deviceNotMounted
return fmt.Errorf("error mounting disk: %s", devicePath) return fmt.Errorf("error mounting disk: %s", devicePath)
} }
if spec.Name() == TimeoutAndFailOnMountDeviceVolumeName { if spec.Name() == TimeoutAndFailOnMountDeviceVolumeName {
_, ok := fv.DeviceMountState[spec.Name()] _, ok := fv.DeviceMountState[spec.Name()]
if !ok { if !ok {
fv.DeviceMountState[spec.Name()] = volumetypes.OperationInProgress fv.DeviceMountState[spec.Name()] = deviceMountUncertain
return volumetypes.NewOperationTimedOutError("timed out mounting error") return volumetypes.NewUncertainProgressError("timed out mounting error")
} }
fv.DeviceMountState[spec.Name()] = volumetypes.OperationFinished fv.DeviceMountState[spec.Name()] = deviceNotMounted
return fmt.Errorf("error mounting disk: %s", devicePath) return fmt.Errorf("error mounting disk: %s", devicePath)
} }
if spec.Name() == SuccessAndTimeoutDeviceName { if spec.Name() == SuccessAndTimeoutDeviceName {
_, ok := fv.DeviceMountState[spec.Name()] _, ok := fv.DeviceMountState[spec.Name()]
if ok { if ok {
fv.DeviceMountState[spec.Name()] = volumetypes.OperationInProgress fv.DeviceMountState[spec.Name()] = deviceMountUncertain
return volumetypes.NewOperationTimedOutError("error mounting state") return volumetypes.NewUncertainProgressError("error mounting state")
} }
} }
@ -1146,17 +1151,13 @@ func (fv *FakeVolume) mountDeviceInternal(spec *Spec, devicePath string, deviceM
return fmt.Errorf("error mounting disk: %s", devicePath) return fmt.Errorf("error mounting disk: %s", devicePath)
} }
} }
fv.DeviceMountState[spec.Name()] = volumetypes.OperationFinished fv.DeviceMountState[spec.Name()] = deviceMounted
fv.MountDeviceCallCount++ fv.MountDeviceCallCount++
return nil return nil
} }
func (fv *FakeVolume) MountDevice(spec *Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) { func (fv *FakeVolume) MountDevice(spec *Spec, devicePath string, deviceMountPath string) error {
err := fv.mountDeviceInternal(spec, devicePath, deviceMountPath) return fv.mountDeviceInternal(spec, devicePath, deviceMountPath)
if volumetypes.IsOperationTimeOutError(err) {
return volumetypes.OperationInProgress, err
}
return volumetypes.OperationFinished, err
} }
func (fv *FakeVolume) GetMountDeviceCallCount() int { func (fv *FakeVolume) GetMountDeviceCallCount() int {

View File

@ -575,12 +575,12 @@ func (og *operationGenerator) GenerateMountVolumeFunc(
} }
// Mount device to global mount path // Mount device to global mount path
operationState, err := volumeDeviceMounter.MountDevice( err = volumeDeviceMounter.MountDevice(
volumeToMount.VolumeSpec, volumeToMount.VolumeSpec,
devicePath, devicePath,
deviceMountPath) deviceMountPath)
if err != nil { if err != nil {
og.markDeviceErrorState(volumeToMount, devicePath, deviceMountPath, operationState, actualStateOfWorld) og.markDeviceErrorState(volumeToMount, devicePath, deviceMountPath, err, actualStateOfWorld)
// On failure, return error. Caller will log and retry. // On failure, return error. Caller will log and retry.
return volumeToMount.GenerateError("MountVolume.MountDevice failed", err) return volumeToMount.GenerateError("MountVolume.MountDevice failed", err)
} }
@ -618,7 +618,7 @@ func (og *operationGenerator) GenerateMountVolumeFunc(
} }
// Execute mount // Execute mount
opExitStatus, mountErr := volumeMounter.SetUp(volume.MounterArgs{ mountErr := volumeMounter.SetUp(volume.MounterArgs{
FsGroup: fsGroup, FsGroup: fsGroup,
DesiredSize: volumeToMount.DesiredSizeLimit, DesiredSize: volumeToMount.DesiredSizeLimit,
}) })
@ -630,11 +630,11 @@ func (og *operationGenerator) GenerateMountVolumeFunc(
Mounter: volumeMounter, Mounter: volumeMounter,
OuterVolumeSpecName: volumeToMount.OuterVolumeSpecName, OuterVolumeSpecName: volumeToMount.OuterVolumeSpecName,
VolumeGidVolume: volumeToMount.VolumeGidValue, VolumeGidVolume: volumeToMount.VolumeGidValue,
VolumeSpec: originalSpec, VolumeSpec: volumeToMount.VolumeSpec,
VolumeMountState: VolumeMounted, VolumeMountState: VolumeMounted,
} }
if mountErr != nil { if mountErr != nil {
og.markVolumeErrorState(volumeToMount, markOpts, opExitStatus, actualStateOfWorld) og.markVolumeErrorState(volumeToMount, markOpts, mountErr, actualStateOfWorld)
// On failure, return error. Caller will log and retry. // On failure, return error. Caller will log and retry.
return volumeToMount.GenerateError("MountVolume.SetUp failed", mountErr) return volumeToMount.GenerateError("MountVolume.SetUp failed", mountErr)
} }
@ -660,17 +660,6 @@ func (og *operationGenerator) GenerateMountVolumeFunc(
} }
} }
// Update actual state of world
markOpts := MarkVolumeMountedOpts{
PodName: volumeToMount.PodName,
PodUID: volumeToMount.Pod.UID,
VolumeName: volumeToMount.VolumeName,
Mounter: volumeMounter,
OuterVolumeSpecName: volumeToMount.OuterVolumeSpecName,
VolumeGidVolume: volumeToMount.VolumeGidValue,
VolumeSpec: volumeToMount.VolumeSpec,
VolumeMountState: VolumeMounted,
}
markVolMountedErr := actualStateOfWorld.MarkVolumeAsMounted(markOpts) markVolMountedErr := actualStateOfWorld.MarkVolumeAsMounted(markOpts)
if markVolMountedErr != nil { if markVolMountedErr != nil {
// On failure, return error. Caller will log and retry. // On failure, return error. Caller will log and retry.
@ -694,45 +683,47 @@ func (og *operationGenerator) GenerateMountVolumeFunc(
} }
} }
func (og *operationGenerator) markDeviceErrorState(volumeToMount VolumeToMount, devicePath, deviceMountPath string, operationState volumetypes.OperationStatus, actualStateOfWorld ActualStateOfWorldMounterUpdater) { func (og *operationGenerator) markDeviceErrorState(volumeToMount VolumeToMount, devicePath, deviceMountPath string, mountError error, actualStateOfWorld ActualStateOfWorldMounterUpdater) {
switch operationState { if volumetypes.IsOperationFinishedError(mountError) &&
case volumetypes.OperationInProgress: actualStateOfWorld.GetDeviceMountState(volumeToMount.VolumeName) == DeviceMountUncertain {
// Only devices which were uncertain can be marked as unmounted
markDeviceUnmountError := actualStateOfWorld.MarkDeviceAsUnmounted(volumeToMount.VolumeName)
if markDeviceUnmountError != nil {
klog.Errorf(volumeToMount.GenerateErrorDetailed("MountDevice.MarkDeviceAsUnmounted failed", markDeviceUnmountError).Error())
}
return
}
if volumetypes.IsUncertainProgressError(mountError) &&
actualStateOfWorld.GetDeviceMountState(volumeToMount.VolumeName) == DeviceNotMounted {
// only devices which are not mounted can be marked as uncertain. We do not want to mark a device // only devices which are not mounted can be marked as uncertain. We do not want to mark a device
// which was previously marked as mounted here as uncertain. // which was previously marked as mounted here as uncertain.
if actualStateOfWorld.GetDeviceMountState(volumeToMount.VolumeName) == DeviceNotMounted { markDeviceUncertainError := actualStateOfWorld.MarkDeviceAsUncertain(volumeToMount.VolumeName, devicePath, deviceMountPath)
markDeviceUncertainError := actualStateOfWorld.MarkDeviceAsUncertain(volumeToMount.VolumeName, devicePath, deviceMountPath) if markDeviceUncertainError != nil {
if markDeviceUncertainError != nil { klog.Errorf(volumeToMount.GenerateErrorDetailed("MountDevice.MarkDeviceAsUncertain failed", markDeviceUncertainError).Error())
klog.Errorf(volumeToMount.GenerateErrorDetailed("MountDevice.MarkDeviceAsUncertain failed", markDeviceUncertainError).Error())
}
}
case volumetypes.OperationFinished:
// Similarly only devices which were uncertain can be marked as unmounted
if actualStateOfWorld.GetDeviceMountState(volumeToMount.VolumeName) == DeviceMountUncertain {
markDeviceUnmountError := actualStateOfWorld.MarkDeviceAsUnmounted(volumeToMount.VolumeName)
if markDeviceUnmountError != nil {
klog.Errorf(volumeToMount.GenerateErrorDetailed("MountDevice.MarkDeviceAsUnmounted failed", markDeviceUnmountError).Error())
}
} }
} }
} }
func (og *operationGenerator) markVolumeErrorState(volumeToMount VolumeToMount, markOpts MarkVolumeOpts, operationState volumetypes.OperationStatus, actualStateOfWorld ActualStateOfWorldMounterUpdater) { func (og *operationGenerator) markVolumeErrorState(volumeToMount VolumeToMount, markOpts MarkVolumeOpts, mountError error, actualStateOfWorld ActualStateOfWorldMounterUpdater) {
switch operationState { if volumetypes.IsOperationFinishedError(mountError) &&
case volumetypes.OperationInProgress: actualStateOfWorld.GetVolumeMountState(volumeToMount.VolumeName, markOpts.PodName) == VolumeMountUncertain {
if actualStateOfWorld.GetVolumeMountState(volumeToMount.VolumeName, markOpts.PodName) == VolumeNotMounted { t := actualStateOfWorld.MarkVolumeAsUnmounted(volumeToMount.PodName, volumeToMount.VolumeName)
t := actualStateOfWorld.MarkVolumeMountAsUncertain(markOpts) if t != nil {
if t != nil { klog.Errorf(volumeToMount.GenerateErrorDetailed("MountVolume.MarkVolumeAsUnmounted failed", t).Error())
klog.Errorf(volumeToMount.GenerateErrorDetailed("MountVolume.MarkVolumeMountAsUncertain failed", t).Error())
}
} }
case volumetypes.OperationFinished: return
if actualStateOfWorld.GetVolumeMountState(volumeToMount.VolumeName, markOpts.PodName) == VolumeMountUncertain { }
t := actualStateOfWorld.MarkVolumeAsUnmounted(volumeToMount.PodName, volumeToMount.VolumeName)
if t != nil { if volumetypes.IsUncertainProgressError(mountError) &&
klog.Errorf(volumeToMount.GenerateErrorDetailed("MountVolume.MarkVolumeAsUnmounted failed", t).Error()) actualStateOfWorld.GetVolumeMountState(volumeToMount.VolumeName, markOpts.PodName) == VolumeNotMounted {
} t := actualStateOfWorld.MarkVolumeMountAsUncertain(markOpts)
if t != nil {
klog.Errorf(volumeToMount.GenerateErrorDetailed("MountVolume.MarkVolumeMountAsUncertain failed", t).Error())
} }
} }
} }
func (og *operationGenerator) GenerateUnmountVolumeFunc( func (og *operationGenerator) GenerateUnmountVolumeFunc(

View File

@ -51,44 +51,52 @@ func (o *GeneratedOperations) Run() (eventErr, detailedErr error) {
return o.OperationFunc() return o.OperationFunc()
} }
// OperationStatus is used to store status of a volume operation // TransientOperationFailure indicates operation failed with a transient error
type OperationStatus string // and may fix itself when retried.
type TransientOperationFailure struct {
const (
// OperationFinished means volume operation has been finished
OperationFinished OperationStatus = "Finished"
// OperationInProgress means volume operation has been started and
// is in-progress. This state does not indicate if operation will succeed or fail but
// merely it has been started and is in-progress.
OperationInProgress OperationStatus = "InProgress"
// OperationStateNoChange indicates it is unchanged from previous state.
// This can be used to indicate transient failures for an operation which
// was in-progress previously.
OperationStateNoChange OperationStatus = "NoChange"
)
// OperationTimedOutError indicates a particular volume operation has timed out.
type OperationTimedOutError struct {
msg string msg string
} }
func (err *OperationTimedOutError) Error() string { func (err *TransientOperationFailure) Error() string {
return err.msg return err.msg
} }
// NewOperationTimedOutError returns a new instance of OperationTimedOutError // NewTransientOperationFailure creates an instance of TransientOperationFailure error
func NewOperationTimedOutError(msg string) *OperationTimedOutError { func NewTransientOperationFailure(msg string) *TransientOperationFailure {
return &OperationTimedOutError{ return &TransientOperationFailure{msg: msg}
msg: msg,
}
} }
// IsOperationTimeOutError returns true if volume operation could have timed out for client but possibly // UncertainProgressError indicates operation failed with a non-final error
// still running or being processed by the volume plugin. // and operation may be in-progress in background.
func IsOperationTimeOutError(err error) bool { type UncertainProgressError struct {
if _, ok := err.(*OperationTimedOutError); ok { msg string
}
func (err *UncertainProgressError) Error() string {
return err.msg
}
// NewUncertainProgressError creates an instance of UncertainProgressError type
func NewUncertainProgressError(msg string) *UncertainProgressError {
return &UncertainProgressError{msg: msg}
}
// IsOperationFinishedError checks if given error is of type that indicates
// operation is finished with an error.
func IsOperationFinishedError(err error) bool {
if _, ok := err.(*UncertainProgressError); ok {
return false
}
if _, ok := err.(*TransientOperationFailure); ok {
return false
}
return true
}
// IsUncertainProgressError checks if given error is of type that indicates
// operation might be in-progress in background.
func IsUncertainProgressError(err error) bool {
if _, ok := err.(*UncertainProgressError); ok {
return true return true
} }
return false return false

View File

@ -19,11 +19,10 @@ package volume
import ( import (
"time" "time"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
// Volume represents a directory used by pods or hosts on a node. All method // Volume represents a directory used by pods or hosts on a node. All method
@ -129,7 +128,11 @@ type Mounter interface {
// content should be owned by 'fsGroup' so that it can be // content should be owned by 'fsGroup' so that it can be
// accessed by the pod. This may be called more than once, so // accessed by the pod. This may be called more than once, so
// implementations must be idempotent. // implementations must be idempotent.
SetUp(mounterArgs MounterArgs) (volumetypes.OperationStatus, error) // It could return following types of errors:
// - TransientOperationFailure
// - UncertainProgressError
// - Error of any other type should be considered a final error
SetUp(mounterArgs MounterArgs) error
// SetUpAt prepares and mounts/unpacks the volume to the // SetUpAt prepares and mounts/unpacks the volume to the
// specified directory path, which may or may not exist yet. // specified directory path, which may or may not exist yet.
@ -249,7 +252,11 @@ type DeviceMounter interface {
// MountDevice mounts the disk to a global path which // MountDevice mounts the disk to a global path which
// individual pods can then bind mount // individual pods can then bind mount
// Note that devicePath can be empty if the volume plugin does not implement any of Attach and WaitForAttach methods. // Note that devicePath can be empty if the volume plugin does not implement any of Attach and WaitForAttach methods.
MountDevice(spec *Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) // It could return following types of errors:
// - TransientOperationFailure
// - UncertainProgressError
// - Error of any other type should be considered a final error
MountDevice(spec *Spec, devicePath string, deviceMountPath string) error
} }
type BulkVolumeVerifier interface { type BulkVolumeVerifier interface {

View File

@ -23,7 +23,6 @@ go_library(
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",

View File

@ -33,7 +33,6 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/legacy-cloud-providers/vsphere" "k8s.io/legacy-cloud-providers/vsphere"
) )
@ -208,7 +207,8 @@ func (plugin *vsphereVolumePlugin) GetDeviceMountRefs(deviceMountPath string) ([
return mounter.GetMountRefs(deviceMountPath) return mounter.GetMountRefs(deviceMountPath)
} }
func (attacher *vsphereVMDKAttacher) mountDeviceInternal(spec *volume.Spec, devicePath string, deviceMountPath string) error { // MountDevice mounts device to global mount point.
func (attacher *vsphereVMDKAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
klog.Info("vsphere MountDevice", devicePath, deviceMountPath) klog.Info("vsphere MountDevice", devicePath, deviceMountPath)
mounter := attacher.host.GetMounter(vsphereVolumePluginName) mounter := attacher.host.GetMounter(vsphereVolumePluginName)
notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath) notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath)
@ -248,12 +248,6 @@ func (attacher *vsphereVMDKAttacher) mountDeviceInternal(spec *volume.Spec, devi
return nil return nil
} }
// MountDevice mounts device to global mount point.
func (attacher *vsphereVMDKAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) {
err := attacher.mountDeviceInternal(spec, devicePath, deviceMountPath)
return volumetypes.OperationFinished, err
}
type vsphereVMDKDetacher struct { type vsphereVMDKDetacher struct {
mounter mount.Interface mounter mount.Interface
vsphereVolumes vsphere.Volumes vsphereVolumes vsphere.Volumes

View File

@ -38,7 +38,7 @@ import (
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types" )
// This is the primary entrypoint for volume plugins. // This is the primary entrypoint for volume plugins.
func ProbeVolumePlugins() []volume.VolumePlugin { func ProbeVolumePlugins() []volume.VolumePlugin {
@ -213,9 +213,8 @@ func (b *vsphereVolumeMounter) GetAttributes() volume.Attributes {
} }
// SetUp attaches the disk and bind mounts to the volume path. // SetUp attaches the disk and bind mounts to the volume path.
func (b *vsphereVolumeMounter) SetUp(mounterArgs volume.MounterArgs) (volumetypes.OperationStatus, error) { func (b *vsphereVolumeMounter) SetUp(mounterArgs volume.MounterArgs) error {
err := b.SetUpAt(b.GetPath(), mounterArgs) return b.SetUpAt(b.GetPath(), mounterArgs)
return volumetypes.OperationFinished, err
} }
// Checks prior to mount operations to verify that the required components (binaries, etc.) // Checks prior to mount operations to verify that the required components (binaries, etc.)

View File

@ -126,7 +126,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Got unexpected path: %s", path) t.Errorf("Got unexpected path: %s", path)
} }
if _, err := mounter.SetUp(volume.MounterArgs{}); err != nil { if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
t.Errorf("Expected success, got: %v", err) t.Errorf("Expected success, got: %v", err)
} }