From 935c23f2ad72f07abbb02dec1b5d0398d385d99a Mon Sep 17 00:00:00 2001 From: Travis Rhoden Date: Thu, 22 Aug 2019 23:18:23 -0600 Subject: [PATCH] Move HostUtil to pkg/volume/util/hostutil This patch moves the HostUtil functionality from the util/mount package to the volume/util/hostutil package. All `*NewHostUtil*` calls are changed to return concrete types instead of interfaces. All callers are changed to use the `*NewHostUtil*` methods instead of directly instantiating the concrete types. --- cmd/kubelet/app/BUILD | 1 + cmd/kubelet/app/server.go | 3 +- pkg/kubelet/BUILD | 2 + pkg/kubelet/kubelet.go | 5 +- pkg/kubelet/kubelet_pods.go | 4 +- pkg/kubelet/kubelet_pods_linux_test.go | 6 +- pkg/kubelet/kubelet_pods_test.go | 6 +- pkg/kubelet/kubelet_pods_windows_test.go | 6 +- pkg/kubelet/kubelet_test.go | 3 +- pkg/kubelet/runonce_test.go | 3 +- pkg/kubelet/volume_host.go | 3 +- pkg/kubelet/volumemanager/BUILD | 2 + pkg/kubelet/volumemanager/reconciler/BUILD | 2 + .../volumemanager/reconciler/reconciler.go | 7 +- .../reconciler/reconciler_test.go | 27 ++-- pkg/kubelet/volumemanager/volume_manager.go | 3 +- .../volumemanager/volume_manager_test.go | 3 +- pkg/kubemark/BUILD | 1 + pkg/kubemark/hollow_kubelet.go | 3 +- pkg/util/mount/BUILD | 12 -- pkg/util/mount/hostutil_unsupported.go | 85 ----------- pkg/util/mount/mount.go | 3 +- pkg/util/mount/mount_helper_unix.go | 54 +++---- pkg/util/mount/mount_helper_unix_test.go | 138 +++++++++--------- pkg/util/mount/mount_linux.go | 16 +- pkg/util/mount/mount_unsupported.go | 4 - pkg/util/mount/mount_windows.go | 4 +- pkg/volume/BUILD | 1 + pkg/volume/hostpath/BUILD | 3 +- pkg/volume/hostpath/host_path.go | 9 +- pkg/volume/hostpath/host_path_test.go | 17 +-- pkg/volume/local/BUILD | 4 + pkg/volume/local/local.go | 13 +- pkg/volume/local/local_test.go | 9 +- pkg/volume/plugins.go | 7 +- pkg/volume/testing/BUILD | 1 + pkg/volume/testing/testing.go | 15 +- pkg/volume/util/BUILD | 1 + pkg/volume/util/hostutil/BUILD | 57 ++++++++ .../util/hostutil}/fake_hostutil.go | 22 ++- .../util/hostutil}/hostutil.go | 13 +- .../util/hostutil}/hostutil_linux.go | 79 ++++++---- .../util/hostutil}/hostutil_linux_test.go | 16 +- .../util/hostutil/hostutil_unsupported.go | 102 +++++++++++++ .../util/hostutil}/hostutil_windows.go | 45 +++--- .../util/hostutil}/hostutil_windows_test.go | 2 +- pkg/volume/util/operationexecutor/BUILD | 3 +- .../util/operationexecutor/fakegenerator.go | 8 +- .../operationexecutor/operation_executor.go | 7 +- .../operation_executor_test.go | 8 +- .../operationexecutor/operation_generator.go | 12 +- 51 files changed, 496 insertions(+), 364 deletions(-) delete mode 100644 pkg/util/mount/hostutil_unsupported.go create mode 100644 pkg/volume/util/hostutil/BUILD rename pkg/{util/mount => volume/util/hostutil}/fake_hostutil.go (79%) rename pkg/{util/mount => volume/util/hostutil}/hostutil.go (92%) rename pkg/{util/mount => volume/util/hostutil}/hostutil_linux.go (73%) rename pkg/{util/mount => volume/util/hostutil}/hostutil_linux_test.go (96%) create mode 100644 pkg/volume/util/hostutil/hostutil_unsupported.go rename pkg/{util/mount => volume/util/hostutil}/hostutil_windows.go (65%) rename pkg/{util/mount => volume/util/hostutil}/hostutil_windows_test.go (99%) diff --git a/cmd/kubelet/app/BUILD b/cmd/kubelet/app/BUILD index 654f93c527b..fc364aa548f 100644 --- a/cmd/kubelet/app/BUILD +++ b/cmd/kubelet/app/BUILD @@ -107,6 +107,7 @@ go_library( "//pkg/volume/scaleio:go_default_library", "//pkg/volume/secret:go_default_library", "//pkg/volume/storageos:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/subpath:go_default_library", "//pkg/volume/vsphere_volume:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index 46540e4760b..e497bdcd838 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -97,6 +97,7 @@ import ( "k8s.io/kubernetes/pkg/util/rlimit" "k8s.io/kubernetes/pkg/version" "k8s.io/kubernetes/pkg/version/verflag" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/utils/exec" ) @@ -369,7 +370,7 @@ func UnsecuredDependencies(s *options.KubeletServer) (*kubelet.Dependencies, err mounter := mount.New(s.ExperimentalMounterPath) subpather := subpath.New(mounter) - hu := mount.NewHostUtil() + hu := hostutil.NewHostUtil() var pluginRunner = exec.New() var dockerClientConfig *dockershim.ClientConfig diff --git a/pkg/kubelet/BUILD b/pkg/kubelet/BUILD index 1f349d4f3df..4aa528ec1fd 100644 --- a/pkg/kubelet/BUILD +++ b/pkg/kubelet/BUILD @@ -112,6 +112,7 @@ go_library( "//pkg/volume/csi:go_default_library", "//pkg/volume/util:go_default_library", "//pkg/volume/util/exec:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/subpath:go_default_library", "//pkg/volume/util/types:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library", @@ -220,6 +221,7 @@ go_test( "//pkg/volume/hostpath:go_default_library", "//pkg/volume/testing:go_default_library", "//pkg/volume/util:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/subpath:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 641c5db13e0..c2acd358e59 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -117,6 +117,7 @@ import ( "k8s.io/kubernetes/pkg/util/selinux" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/csi" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/pkg/volume/util/volumepathhandler" utilexec "k8s.io/utils/exec" @@ -254,7 +255,7 @@ type Dependencies struct { OnHeartbeatFailure func() KubeClient clientset.Interface Mounter mount.Interface - HostUtil mount.HostUtils + HostUtil hostutil.HostUtils OOMAdjuster *oom.OOMAdjuster OSInterface kubecontainer.OSInterface PodConfig *config.PodConfig @@ -1105,7 +1106,7 @@ type Kubelet struct { mounter mount.Interface // hostutil to interact with filesystems - hostutil mount.HostUtils + hostutil hostutil.HostUtils // subpather to execute subpath actions subpather subpath.Interface diff --git a/pkg/kubelet/kubelet_pods.go b/pkg/kubelet/kubelet_pods.go index 29a2b6b4db9..013d0f55aea 100644 --- a/pkg/kubelet/kubelet_pods.go +++ b/pkg/kubelet/kubelet_pods.go @@ -59,8 +59,8 @@ import ( "k8s.io/kubernetes/pkg/kubelet/status" kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/kubelet/util/format" - mountutil "k8s.io/kubernetes/pkg/util/mount" volumeutil "k8s.io/kubernetes/pkg/volume/util" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/pkg/volume/util/volumepathhandler" volumevalidation "k8s.io/kubernetes/pkg/volume/validation" @@ -128,7 +128,7 @@ func (kl *Kubelet) makeBlockVolumes(pod *v1.Pod, container *v1.Container, podVol } // makeMounts determines the mount points for the given container. -func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain, podIP string, podVolumes kubecontainer.VolumeMap, hu mountutil.HostUtils, subpather subpath.Interface, expandEnvs []kubecontainer.EnvVar) ([]kubecontainer.Mount, func(), error) { +func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain, podIP string, podVolumes kubecontainer.VolumeMap, hu hostutil.HostUtils, subpather subpath.Interface, expandEnvs []kubecontainer.EnvVar) ([]kubecontainer.Mount, func(), error) { // Kubernetes only mounts on /etc/hosts if: // - container is not an infrastructure (pause) container // - container is not already mounting on /etc/hosts diff --git a/pkg/kubelet/kubelet_pods_linux_test.go b/pkg/kubelet/kubelet_pods_linux_test.go index c4fe1148e39..878f6fe9d05 100644 --- a/pkg/kubelet/kubelet_pods_linux_test.go +++ b/pkg/kubelet/kubelet_pods_linux_test.go @@ -22,13 +22,13 @@ import ( "testing" "github.com/stretchr/testify/assert" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" _ "k8s.io/kubernetes/pkg/apis/core/install" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/util/mount" volumetest "k8s.io/kubernetes/pkg/volume/testing" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/subpath" ) @@ -241,7 +241,7 @@ func TestMakeMounts(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { - fhu := &mount.FakeHostUtil{} + fhu := hostutil.NewFakeHostUtil(nil) fsp := &subpath.FakeSubpath{} pod := v1.Pod{ Spec: v1.PodSpec{ diff --git a/pkg/kubelet/kubelet_pods_test.go b/pkg/kubelet/kubelet_pods_test.go index f6f1a8a0e53..ad665874eec 100644 --- a/pkg/kubelet/kubelet_pods_test.go +++ b/pkg/kubelet/kubelet_pods_test.go @@ -27,7 +27,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -48,12 +48,12 @@ import ( containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" "k8s.io/kubernetes/pkg/kubelet/server/portforward" "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" - "k8s.io/kubernetes/pkg/util/mount" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/subpath" ) func TestDisabledSubpath(t *testing.T) { - fhu := &mount.FakeHostUtil{} + fhu := hostutil.NewFakeHostUtil(nil) fsp := &subpath.FakeSubpath{} pod := v1.Pod{ Spec: v1.PodSpec{ diff --git a/pkg/kubelet/kubelet_pods_windows_test.go b/pkg/kubelet/kubelet_pods_windows_test.go index 16d514ee797..e95863dd47f 100644 --- a/pkg/kubelet/kubelet_pods_windows_test.go +++ b/pkg/kubelet/kubelet_pods_windows_test.go @@ -20,9 +20,9 @@ import ( "testing" "github.com/stretchr/testify/assert" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/util/mount" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/subpath" ) @@ -82,7 +82,7 @@ func TestMakeMountsWindows(t *testing.T) { }, } - fhu := &mount.FakeHostUtil{} + fhu := hostutil.NewFakeHostUtil(nil) fsp := &subpath.FakeSubpath{} mounts, _, _ := makeMounts(&pod, "/pod", &container, "fakepodname", "", "", podVolumes, fhu, fsp, nil) diff --git a/pkg/kubelet/kubelet_test.go b/pkg/kubelet/kubelet_test.go index 7f6c7fb4126..80c6dcb73b6 100644 --- a/pkg/kubelet/kubelet_test.go +++ b/pkg/kubelet/kubelet_test.go @@ -76,6 +76,7 @@ import ( _ "k8s.io/kubernetes/pkg/volume/hostpath" volumetest "k8s.io/kubernetes/pkg/volume/testing" "k8s.io/kubernetes/pkg/volume/util" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/subpath" ) @@ -162,7 +163,7 @@ func newTestKubeletWithImageList( kubelet.heartbeatClient = fakeKubeClient kubelet.os = &containertest.FakeOS{} kubelet.mounter = &mount.FakeMounter{} - kubelet.hostutil = &mount.FakeHostUtil{} + kubelet.hostutil = hostutil.NewFakeHostUtil(nil) kubelet.subpather = &subpath.FakeSubpath{} kubelet.hostname = testKubeletHostname diff --git a/pkg/kubelet/runonce_test.go b/pkg/kubelet/runonce_test.go index fabcd8aa48b..7239133e481 100644 --- a/pkg/kubelet/runonce_test.go +++ b/pkg/kubelet/runonce_test.go @@ -46,6 +46,7 @@ import ( "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" volumetest "k8s.io/kubernetes/pkg/volume/testing" + "k8s.io/kubernetes/pkg/volume/util/hostutil" ) func TestRunOnce(t *testing.T) { @@ -85,7 +86,7 @@ func TestRunOnce(t *testing.T) { hostname: testKubeletHostname, nodeName: testKubeletHostname, runtimeState: newRuntimeState(time.Second), - hostutil: &mount.FakeHostUtil{}, + hostutil: hostutil.NewFakeHostUtil(nil), } kb.containerManager = cm.NewStubContainerManager() diff --git a/pkg/kubelet/volume_host.go b/pkg/kubelet/volume_host.go index 4a63db4b864..7135a1300c0 100644 --- a/pkg/kubelet/volume_host.go +++ b/pkg/kubelet/volume_host.go @@ -44,6 +44,7 @@ import ( "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util" execmnt "k8s.io/kubernetes/pkg/volume/util/exec" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/subpath" ) @@ -160,7 +161,7 @@ func (kvh *kubeletVolumeHost) GetSubpather() subpath.Interface { return kvh.kubelet.subpather } -func (kvh *kubeletVolumeHost) GetHostUtil() mount.HostUtils { +func (kvh *kubeletVolumeHost) GetHostUtil() hostutil.HostUtils { return kvh.kubelet.hostutil } diff --git a/pkg/kubelet/volumemanager/BUILD b/pkg/kubelet/volumemanager/BUILD index de11977bdd4..14a84296c55 100644 --- a/pkg/kubelet/volumemanager/BUILD +++ b/pkg/kubelet/volumemanager/BUILD @@ -26,6 +26,7 @@ go_library( "//pkg/util/mount:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/util:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/operationexecutor:go_default_library", "//pkg/volume/util/types:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library", @@ -58,6 +59,7 @@ go_test( "//pkg/volume:go_default_library", "//pkg/volume/testing:go_default_library", "//pkg/volume/util:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/types: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", diff --git a/pkg/kubelet/volumemanager/reconciler/BUILD b/pkg/kubelet/volumemanager/reconciler/BUILD index fd9754be991..523ca37a03d 100644 --- a/pkg/kubelet/volumemanager/reconciler/BUILD +++ b/pkg/kubelet/volumemanager/reconciler/BUILD @@ -18,6 +18,7 @@ go_library( "//pkg/util/mount:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/util:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/nestedpendingoperations:go_default_library", "//pkg/volume/util/operationexecutor:go_default_library", "//pkg/volume/util/types:go_default_library", @@ -44,6 +45,7 @@ go_test( "//pkg/volume:go_default_library", "//pkg/volume/testing:go_default_library", "//pkg/volume/util:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/operationexecutor:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", diff --git a/pkg/kubelet/volumemanager/reconciler/reconciler.go b/pkg/kubelet/volumemanager/reconciler/reconciler.go index e5d1d5ea235..4199dd6b527 100644 --- a/pkg/kubelet/volumemanager/reconciler/reconciler.go +++ b/pkg/kubelet/volumemanager/reconciler/reconciler.go @@ -26,7 +26,7 @@ import ( "path" "time" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" @@ -40,6 +40,7 @@ import ( "k8s.io/kubernetes/pkg/util/mount" volumepkg "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/nestedpendingoperations" "k8s.io/kubernetes/pkg/volume/util/operationexecutor" volumetypes "k8s.io/kubernetes/pkg/volume/util/types" @@ -100,7 +101,7 @@ func NewReconciler( populatorHasAddedPods func() bool, operationExecutor operationexecutor.OperationExecutor, mounter mount.Interface, - hostutil mount.HostUtils, + hostutil hostutil.HostUtils, volumePluginMgr *volumepkg.VolumePluginMgr, kubeletPodsDir string) Reconciler { return &reconciler{ @@ -132,7 +133,7 @@ type reconciler struct { populatorHasAddedPods func() bool operationExecutor operationexecutor.OperationExecutor mounter mount.Interface - hostutil mount.HostUtils + hostutil hostutil.HostUtils volumePluginMgr *volumepkg.VolumePluginMgr kubeletPodsDir string timeOfLastSync time.Time diff --git a/pkg/kubelet/volumemanager/reconciler/reconciler_test.go b/pkg/kubelet/volumemanager/reconciler/reconciler_test.go index 1ab0264bdab..99c83a7ea53 100644 --- a/pkg/kubelet/volumemanager/reconciler/reconciler_test.go +++ b/pkg/kubelet/volumemanager/reconciler/reconciler_test.go @@ -22,7 +22,7 @@ import ( "time" "github.com/stretchr/testify/assert" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -40,6 +40,7 @@ import ( "k8s.io/kubernetes/pkg/volume" volumetesting "k8s.io/kubernetes/pkg/volume/testing" "k8s.io/kubernetes/pkg/volume/util" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/operationexecutor" ) @@ -84,7 +85,7 @@ func Test_Run_Positive_DoNothing(t *testing.T) { hasAddedPods, oex, &mount.FakeMounter{}, - &mount.FakeHostUtil{}, + hostutil.NewFakeHostUtil(nil), volumePluginMgr, kubeletPodsDir) @@ -128,7 +129,7 @@ func Test_Run_Positive_VolumeAttachAndMount(t *testing.T) { hasAddedPods, oex, &mount.FakeMounter{}, - &mount.FakeHostUtil{}, + hostutil.NewFakeHostUtil(nil), volumePluginMgr, kubeletPodsDir) pod := &v1.Pod{ @@ -206,7 +207,7 @@ func Test_Run_Positive_VolumeMountControllerAttachEnabled(t *testing.T) { hasAddedPods, oex, &mount.FakeMounter{}, - &mount.FakeHostUtil{}, + hostutil.NewFakeHostUtil(nil), volumePluginMgr, kubeletPodsDir) pod := &v1.Pod{ @@ -285,7 +286,7 @@ func Test_Run_Positive_VolumeAttachMountUnmountDetach(t *testing.T) { hasAddedPods, oex, &mount.FakeMounter{}, - &mount.FakeHostUtil{}, + hostutil.NewFakeHostUtil(nil), volumePluginMgr, kubeletPodsDir) pod := &v1.Pod{ @@ -375,7 +376,7 @@ func Test_Run_Positive_VolumeUnmountControllerAttachEnabled(t *testing.T) { hasAddedPods, oex, &mount.FakeMounter{}, - &mount.FakeHostUtil{}, + hostutil.NewFakeHostUtil(nil), volumePluginMgr, kubeletPodsDir) pod := &v1.Pod{ @@ -502,7 +503,7 @@ func Test_Run_Positive_VolumeAttachAndMap(t *testing.T) { hasAddedPods, oex, &mount.FakeMounter{}, - &mount.FakeHostUtil{}, + hostutil.NewFakeHostUtil(nil), volumePluginMgr, kubeletPodsDir) @@ -608,7 +609,7 @@ func Test_Run_Positive_BlockVolumeMapControllerAttachEnabled(t *testing.T) { hasAddedPods, oex, &mount.FakeMounter{}, - &mount.FakeHostUtil{}, + hostutil.NewFakeHostUtil(nil), volumePluginMgr, kubeletPodsDir) @@ -709,7 +710,7 @@ func Test_Run_Positive_BlockVolumeAttachMapUnmapDetach(t *testing.T) { hasAddedPods, oex, &mount.FakeMounter{}, - &mount.FakeHostUtil{}, + hostutil.NewFakeHostUtil(nil), volumePluginMgr, kubeletPodsDir) @@ -823,7 +824,7 @@ func Test_Run_Positive_VolumeUnmapControllerAttachEnabled(t *testing.T) { hasAddedPods, oex, &mount.FakeMounter{}, - &mount.FakeHostUtil{}, + hostutil.NewFakeHostUtil(nil), volumePluginMgr, kubeletPodsDir) @@ -993,7 +994,7 @@ func Test_GenerateUnmapDeviceFunc_Plugin_Not_Found(t *testing.T) { nil, /* fakeRecorder */ false, /* checkNodeCapabilitiesBeforeMount */ nil)) - var hostutil mount.HostUtils + var hostutil hostutil.HostUtils volumeMode := v1.PersistentVolumeBlock tmpSpec := &volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{VolumeMode: &volumeMode}}} deviceToDetach := operationexecutor.AttachedVolume{VolumeSpec: tmpSpec, PluginName: "fake-file-plugin"} @@ -1096,7 +1097,7 @@ func Test_Run_Positive_VolumeFSResizeControllerAttachEnabled(t *testing.T) { hasAddedPods, oex, &mount.FakeMounter{}, - &mount.FakeHostUtil{}, + hostutil.NewFakeHostUtil(nil), volumePluginMgr, kubeletPodsDir) @@ -1278,7 +1279,7 @@ func Test_Run_Positive_VolumeMountControllerAttachEnabledRace(t *testing.T) { hasAddedPods, oex, &mount.FakeMounter{}, - &mount.FakeHostUtil{}, + hostutil.NewFakeHostUtil(nil), volumePluginMgr, kubeletPodsDir) pod := &v1.Pod{ diff --git a/pkg/kubelet/volumemanager/volume_manager.go b/pkg/kubelet/volumemanager/volume_manager.go index d8549ca5e97..0aa368761e5 100644 --- a/pkg/kubelet/volumemanager/volume_manager.go +++ b/pkg/kubelet/volumemanager/volume_manager.go @@ -44,6 +44,7 @@ import ( "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/operationexecutor" "k8s.io/kubernetes/pkg/volume/util/types" "k8s.io/kubernetes/pkg/volume/util/volumepathhandler" @@ -153,7 +154,7 @@ func NewVolumeManager( volumePluginMgr *volume.VolumePluginMgr, kubeContainerRuntime container.Runtime, mounter mount.Interface, - hostutil mount.HostUtils, + hostutil hostutil.HostUtils, kubeletPodsDir string, recorder record.EventRecorder, checkNodeCapabilitiesBeforeMount bool, diff --git a/pkg/kubelet/volumemanager/volume_manager_test.go b/pkg/kubelet/volumemanager/volume_manager_test.go index db4e78e24bf..ed8bdb9acc5 100644 --- a/pkg/kubelet/volumemanager/volume_manager_test.go +++ b/pkg/kubelet/volumemanager/volume_manager_test.go @@ -46,6 +46,7 @@ import ( "k8s.io/kubernetes/pkg/volume" volumetest "k8s.io/kubernetes/pkg/volume/testing" "k8s.io/kubernetes/pkg/volume/util" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/types" ) @@ -301,7 +302,7 @@ func newTestVolumeManager(tmpDir string, podManager kubepod.Manager, kubeClient plugMgr, &containertest.FakeRuntime{}, &mount.FakeMounter{}, - &mount.FakeHostUtil{}, + hostutil.NewFakeHostUtil(nil), "", fakeRecorder, false, /* experimentalCheckNodeCapabilitiesBeforeMount */ diff --git a/pkg/kubemark/BUILD b/pkg/kubemark/BUILD index b7bced83d39..bfddad59b6f 100644 --- a/pkg/kubemark/BUILD +++ b/pkg/kubemark/BUILD @@ -35,6 +35,7 @@ go_library( "//pkg/volume/emptydir:go_default_library", "//pkg/volume/projected:go_default_library", "//pkg/volume/secret:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/subpath: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", diff --git a/pkg/kubemark/hollow_kubelet.go b/pkg/kubemark/hollow_kubelet.go index db44981f5ec..ed74ea91b04 100644 --- a/pkg/kubemark/hollow_kubelet.go +++ b/pkg/kubemark/hollow_kubelet.go @@ -36,6 +36,7 @@ import ( "k8s.io/kubernetes/pkg/volume/emptydir" "k8s.io/kubernetes/pkg/volume/projected" "k8s.io/kubernetes/pkg/volume/secret" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/test/utils" @@ -75,7 +76,7 @@ func NewHollowKubelet( OOMAdjuster: oom.NewFakeOOMAdjuster(), Mounter: mount.New("" /* default mount path */), Subpather: &subpath.FakeSubpath{}, - HostUtil: &mount.FakeHostUtil{}, + HostUtil: hostutil.NewFakeHostUtil(nil), } return &HollowKubelet{ diff --git a/pkg/util/mount/BUILD b/pkg/util/mount/BUILD index 3fdbbddbccb..813b14879f5 100644 --- a/pkg/util/mount/BUILD +++ b/pkg/util/mount/BUILD @@ -6,11 +6,6 @@ go_library( "doc.go", "exec.go", "fake.go", - "fake_hostutil.go", - "hostutil.go", - "hostutil_linux.go", - "hostutil_unsupported.go", - "hostutil_windows.go", "mount.go", "mount_helper_common.go", "mount_helper_unix.go", @@ -38,9 +33,7 @@ go_library( "//vendor/k8s.io/utils/io:go_default_library", ], "@io_bazel_rules_go//go/platform:linux": [ - "//vendor/golang.org/x/sys/unix:go_default_library", "//vendor/k8s.io/utils/io:go_default_library", - "//vendor/k8s.io/utils/path:go_default_library", ], "@io_bazel_rules_go//go/platform:nacl": [ "//vendor/k8s.io/utils/io:go_default_library", @@ -68,8 +61,6 @@ go_library( go_test( name = "go_default_test", srcs = [ - "hostutil_linux_test.go", - "hostutil_windows_test.go", "mount_helper_test.go", "mount_helper_unix_test.go", "mount_helper_windows_test.go", @@ -82,9 +73,6 @@ go_test( deps = [ "//vendor/k8s.io/utils/exec/testing:go_default_library", ] + select({ - "@io_bazel_rules_go//go/platform:linux": [ - "//vendor/k8s.io/utils/exec:go_default_library", - ], "@io_bazel_rules_go//go/platform:windows": [ "//vendor/github.com/stretchr/testify/assert:go_default_library", ], diff --git a/pkg/util/mount/hostutil_unsupported.go b/pkg/util/mount/hostutil_unsupported.go deleted file mode 100644 index d4b05137156..00000000000 --- a/pkg/util/mount/hostutil_unsupported.go +++ /dev/null @@ -1,85 +0,0 @@ -// +build !linux,!windows - -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package mount - -import ( - "os" -) - -type hostUtil struct{} - -// NewHostUtil returns a struct that implements the HostUtils interface on -// unsupported platforms -func NewHostUtil() HostUtils { - return &hostUtil{} -} - -// DeviceOpened determines if the device is in use elsewhere -func (hu *hostUtil) DeviceOpened(pathname string) (bool, error) { - return false, errUnsupported -} - -// PathIsDevice determines if a path is a device. -func (hu *hostUtil) PathIsDevice(pathname string) (bool, error) { - return true, errUnsupported -} - -// GetDeviceNameFromMount finds the device name by checking the mount path -// to get the global mount path within its plugin directory -func (hu *hostUtil) GetDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) { - return "", errUnsupported -} - -func (hu *hostUtil) MakeRShared(path string) error { - return errUnsupported -} - -func (hu *hostUtil) GetFileType(pathname string) (FileType, error) { - return FileType("fake"), errUnsupported -} - -func (hu *hostUtil) MakeFile(pathname string) error { - return errUnsupported -} - -func (hu *hostUtil) MakeDir(pathname string) error { - return errUnsupported -} - -func (hu *hostUtil) PathExists(pathname string) (bool, error) { - return true, errUnsupported -} - -// EvalHostSymlinks returns the path name after evaluating symlinks -func (hu *hostUtil) EvalHostSymlinks(pathname string) (string, error) { - return "", errUnsupported -} - -// GetOwner returns the integer ID for the user and group of the given path -func (hu *hostUtil) GetOwner(pathname string) (int64, int64, error) { - return -1, -1, errUnsupported -} - -func (hu *hostUtil) GetSELinuxSupport(pathname string) (bool, error) { - return false, errUnsupported -} - -func (hu *hostUtil) GetMode(pathname string) (os.FileMode, error) { - return 0, errUnsupported -} diff --git a/pkg/util/mount/mount.go b/pkg/util/mount/mount.go index 14b53d9bb82..7324d691144 100644 --- a/pkg/util/mount/mount.go +++ b/pkg/util/mount/mount.go @@ -180,8 +180,7 @@ func IsNotMountPoint(mounter Interface, file string) (bool, error) { } // Resolve any symlinks in file, kernel would do the same and use the resolved path in /proc/mounts. - hu := NewHostUtil() - resolvedFile, err := hu.EvalHostSymlinks(file) + resolvedFile, err := filepath.EvalSymlinks(file) if err != nil { return true, err } diff --git a/pkg/util/mount/mount_helper_unix.go b/pkg/util/mount/mount_helper_unix.go index b0602bc08c3..9c91e158264 100644 --- a/pkg/util/mount/mount_helper_unix.go +++ b/pkg/util/mount/mount_helper_unix.go @@ -55,38 +55,38 @@ func IsCorruptedMnt(err error) bool { return underlyingError == syscall.ENOTCONN || underlyingError == syscall.ESTALE || underlyingError == syscall.EIO || underlyingError == syscall.EACCES } -// This represents a single line in /proc//mountinfo. -type mountInfo struct { +// MountInfo represents a single line in /proc//mountinfo. +type MountInfo struct { // Unique ID for the mount (maybe reused after umount). - id int + ID int // The ID of the parent mount (or of self for the root of this mount namespace's mount tree). - parentID int + ParentID int // The value of `st_dev` for files on this filesystem. - majorMinor string + MajorMinor string // The pathname of the directory in the filesystem which forms the root of this mount. - root string + Root string // Mount source, filesystem-specific information. e.g. device, tmpfs name. - source string + Source string // Mount point, the pathname of the mount point. - mountPoint string + MountPoint string // Optional fieds, zero or more fields of the form "tag[:value]". - optionalFields []string + OptionalFields []string // The filesystem type in the form "type[.subtype]". - fsType string + FsType string // Per-mount options. - mountOptions []string + MountOptions []string // Per-superblock options. - superOptions []string + SuperOptions []string } -// parseMountInfo parses /proc/xxx/mountinfo. -func parseMountInfo(filename string) ([]mountInfo, error) { +// ParseMountInfo parses /proc/xxx/mountinfo. +func ParseMountInfo(filename string) ([]MountInfo, error) { content, err := utilio.ConsistentRead(filename, maxListTries) if err != nil { - return []mountInfo{}, err + return []MountInfo{}, err } contentStr := string(content) - infos := []mountInfo{} + infos := []MountInfo{} for _, line := range strings.Split(contentStr, "\n") { if line == "" { @@ -106,27 +106,27 @@ func parseMountInfo(filename string) ([]mountInfo, error) { if err != nil { return nil, err } - info := mountInfo{ - id: id, - parentID: parentID, - majorMinor: fields[2], - root: fields[3], - mountPoint: fields[4], - mountOptions: strings.Split(fields[5], ","), + info := MountInfo{ + ID: id, + ParentID: parentID, + MajorMinor: fields[2], + Root: fields[3], + MountPoint: fields[4], + MountOptions: strings.Split(fields[5], ","), } // All fields until "-" are "optional fields". i := 6 for ; i < len(fields) && fields[i] != "-"; i++ { - info.optionalFields = append(info.optionalFields, fields[i]) + info.OptionalFields = append(info.OptionalFields, fields[i]) } // Parse the rest 3 fields. i++ if len(fields)-i < 3 { return nil, fmt.Errorf("expect 3 fields in %s, got %d", line, len(fields)-i) } - info.fsType = fields[i] - info.source = fields[i+1] - info.superOptions = strings.Split(fields[i+2], ",") + info.FsType = fields[i] + info.Source = fields[i+1] + info.SuperOptions = strings.Split(fields[i+2], ",") infos = append(infos, info) } return infos, nil diff --git a/pkg/util/mount/mount_helper_unix_test.go b/pkg/util/mount/mount_helper_unix_test.go index 5c1ebdb4a22..f364b02863c 100644 --- a/pkg/util/mount/mount_helper_unix_test.go +++ b/pkg/util/mount/mount_helper_unix_test.go @@ -92,107 +92,107 @@ func TestParseMountInfo(t *testing.T) { tests := []struct { name string id int - expectedInfo mountInfo + expectedInfo MountInfo }{ { "simple bind mount", 189, - mountInfo{ - id: 189, - parentID: 80, - majorMinor: "8:1", - root: "/var/lib/kubelet", - source: "/dev/sda1", - mountPoint: "/var/lib/kubelet", - optionalFields: []string{"shared:30"}, - fsType: "ext4", - mountOptions: []string{"rw", "relatime"}, - superOptions: []string{"rw", "commit=30", "data=ordered"}, + MountInfo{ + ID: 189, + ParentID: 80, + MajorMinor: "8:1", + Root: "/var/lib/kubelet", + Source: "/dev/sda1", + MountPoint: "/var/lib/kubelet", + OptionalFields: []string{"shared:30"}, + FsType: "ext4", + MountOptions: []string{"rw", "relatime"}, + SuperOptions: []string{"rw", "commit=30", "data=ordered"}, }, }, { "bind mount a directory", 222, - mountInfo{ - id: 222, - parentID: 24, - majorMinor: "253:0", - root: "/tmp/src", - source: "/dev/mapper/vagrant--vg-root", - mountPoint: "/mnt/dst", - optionalFields: []string{"shared:1"}, - fsType: "ext4", - mountOptions: []string{"rw", "relatime"}, - superOptions: []string{"rw", "errors=remount-ro", "data=ordered"}, + MountInfo{ + ID: 222, + ParentID: 24, + MajorMinor: "253:0", + Root: "/tmp/src", + Source: "/dev/mapper/vagrant--vg-root", + MountPoint: "/mnt/dst", + OptionalFields: []string{"shared:1"}, + FsType: "ext4", + MountOptions: []string{"rw", "relatime"}, + SuperOptions: []string{"rw", "errors=remount-ro", "data=ordered"}, }, }, { "more than one optional fields", 224, - mountInfo{ - id: 224, - parentID: 62, - majorMinor: "253:0", - root: "/var/lib/docker/devicemapper/test/shared", - source: "/dev/mapper/ssd-root", - mountPoint: "/var/lib/docker/devicemapper/test/shared", - optionalFields: []string{"master:1", "shared:44"}, - fsType: "ext4", - mountOptions: []string{"rw", "relatime"}, - superOptions: []string{"rw", "seclabel", "data=ordered"}, + MountInfo{ + ID: 224, + ParentID: 62, + MajorMinor: "253:0", + Root: "/var/lib/docker/devicemapper/test/shared", + Source: "/dev/mapper/ssd-root", + MountPoint: "/var/lib/docker/devicemapper/test/shared", + OptionalFields: []string{"master:1", "shared:44"}, + FsType: "ext4", + MountOptions: []string{"rw", "relatime"}, + SuperOptions: []string{"rw", "seclabel", "data=ordered"}, }, }, { "cgroup-mountpoint", 28, - mountInfo{ - id: 28, - parentID: 18, - majorMinor: "0:24", - root: "/", - source: "tmpfs", - mountPoint: "/sys/fs/cgroup", - optionalFields: []string{"shared:9"}, - fsType: "tmpfs", - mountOptions: []string{"ro", "nosuid", "nodev", "noexec"}, - superOptions: []string{"ro", "mode=755"}, + MountInfo{ + ID: 28, + ParentID: 18, + MajorMinor: "0:24", + Root: "/", + Source: "tmpfs", + MountPoint: "/sys/fs/cgroup", + OptionalFields: []string{"shared:9"}, + FsType: "tmpfs", + MountOptions: []string{"ro", "nosuid", "nodev", "noexec"}, + SuperOptions: []string{"ro", "mode=755"}, }, }, { "cgroup-subsystem-systemd-mountpoint", 29, - mountInfo{ - id: 29, - parentID: 28, - majorMinor: "0:25", - root: "/", - source: "cgroup", - mountPoint: "/sys/fs/cgroup/systemd", - optionalFields: []string{"shared:10"}, - fsType: "cgroup", - mountOptions: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}, - superOptions: []string{"rw", "xattr", "release_agent=/lib/systemd/systemd-cgroups-agent", "name=systemd"}, + MountInfo{ + ID: 29, + ParentID: 28, + MajorMinor: "0:25", + Root: "/", + Source: "cgroup", + MountPoint: "/sys/fs/cgroup/systemd", + OptionalFields: []string{"shared:10"}, + FsType: "cgroup", + MountOptions: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}, + SuperOptions: []string{"rw", "xattr", "release_agent=/lib/systemd/systemd-cgroups-agent", "name=systemd"}, }, }, { "cgroup-subsystem-cpuset-mountpoint", 31, - mountInfo{ - id: 31, - parentID: 28, - majorMinor: "0:27", - root: "/", - source: "cgroup", - mountPoint: "/sys/fs/cgroup/cpuset", - optionalFields: []string{"shared:13"}, - fsType: "cgroup", - mountOptions: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}, - superOptions: []string{"rw", "cpuset"}, + MountInfo{ + ID: 31, + ParentID: 28, + MajorMinor: "0:27", + Root: "/", + Source: "cgroup", + MountPoint: "/sys/fs/cgroup/cpuset", + OptionalFields: []string{"shared:13"}, + FsType: "cgroup", + MountOptions: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}, + SuperOptions: []string{"rw", "cpuset"}, }, }, } - infos, err := parseMountInfo(filename) + infos, err := ParseMountInfo(filename) if err != nil { t.Fatalf("Cannot parse %s: %s", filename, err) } @@ -200,7 +200,7 @@ func TestParseMountInfo(t *testing.T) { for _, test := range tests { found := false for _, info := range infos { - if info.id == test.id { + if info.ID == test.id { found = true if !reflect.DeepEqual(info, test.expectedInfo) { t.Errorf("Test case %q:\n expected: %+v\n got: %+v", test.name, test.expectedInfo, info) diff --git a/pkg/util/mount/mount_linux.go b/pkg/util/mount/mount_linux.go index 6555ac8b75f..dfd52bfe105 100644 --- a/pkg/util/mount/mount_linux.go +++ b/pkg/util/mount/mount_linux.go @@ -447,7 +447,7 @@ func parseProcMounts(content []byte) ([]MountPoint, error) { // root path and major:minor to represent mount source uniquely. // This implementation is shared between Linux and NsEnterMounter func SearchMountPoints(hostSource, mountInfoPath string) ([]string, error) { - mis, err := parseMountInfo(mountInfoPath) + mis, err := ParseMountInfo(mountInfoPath) if err != nil { return nil, err } @@ -460,11 +460,11 @@ func SearchMountPoints(hostSource, mountInfoPath string) ([]string, error) { // We need search in backward order because it's possible for later mounts // to overlap earlier mounts. for i := len(mis) - 1; i >= 0; i-- { - if hostSource == mis[i].mountPoint || PathWithinBase(hostSource, mis[i].mountPoint) { + if hostSource == mis[i].MountPoint || PathWithinBase(hostSource, mis[i].MountPoint) { // If it's a mount point or path under a mount point. - mountID = mis[i].id - rootPath = filepath.Join(mis[i].root, strings.TrimPrefix(hostSource, mis[i].mountPoint)) - majorMinor = mis[i].majorMinor + mountID = mis[i].ID + rootPath = filepath.Join(mis[i].Root, strings.TrimPrefix(hostSource, mis[i].MountPoint)) + majorMinor = mis[i].MajorMinor break } } @@ -475,12 +475,12 @@ func SearchMountPoints(hostSource, mountInfoPath string) ([]string, error) { var refs []string for i := range mis { - if mis[i].id == mountID { + if mis[i].ID == mountID { // Ignore mount entry for mount source itself. continue } - if mis[i].root == rootPath && mis[i].majorMinor == majorMinor { - refs = append(refs, mis[i].mountPoint) + if mis[i].Root == rootPath && mis[i].MajorMinor == majorMinor { + refs = append(refs, mis[i].MountPoint) } } diff --git a/pkg/util/mount/mount_unsupported.go b/pkg/util/mount/mount_unsupported.go index 5a1d107abd9..d13ec5c34d5 100644 --- a/pkg/util/mount/mount_unsupported.go +++ b/pkg/util/mount/mount_unsupported.go @@ -70,7 +70,3 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) { return true, errUnsupported } - -func getDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) { - return "", errUnsupported -} diff --git a/pkg/util/mount/mount_windows.go b/pkg/util/mount/mount_windows.go index bd5bfa6def6..f77931d1446 100644 --- a/pkg/util/mount/mount_windows.go +++ b/pkg/util/mount/mount_windows.go @@ -27,6 +27,7 @@ import ( "k8s.io/klog" "k8s.io/utils/keymutex" + utilpath "k8s.io/utils/path" ) // Mounter provides the default implementation of mount.Interface @@ -176,8 +177,7 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) { if err != nil { return true, fmt.Errorf("readlink error: %v", err) } - hu := NewHostUtil() - exists, err := hu.PathExists(target) + exists, err := utilpath.Exists(utilpath.CheckFollowSymlink, target) if err != nil { return true, err } diff --git a/pkg/volume/BUILD b/pkg/volume/BUILD index 3e4c112b507..edef4b8bee4 100644 --- a/pkg/volume/BUILD +++ b/pkg/volume/BUILD @@ -21,6 +21,7 @@ go_library( "//pkg/features:go_default_library", "//pkg/util/mount:go_default_library", "//pkg/volume/util/fs:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/recyclerclient:go_default_library", "//pkg/volume/util/subpath:go_default_library", "//staging/src/k8s.io/api/authentication/v1:go_default_library", diff --git a/pkg/volume/hostpath/BUILD b/pkg/volume/hostpath/BUILD index 651159f6855..37cbe37ea01 100644 --- a/pkg/volume/hostpath/BUILD +++ b/pkg/volume/hostpath/BUILD @@ -17,6 +17,7 @@ go_library( "//pkg/util/mount:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/util:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/recyclerclient:go_default_library", "//pkg/volume/validation:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", @@ -31,9 +32,9 @@ go_test( srcs = ["host_path_test.go"], embed = [":go_default_library"], deps = [ - "//pkg/util/mount:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/testing:go_default_library", + "//pkg/volume/util/hostutil: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/apis/meta/v1:go_default_library", diff --git a/pkg/volume/hostpath/host_path.go b/pkg/volume/hostpath/host_path.go index 7541ec9dd28..ffc4e7d7bdf 100644 --- a/pkg/volume/hostpath/host_path.go +++ b/pkg/volume/hostpath/host_path.go @@ -28,6 +28,7 @@ import ( "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/recyclerclient" "k8s.io/kubernetes/pkg/volume/validation" ) @@ -207,7 +208,7 @@ type hostPathMounter struct { *hostPath readOnly bool mounter mount.Interface - hu mount.HostUtils + hu hostutil.HostUtils } var _ volume.Mounter = &hostPathMounter{} @@ -361,7 +362,7 @@ type hostPathTypeChecker interface { type fileTypeChecker struct { path string exists bool - hu mount.HostUtils + hu hostutil.HostUtils } func (ftc *fileTypeChecker) Exists() bool { @@ -423,12 +424,12 @@ func (ftc *fileTypeChecker) GetPath() string { return ftc.path } -func newFileTypeChecker(path string, hu mount.HostUtils) hostPathTypeChecker { +func newFileTypeChecker(path string, hu hostutil.HostUtils) hostPathTypeChecker { return &fileTypeChecker{path: path, hu: hu} } // checkType checks whether the given path is the exact pathType -func checkType(path string, pathType *v1.HostPathType, hu mount.HostUtils) error { +func checkType(path string, pathType *v1.HostPathType, hu hostutil.HostUtils) error { return checkTypeInternal(newFileTypeChecker(path, hu), pathType) } diff --git a/pkg/volume/hostpath/host_path_test.go b/pkg/volume/hostpath/host_path_test.go index b967d8058e7..3d9ad182372 100644 --- a/pkg/volume/hostpath/host_path_test.go +++ b/pkg/volume/hostpath/host_path_test.go @@ -21,15 +21,15 @@ import ( "os" "testing" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/client-go/kubernetes/fake" - utilmount "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" volumetest "k8s.io/kubernetes/pkg/volume/testing" + "k8s.io/kubernetes/pkg/volume/util/hostutil" utilpath "k8s.io/utils/path" ) @@ -358,13 +358,13 @@ func TestOSFileTypeChecker(t *testing.T) { { name: "Existing Folder", path: "/tmp/ExistingFolder", - desiredType: string(utilmount.FileTypeDirectory), + desiredType: string(hostutil.FileTypeDirectory), isDir: true, }, { name: "Existing File", path: "/tmp/ExistingFolder/foo", - desiredType: string(utilmount.FileTypeFile), + desiredType: string(hostutil.FileTypeFile), isFile: true, }, { @@ -388,11 +388,10 @@ func TestOSFileTypeChecker(t *testing.T) { } for i, tc := range testCases { - fakeFTC := &utilmount.FakeHostUtil{ - Filesystem: map[string]utilmount.FileType{ - tc.path: utilmount.FileType(tc.desiredType), - }, - } + fakeFTC := hostutil.NewFakeHostUtil( + map[string]hostutil.FileType{ + tc.path: hostutil.FileType(tc.desiredType), + }) oftc := newFileTypeChecker(tc.path, fakeFTC) path := oftc.GetPath() diff --git a/pkg/volume/local/BUILD b/pkg/volume/local/BUILD index 63f2323d7a4..57cec77324c 100644 --- a/pkg/volume/local/BUILD +++ b/pkg/volume/local/BUILD @@ -13,6 +13,7 @@ go_library( "//pkg/util/mount:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/util:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/validation: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", @@ -36,6 +37,7 @@ go_test( "//pkg/util/mount:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/testing:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", @@ -45,6 +47,7 @@ go_test( "//pkg/util/mount:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/testing:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", @@ -54,6 +57,7 @@ go_test( "//pkg/util/mount:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/testing:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", diff --git a/pkg/volume/local/local.go b/pkg/volume/local/local.go index be043a1a503..faef40d7afd 100644 --- a/pkg/volume/local/local.go +++ b/pkg/volume/local/local.go @@ -33,6 +33,7 @@ import ( "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/validation" "k8s.io/utils/keymutex" utilstrings "k8s.io/utils/strings" @@ -246,9 +247,9 @@ func (plugin *localVolumePlugin) getGlobalLocalPath(spec *volume.Spec) (string, return "", err } switch fileType { - case mount.FileTypeDirectory: + case hostutil.FileTypeDirectory: return spec.PersistentVolume.Spec.Local.Path, nil - case mount.FileTypeBlockDev: + case hostutil.FileTypeBlockDev: return filepath.Join(plugin.generateBlockDeviceBaseGlobalPath(), spec.Name()), nil default: return "", fmt.Errorf("only directory and block device are supported") @@ -260,7 +261,7 @@ var _ volume.DeviceMountableVolumePlugin = &localVolumePlugin{} type deviceMounter struct { plugin *localVolumePlugin mounter *mount.SafeFormatAndMount - hostUtil mount.HostUtils + hostUtil hostutil.HostUtils } var _ volume.DeviceMounter = &deviceMounter{} @@ -332,11 +333,11 @@ func (dm *deviceMounter) MountDevice(spec *volume.Spec, devicePath string, devic } switch fileType { - case mount.FileTypeBlockDev: + case hostutil.FileTypeBlockDev: // local volume plugin does not implement AttachableVolumePlugin interface, so set devicePath to Path in PV spec directly devicePath = spec.PersistentVolume.Spec.Local.Path return dm.mountLocalBlockDevice(spec, devicePath, deviceMountPath) - case mount.FileTypeDirectory: + case hostutil.FileTypeDirectory: // if the given local volume path is of already filesystem directory, return directly return nil default: @@ -410,7 +411,7 @@ type localVolume struct { globalPath string // Mounter interface that provides system calls to mount the global path to the pod local path. mounter mount.Interface - hostUtil mount.HostUtils + hostUtil hostutil.HostUtils plugin *localVolumePlugin volume.MetricsProvider } diff --git a/pkg/volume/local/local_test.go b/pkg/volume/local/local_test.go index dcad1a056c9..08cfea559d7 100644 --- a/pkg/volume/local/local_test.go +++ b/pkg/volume/local/local_test.go @@ -26,13 +26,14 @@ import ( "runtime" "testing" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" utiltesting "k8s.io/client-go/util/testing" "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" volumetest "k8s.io/kubernetes/pkg/volume/testing" + "k8s.io/kubernetes/pkg/volume/util/hostutil" ) const ( @@ -109,10 +110,10 @@ func getDeviceMountablePluginWithBlockPath(t *testing.T, isBlockDevice bool) (st } plugMgr := volume.VolumePluginMgr{} - var pathToFSType map[string]mount.FileType + var pathToFSType map[string]hostutil.FileType if isBlockDevice { - pathToFSType = map[string]mount.FileType{ - tmpDir: mount.FileTypeBlockDev, + pathToFSType = map[string]hostutil.FileType{ + tmpDir: hostutil.FileTypeBlockDev, } } diff --git a/pkg/volume/plugins.go b/pkg/volume/plugins.go index 922e7403626..406168e9055 100644 --- a/pkg/volume/plugins.go +++ b/pkg/volume/plugins.go @@ -23,7 +23,7 @@ import ( "sync" authenticationv1 "k8s.io/api/authentication/v1" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -39,6 +39,7 @@ import ( "k8s.io/klog" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/util/mount" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/recyclerclient" "k8s.io/kubernetes/pkg/volume/util/subpath" ) @@ -341,8 +342,8 @@ type KubeletVolumeHost interface { CSIDriversSynced() cache.InformerSynced // WaitForCacheSync is a helper function that waits for cache sync for CSIDriverLister WaitForCacheSync() error - // Returns HostUtils Interface - GetHostUtil() mount.HostUtils + // Returns hostutil.HostUtils + GetHostUtil() hostutil.HostUtils } // AttachDetachVolumeHost is a AttachDetach Controller specific interface that plugins can use diff --git a/pkg/volume/testing/BUILD b/pkg/volume/testing/BUILD index 94a957466f1..42dfb176e76 100644 --- a/pkg/volume/testing/BUILD +++ b/pkg/volume/testing/BUILD @@ -16,6 +16,7 @@ go_library( "//pkg/util/mount:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/util:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/recyclerclient:go_default_library", "//pkg/volume/util/subpath:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library", diff --git a/pkg/volume/testing/testing.go b/pkg/volume/testing/testing.go index a61a0c6f8d9..c04143a543c 100644 --- a/pkg/volume/testing/testing.go +++ b/pkg/volume/testing/testing.go @@ -28,7 +28,7 @@ import ( "time" authenticationv1 "k8s.io/api/authentication/v1" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -43,6 +43,7 @@ import ( "k8s.io/kubernetes/pkg/util/mount" . "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/recyclerclient" "k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/pkg/volume/util/volumepathhandler" @@ -70,7 +71,7 @@ type fakeVolumeHost struct { pluginMgr VolumePluginMgr cloud cloudprovider.Interface mounter mount.Interface - hostUtil mount.HostUtils + hostUtil hostutil.HostUtils exec mount.Exec nodeLabels map[string]string nodeName string @@ -105,12 +106,10 @@ func NewFakeVolumeHostWithCSINodeName(rootDir string, kubeClient clientset.Inter return volHost } -func newFakeVolumeHost(rootDir string, kubeClient clientset.Interface, plugins []VolumePlugin, cloud cloudprovider.Interface, pathToTypeMap map[string]mount.FileType) *fakeVolumeHost { +func newFakeVolumeHost(rootDir string, kubeClient clientset.Interface, plugins []VolumePlugin, cloud cloudprovider.Interface, pathToTypeMap map[string]hostutil.FileType) *fakeVolumeHost { host := &fakeVolumeHost{rootDir: rootDir, kubeClient: kubeClient, cloud: cloud} host.mounter = &mount.FakeMounter{} - host.hostUtil = &mount.FakeHostUtil{ - Filesystem: pathToTypeMap, - } + host.hostUtil = hostutil.NewFakeHostUtil(pathToTypeMap) host.exec = mount.NewFakeExec(nil) host.pluginMgr.InitPlugins(plugins, nil /* prober */, host) host.subpather = &subpath.FakeSubpath{} @@ -118,7 +117,7 @@ func newFakeVolumeHost(rootDir string, kubeClient clientset.Interface, plugins [ return host } -func NewFakeVolumeHostWithMounterFSType(rootDir string, kubeClient clientset.Interface, plugins []VolumePlugin, pathToTypeMap map[string]mount.FileType) *fakeVolumeHost { +func NewFakeVolumeHostWithMounterFSType(rootDir string, kubeClient clientset.Interface, plugins []VolumePlugin, pathToTypeMap map[string]hostutil.FileType) *fakeVolumeHost { volHost := newFakeVolumeHost(rootDir, kubeClient, plugins, nil, pathToTypeMap) return volHost } @@ -159,7 +158,7 @@ func (f *fakeVolumeHost) GetMounter(pluginName string) mount.Interface { return f.mounter } -func (f *fakeVolumeHost) GetHostUtil() mount.HostUtils { +func (f *fakeVolumeHost) GetHostUtil() hostutil.HostUtils { return f.hostUtil } diff --git a/pkg/volume/util/BUILD b/pkg/volume/util/BUILD index a451cbb4396..55d9a2ecfbc 100644 --- a/pkg/volume/util/BUILD +++ b/pkg/volume/util/BUILD @@ -94,6 +94,7 @@ filegroup( "//pkg/volume/util/exec:all-srcs", "//pkg/volume/util/fs:all-srcs", "//pkg/volume/util/fsquota:all-srcs", + "//pkg/volume/util/hostutil:all-srcs", "//pkg/volume/util/nestedpendingoperations:all-srcs", "//pkg/volume/util/operationexecutor:all-srcs", "//pkg/volume/util/recyclerclient:all-srcs", diff --git a/pkg/volume/util/hostutil/BUILD b/pkg/volume/util/hostutil/BUILD new file mode 100644 index 00000000000..153d6a1e5d3 --- /dev/null +++ b/pkg/volume/util/hostutil/BUILD @@ -0,0 +1,57 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = [ + "fake_hostutil.go", + "hostutil.go", + "hostutil_linux.go", + "hostutil_unsupported.go", + "hostutil_windows.go", + ], + importpath = "k8s.io/kubernetes/pkg/volume/util/hostutil", + visibility = ["//visibility:public"], + deps = [ + "//pkg/util/mount:go_default_library", + ] + select({ + "@io_bazel_rules_go//go/platform:linux": [ + "//vendor/golang.org/x/sys/unix:go_default_library", + "//vendor/k8s.io/klog:go_default_library", + "//vendor/k8s.io/utils/path:go_default_library", + ], + "@io_bazel_rules_go//go/platform:windows": [ + "//vendor/k8s.io/klog:go_default_library", + "//vendor/k8s.io/utils/path:go_default_library", + ], + "//conditions:default": [], + }), +) + +go_test( + name = "go_default_test", + srcs = [ + "hostutil_linux_test.go", + "hostutil_windows_test.go", + ], + embed = [":go_default_library"], + deps = select({ + "@io_bazel_rules_go//go/platform:linux": [ + "//vendor/k8s.io/utils/exec:go_default_library", + ], + "//conditions:default": [], + }), +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/pkg/util/mount/fake_hostutil.go b/pkg/volume/util/hostutil/fake_hostutil.go similarity index 79% rename from pkg/util/mount/fake_hostutil.go rename to pkg/volume/util/hostutil/fake_hostutil.go index f00eb402c1e..d098e91a1b5 100644 --- a/pkg/util/mount/fake_hostutil.go +++ b/pkg/volume/util/hostutil/fake_hostutil.go @@ -14,22 +14,36 @@ See the License for the specific language governing permissions and limitations under the License. */ -package mount +package hostutil import ( "errors" "os" "sync" + + "k8s.io/kubernetes/pkg/util/mount" ) -// FakeHostUtil is a fake mount.HostUtils implementation for testing +// FakeHostUtil is a fake HostUtils implementation for testing type FakeHostUtil struct { - MountPoints []MountPoint + MountPoints []mount.MountPoint Filesystem map[string]FileType mutex sync.Mutex } +// NewFakeHostUtil returns a struct that implements the HostUtils interface +// for testing +// TODO: no callers were initializing the struct with any MountPoints. Check +// if those are still being used by any callers and if MountPoints still need +// to be a part of the struct. +func NewFakeHostUtil(fs map[string]FileType) *FakeHostUtil { + return &FakeHostUtil{ + Filesystem: fs, + } +} + +// Compile-time check to make sure FakeHostUtil implements interface var _ HostUtils = &FakeHostUtil{} // DeviceOpened checks if block device referenced by pathname is in use by @@ -52,7 +66,7 @@ func (hu *FakeHostUtil) PathIsDevice(pathname string) (bool, error) { } // GetDeviceNameFromMount given a mount point, find the volume id -func (hu *FakeHostUtil) GetDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) { +func (hu *FakeHostUtil) GetDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) { return getDeviceNameFromMount(mounter, mountPath, pluginMountDir) } diff --git a/pkg/util/mount/hostutil.go b/pkg/volume/util/hostutil/hostutil.go similarity index 92% rename from pkg/util/mount/hostutil.go rename to pkg/volume/util/hostutil/hostutil.go index 0e748065377..68e5c7e999c 100644 --- a/pkg/util/mount/hostutil.go +++ b/pkg/volume/util/hostutil/hostutil.go @@ -14,14 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -// TODO(thockin): This whole pkg is pretty linux-centric. As soon as we have -// an alternate platform, we will need to abstract further. - -package mount +package hostutil import ( "fmt" "os" + + "k8s.io/kubernetes/pkg/util/mount" ) // FileType enumerates the known set of possible file types. @@ -51,7 +50,7 @@ type HostUtils interface { PathIsDevice(pathname string) (bool, error) // GetDeviceNameFromMount finds the device name by checking the mount path // to get the global mount path within its plugin directory. - GetDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) + GetDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) // MakeRShared checks that given path is on a mount with 'rshared' mount // propagation. If not, it bind-mounts the path as rshared. MakeRShared(path string) error @@ -72,8 +71,8 @@ type HostUtils interface { } // Compile-time check to ensure all HostUtil implementations satisfy -// the HostUtils Interface. -var _ HostUtils = &hostUtil{} +// the Interface. +var _ HostUtils = &HostUtil{} // getFileType checks for file/directory/socket and block/character devices. func getFileType(pathname string) (FileType, error) { diff --git a/pkg/util/mount/hostutil_linux.go b/pkg/volume/util/hostutil/hostutil_linux.go similarity index 73% rename from pkg/util/mount/hostutil_linux.go rename to pkg/volume/util/hostutil/hostutil_linux.go index e60c4b22289..87979911fd9 100644 --- a/pkg/util/mount/hostutil_linux.go +++ b/pkg/volume/util/hostutil/hostutil_linux.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package mount +package hostutil import ( "fmt" @@ -27,17 +27,26 @@ import ( "syscall" "golang.org/x/sys/unix" + "k8s.io/klog" utilpath "k8s.io/utils/path" + + "k8s.io/kubernetes/pkg/util/mount" ) -type hostUtil struct { +const ( + // Location of the mountinfo file + procMountInfoPath = "/proc/self/mountinfo" +) + +// HostUtil implements HostUtils for Linux platforms. +type HostUtil struct { } // NewHostUtil returns a struct that implements the HostUtils interface on // linux platforms -func NewHostUtil() HostUtils { - return &hostUtil{} +func NewHostUtil() *HostUtil { + return &HostUtil{} } // DeviceOpened checks if block device in use by calling Open with O_EXCL flag. @@ -45,13 +54,13 @@ func NewHostUtil() HostUtils { // If open returns errno EBUSY, return true with nil error. // If open returns nil, return false with nil error. // Otherwise, return false with error -func (hu *hostUtil) DeviceOpened(pathname string) (bool, error) { +func (hu *HostUtil) DeviceOpened(pathname string) (bool, error) { return ExclusiveOpenFailsOnDevice(pathname) } // PathIsDevice uses FileInfo returned from os.Stat to check if path refers // to a device. -func (hu *hostUtil) PathIsDevice(pathname string) (bool, error) { +func (hu *HostUtil) PathIsDevice(pathname string) (bool, error) { pathType, err := hu.GetFileType(pathname) isDevice := pathType == FileTypeCharDev || pathType == FileTypeBlockDev return isDevice, err @@ -95,20 +104,15 @@ func ExclusiveOpenFailsOnDevice(pathname string) (bool, error) { return false, errno } -//GetDeviceNameFromMount: given a mount point, find the device name from its global mount point -func (hu *hostUtil) GetDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) { - return GetDeviceNameFromMountLinux(mounter, mountPath, pluginMountDir) +// GetDeviceNameFromMount given a mount point, find the device name from its global mount point +func (hu *HostUtil) GetDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) { + return getDeviceNameFromMount(mounter, mountPath, pluginMountDir) } -func getDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) { - return GetDeviceNameFromMountLinux(mounter, mountPath, pluginMountDir) -} - -// GetDeviceNameFromMountLinux find the device name from /proc/mounts in which +// getDeviceNameFromMountLinux find the device name from /proc/mounts in which // the mount path reference should match the given plugin mount directory. In case no mount path reference // matches, returns the volume name taken from its given mountPath -// This implementation is shared with NsEnterMounter -func GetDeviceNameFromMountLinux(mounter Interface, mountPath, pluginMountDir string) (string, error) { +func getDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) { refs, err := mounter.GetMountRefs(mountPath) if err != nil { klog.V(4).Infof("GetMountRefs failed for mount path %q: %v", mountPath, err) @@ -132,19 +136,27 @@ func GetDeviceNameFromMountLinux(mounter Interface, mountPath, pluginMountDir st return path.Base(mountPath), nil } -func (hu *hostUtil) MakeRShared(path string) error { +// MakeRShared checks that given path is on a mount with 'rshared' mount +// propagation. If not, it bind-mounts the path as rshared. +func (hu *HostUtil) MakeRShared(path string) error { return DoMakeRShared(path, procMountInfoPath) } -func (hu *hostUtil) GetFileType(pathname string) (FileType, error) { +// GetFileType checks for file/directory/socket/block/character devices. +func (hu *HostUtil) GetFileType(pathname string) (FileType, error) { return getFileType(pathname) } -func (hu *hostUtil) PathExists(pathname string) (bool, error) { +// PathExists tests if the given path already exists +// Error is returned on any other error than "file not found". +func (hu *HostUtil) PathExists(pathname string) (bool, error) { return utilpath.Exists(utilpath.CheckFollowSymlink, pathname) } -func (hu *hostUtil) EvalHostSymlinks(pathname string) (string, error) { +// EvalHostSymlinks returns the path name after evaluating symlinks. +// TODO once the nsenter implementation is removed, this method can be removed +// from the interface and filepath.EvalSymlinks used directly +func (hu *HostUtil) EvalHostSymlinks(pathname string) (string, error) { return filepath.EvalSymlinks(pathname) } @@ -157,7 +169,7 @@ func isShared(mount string, mountInfoPath string) (bool, error) { } // parse optional parameters - for _, opt := range info.optionalFields { + for _, opt := range info.OptionalFields { if strings.HasPrefix(opt, "shared:") { return true, nil } @@ -165,23 +177,23 @@ func isShared(mount string, mountInfoPath string) (bool, error) { return false, nil } -func findMountInfo(path, mountInfoPath string) (mountInfo, error) { - infos, err := parseMountInfo(mountInfoPath) +func findMountInfo(path, mountInfoPath string) (mount.MountInfo, error) { + infos, err := mount.ParseMountInfo(mountInfoPath) if err != nil { - return mountInfo{}, err + return mount.MountInfo{}, err } // process /proc/xxx/mountinfo in backward order and find the first mount // point that is prefix of 'path' - that's the mount where path resides - var info *mountInfo + var info *mount.MountInfo for i := len(infos) - 1; i >= 0; i-- { - if PathWithinBase(path, infos[i].mountPoint) { + if mount.PathWithinBase(path, infos[i].MountPoint) { info = &infos[i] break } } if info == nil { - return mountInfo{}, fmt.Errorf("cannot find mount point for %q", path) + return mount.MountInfo{}, fmt.Errorf("cannot find mount point for %q", path) } return *info, nil } @@ -222,12 +234,12 @@ func GetSELinux(path string, mountInfoFilename string) (bool, error) { } // "seclabel" can be both in mount options and super options. - for _, opt := range info.superOptions { + for _, opt := range info.SuperOptions { if opt == "seclabel" { return true, nil } } - for _, opt := range info.mountOptions { + for _, opt := range info.MountOptions { if opt == "seclabel" { return true, nil } @@ -235,12 +247,14 @@ func GetSELinux(path string, mountInfoFilename string) (bool, error) { return false, nil } -func (hu *hostUtil) GetSELinuxSupport(pathname string) (bool, error) { +// GetSELinuxSupport returns true if given path is on a mount that supports +// SELinux. +func (hu *HostUtil) GetSELinuxSupport(pathname string) (bool, error) { return GetSELinux(pathname, procMountInfoPath) } // GetOwner returns the integer ID for the user and group of the given path -func (hu *hostUtil) GetOwner(pathname string) (int64, int64, error) { +func (hu *HostUtil) GetOwner(pathname string) (int64, int64, error) { realpath, err := filepath.EvalSymlinks(pathname) if err != nil { return -1, -1, err @@ -248,7 +262,8 @@ func (hu *hostUtil) GetOwner(pathname string) (int64, int64, error) { return GetOwnerLinux(realpath) } -func (hu *hostUtil) GetMode(pathname string) (os.FileMode, error) { +// GetMode returns permissions of the path. +func (hu *HostUtil) GetMode(pathname string) (os.FileMode, error) { return GetModeLinux(pathname) } diff --git a/pkg/util/mount/hostutil_linux_test.go b/pkg/volume/util/hostutil/hostutil_linux_test.go similarity index 96% rename from pkg/util/mount/hostutil_linux_test.go rename to pkg/volume/util/hostutil/hostutil_linux_test.go index aec45afeb84..35fc96efe66 100644 --- a/pkg/util/mount/hostutil_linux_test.go +++ b/pkg/volume/util/hostutil/hostutil_linux_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package mount +package hostutil import ( "fmt" @@ -311,3 +311,17 @@ func isOperationNotPermittedError(err error) bool { } return false } + +func writeFile(content string) (string, string, error) { + tempDir, err := ioutil.TempDir("", "mounter_shared_test") + if err != nil { + return "", "", err + } + filename := filepath.Join(tempDir, "mountinfo") + err = ioutil.WriteFile(filename, []byte(content), 0600) + if err != nil { + os.RemoveAll(tempDir) + return "", "", err + } + return tempDir, filename, nil +} diff --git a/pkg/volume/util/hostutil/hostutil_unsupported.go b/pkg/volume/util/hostutil/hostutil_unsupported.go new file mode 100644 index 00000000000..a5e9081f919 --- /dev/null +++ b/pkg/volume/util/hostutil/hostutil_unsupported.go @@ -0,0 +1,102 @@ +// +build !linux,!windows + +/* +Copyright 2014 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package hostutil + +import ( + "errors" + "os" + + "k8s.io/kubernetes/pkg/util/mount" +) + +// HostUtil is an HostUtils implementation that allows compilation on +// unsupported platforms +type HostUtil struct{} + +// NewHostUtil returns a struct that implements the HostUtils interface on +// unsupported platforms +func NewHostUtil() *HostUtil { + return &HostUtil{} +} + +var errUnsupported = errors.New("volume/util/hostutil on this platform is not supported") + +// DeviceOpened always returns an error on unsupported platforms +func (hu *HostUtil) DeviceOpened(pathname string) (bool, error) { + return false, errUnsupported +} + +// PathIsDevice always returns an error on unsupported platforms +func (hu *HostUtil) PathIsDevice(pathname string) (bool, error) { + return true, errUnsupported +} + +// GetDeviceNameFromMount always returns an error on unsupported platforms +func (hu *HostUtil) GetDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) { + return getDeviceNameFromMount(mounter, mountPath, pluginMountDir) +} + +// MakeRShared always returns an error on unsupported platforms +func (hu *HostUtil) MakeRShared(path string) error { + return errUnsupported +} + +// GetFileType always returns an error on unsupported platforms +func (hu *HostUtil) GetFileType(pathname string) (FileType, error) { + return FileType("fake"), errUnsupported +} + +// MakeFile always returns an error on unsupported platforms +func (hu *HostUtil) MakeFile(pathname string) error { + return errUnsupported +} + +// MakeDir always returns an error on unsupported platforms +func (hu *HostUtil) MakeDir(pathname string) error { + return errUnsupported +} + +// PathExists always returns an error on unsupported platforms +func (hu *HostUtil) PathExists(pathname string) (bool, error) { + return true, errUnsupported +} + +// EvalHostSymlinks always returns an error on unsupported platforms +func (hu *HostUtil) EvalHostSymlinks(pathname string) (string, error) { + return "", errUnsupported +} + +// GetOwner always returns an error on unsupported platforms +func (hu *HostUtil) GetOwner(pathname string) (int64, int64, error) { + return -1, -1, errUnsupported +} + +// GetSELinuxSupport always returns an error on unsupported platforms +func (hu *HostUtil) GetSELinuxSupport(pathname string) (bool, error) { + return false, errUnsupported +} + +//GetMode always returns an error on unsupported platforms +func (hu *HostUtil) GetMode(pathname string) (os.FileMode, error) { + return 0, errUnsupported +} + +func getDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) { + return "", errUnsupported +} diff --git a/pkg/util/mount/hostutil_windows.go b/pkg/volume/util/hostutil/hostutil_windows.go similarity index 65% rename from pkg/util/mount/hostutil_windows.go rename to pkg/volume/util/hostutil/hostutil_windows.go index 87e9fc2e6c9..bb74e939e72 100644 --- a/pkg/util/mount/hostutil_windows.go +++ b/pkg/volume/util/hostutil/hostutil_windows.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package mount +package hostutil import ( "fmt" @@ -26,27 +26,28 @@ import ( "strings" "k8s.io/klog" - utilpath "k8s.io/utils/path" + + "k8s.io/kubernetes/pkg/util/mount" ) -type hostUtil struct{} +// HostUtil implements HostUtils for Windows platforms. +type HostUtil struct{} -// NewHostUtil returns a struct that implements the HostUtils interface on -// windows platforms -func NewHostUtil() HostUtils { - return &hostUtil{} +// NewHostUtil returns a struct that implements HostUtils on Windows platforms +func NewHostUtil() *HostUtil { + return &HostUtil{} } // GetDeviceNameFromMount given a mnt point, find the device -func (hu *hostUtil) GetDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) { +func (hu *HostUtil) GetDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) { return getDeviceNameFromMount(mounter, mountPath, pluginMountDir) } // getDeviceNameFromMount find the device(drive) name in which // the mount path reference should match the given plugin mount directory. In case no mount path reference // matches, returns the volume name taken from its given mountPath -func getDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) { +func getDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) { refs, err := mounter.GetMountRefs(mountPath) if err != nil { klog.V(4).Infof("GetMountRefs failed for mount path %q: %v", mountPath, err) @@ -55,10 +56,10 @@ func getDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) if len(refs) == 0 { return "", fmt.Errorf("directory %s is not mounted", mountPath) } - basemountPath := NormalizeWindowsPath(pluginMountDir) + basemountPath := mount.NormalizeWindowsPath(pluginMountDir) for _, ref := range refs { if strings.Contains(ref, basemountPath) { - volumeID, err := filepath.Rel(NormalizeWindowsPath(basemountPath), ref) + volumeID, err := filepath.Rel(mount.NormalizeWindowsPath(basemountPath), ref) if err != nil { klog.Errorf("Failed to get volume id from mount %s - %v", mountPath, err) return "", err @@ -71,49 +72,51 @@ func getDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) } // DeviceOpened determines if the device is in use elsewhere -func (hu *hostUtil) DeviceOpened(pathname string) (bool, error) { +func (hu *HostUtil) DeviceOpened(pathname string) (bool, error) { return false, nil } // PathIsDevice determines if a path is a device. -func (hu *hostUtil) PathIsDevice(pathname string) (bool, error) { +func (hu *HostUtil) PathIsDevice(pathname string) (bool, error) { return false, nil } // MakeRShared checks that given path is on a mount with 'rshared' mount // propagation. Empty implementation here. -func (hu *hostUtil) MakeRShared(path string) error { +func (hu *HostUtil) MakeRShared(path string) error { return nil } // GetFileType checks for sockets/block/character devices -func (hu *(hostUtil)) GetFileType(pathname string) (FileType, error) { +func (hu *(HostUtil)) GetFileType(pathname string) (FileType, error) { return getFileType(pathname) } // PathExists checks whether the path exists -func (hu *hostUtil) PathExists(pathname string) (bool, error) { +func (hu *HostUtil) PathExists(pathname string) (bool, error) { return utilpath.Exists(utilpath.CheckFollowSymlink, pathname) } // EvalHostSymlinks returns the path name after evaluating symlinks -func (hu *hostUtil) EvalHostSymlinks(pathname string) (string, error) { +func (hu *HostUtil) EvalHostSymlinks(pathname string) (string, error) { return filepath.EvalSymlinks(pathname) } // GetOwner returns the integer ID for the user and group of the given path // Note that on windows, it always returns 0. We actually don't set Group on // windows platform, see SetVolumeOwnership implementation. -func (hu *hostUtil) GetOwner(pathname string) (int64, int64, error) { +func (hu *HostUtil) GetOwner(pathname string) (int64, int64, error) { return -1, -1, nil } -func (hu *hostUtil) GetSELinuxSupport(pathname string) (bool, error) { - // Windows does not support SELinux. +// GetSELinuxSupport returns a boolean indicating support for SELinux. +// Windows does not support SELinux. +func (hu *HostUtil) GetSELinuxSupport(pathname string) (bool, error) { return false, nil } -func (hu *hostUtil) GetMode(pathname string) (os.FileMode, error) { +// GetMode returns permissions of the path. +func (hu *HostUtil) GetMode(pathname string) (os.FileMode, error) { info, err := os.Stat(pathname) if err != nil { return 0, err diff --git a/pkg/util/mount/hostutil_windows_test.go b/pkg/volume/util/hostutil/hostutil_windows_test.go similarity index 99% rename from pkg/util/mount/hostutil_windows_test.go rename to pkg/volume/util/hostutil/hostutil_windows_test.go index 1a17c05d29e..48d71c8558d 100644 --- a/pkg/util/mount/hostutil_windows_test.go +++ b/pkg/volume/util/hostutil/hostutil_windows_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package mount +package hostutil import ( "io/ioutil" diff --git a/pkg/volume/util/operationexecutor/BUILD b/pkg/volume/util/operationexecutor/BUILD index d97651eabbf..6204312d371 100644 --- a/pkg/volume/util/operationexecutor/BUILD +++ b/pkg/volume/util/operationexecutor/BUILD @@ -21,6 +21,7 @@ go_library( "//pkg/volume:go_default_library", "//pkg/volume/csi:go_default_library", "//pkg/volume/util:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/nestedpendingoperations:go_default_library", "//pkg/volume/util/types:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library", @@ -48,13 +49,13 @@ go_test( embed = [":go_default_library"], deps = [ "//pkg/features:go_default_library", - "//pkg/util/mount:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/awsebs:go_default_library", "//pkg/volume/csi:go_default_library", "//pkg/volume/csi/testing:go_default_library", "//pkg/volume/gcepd:go_default_library", "//pkg/volume/testing:go_default_library", + "//pkg/volume/util/hostutil:go_default_library", "//pkg/volume/util/types: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", diff --git a/pkg/volume/util/operationexecutor/fakegenerator.go b/pkg/volume/util/operationexecutor/fakegenerator.go index ca317acc85a..69c1ab693cc 100644 --- a/pkg/volume/util/operationexecutor/fakegenerator.go +++ b/pkg/volume/util/operationexecutor/fakegenerator.go @@ -19,10 +19,10 @@ package operationexecutor import ( "time" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" + "k8s.io/kubernetes/pkg/volume/util/hostutil" volumetypes "k8s.io/kubernetes/pkg/volume/util/types" ) @@ -64,7 +64,7 @@ func (f *fakeOGCounter) GenerateVolumesAreAttachedFunc(attachedVolumes []Attache return f.recordFuncCall("GenerateVolumesAreAttachedFunc"), nil } -func (f *fakeOGCounter) GenerateUnmountDeviceFunc(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, hu mount.HostUtils) (volumetypes.GeneratedOperations, error) { +func (f *fakeOGCounter) GenerateUnmountDeviceFunc(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, hu hostutil.HostUtils) (volumetypes.GeneratedOperations, error) { return f.recordFuncCall("GenerateUnmountDeviceFunc"), nil } @@ -80,7 +80,7 @@ func (f *fakeOGCounter) GenerateUnmapVolumeFunc(volumeToUnmount MountedVolume, a return f.recordFuncCall("GenerateUnmapVolumeFunc"), nil } -func (f *fakeOGCounter) GenerateUnmapDeviceFunc(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, hu mount.HostUtils) (volumetypes.GeneratedOperations, error) { +func (f *fakeOGCounter) GenerateUnmapDeviceFunc(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, hu hostutil.HostUtils) (volumetypes.GeneratedOperations, error) { return f.recordFuncCall("GenerateUnmapDeviceFunc"), nil } diff --git a/pkg/volume/util/operationexecutor/operation_executor.go b/pkg/volume/util/operationexecutor/operation_executor.go index a7480f718d0..b61d3d763be 100644 --- a/pkg/volume/util/operationexecutor/operation_executor.go +++ b/pkg/volume/util/operationexecutor/operation_executor.go @@ -26,13 +26,14 @@ import ( "k8s.io/klog" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/types" "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/csi" "k8s.io/kubernetes/pkg/volume/util" + "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/nestedpendingoperations" volumetypes "k8s.io/kubernetes/pkg/volume/util/types" "k8s.io/kubernetes/pkg/volume/util/volumepathhandler" @@ -124,7 +125,7 @@ type OperationExecutor interface { // global map path. If number of reference is zero, remove global map path // directory and free a volume for detach. // It then updates the actual state of the world to reflect that. - UnmountDevice(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, hostutil mount.HostUtils) error + UnmountDevice(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, hostutil hostutil.HostUtils) error // VerifyControllerAttachedVolume checks if the specified volume is present // in the specified nodes AttachedVolumes Status field. It uses kubeClient @@ -824,7 +825,7 @@ func (oe *operationExecutor) UnmountVolume( func (oe *operationExecutor) UnmountDevice( deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, - hostutil mount.HostUtils) error { + hostutil hostutil.HostUtils) error { fsVolume, err := util.CheckVolumeModeFilesystem(deviceToDetach.VolumeSpec) if err != nil { return err diff --git a/pkg/volume/util/operationexecutor/operation_executor_test.go b/pkg/volume/util/operationexecutor/operation_executor_test.go index eec9c975530..326f86c99d4 100644 --- a/pkg/volume/util/operationexecutor/operation_executor_test.go +++ b/pkg/volume/util/operationexecutor/operation_executor_test.go @@ -21,12 +21,12 @@ import ( "testing" "time" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/uuid" - "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" + "k8s.io/kubernetes/pkg/volume/util/hostutil" volumetypes "k8s.io/kubernetes/pkg/volume/util/types" ) @@ -433,7 +433,7 @@ func (fopg *fakeOperationGenerator) GenerateVolumesAreAttachedFunc(attachedVolum OperationFunc: opFunc, }, nil } -func (fopg *fakeOperationGenerator) GenerateUnmountDeviceFunc(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, hostutil mount.HostUtils) (volumetypes.GeneratedOperations, error) { +func (fopg *fakeOperationGenerator) GenerateUnmountDeviceFunc(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, hostutil hostutil.HostUtils) (volumetypes.GeneratedOperations, error) { opFunc := func() (error, error) { startOperationAndBlock(fopg.ch, fopg.quit) return nil, nil @@ -506,7 +506,7 @@ func (fopg *fakeOperationGenerator) GenerateUnmapVolumeFunc(volumeToUnmount Moun }, nil } -func (fopg *fakeOperationGenerator) GenerateUnmapDeviceFunc(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, hostutil mount.HostUtils) (volumetypes.GeneratedOperations, error) { +func (fopg *fakeOperationGenerator) GenerateUnmapDeviceFunc(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, hostutil hostutil.HostUtils) (volumetypes.GeneratedOperations, error) { opFunc := func() (error, error) { startOperationAndBlock(fopg.ch, fopg.quit) return nil, nil diff --git a/pkg/volume/util/operationexecutor/operation_generator.go b/pkg/volume/util/operationexecutor/operation_generator.go index f524341d0ac..ff864df2565 100644 --- a/pkg/volume/util/operationexecutor/operation_generator.go +++ b/pkg/volume/util/operationexecutor/operation_generator.go @@ -36,10 +36,10 @@ import ( "k8s.io/klog" "k8s.io/kubernetes/pkg/features" kevents "k8s.io/kubernetes/pkg/kubelet/events" - "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/csi" "k8s.io/kubernetes/pkg/volume/util" + "k8s.io/kubernetes/pkg/volume/util/hostutil" volumetypes "k8s.io/kubernetes/pkg/volume/util/types" "k8s.io/kubernetes/pkg/volume/util/volumepathhandler" ) @@ -106,7 +106,7 @@ type OperationGenerator interface { GenerateVolumesAreAttachedFunc(attachedVolumes []AttachedVolume, nodeName types.NodeName, actualStateOfWorld ActualStateOfWorldAttacherUpdater) (volumetypes.GeneratedOperations, error) // Generates the UnMountDevice function needed to perform the unmount of a device - GenerateUnmountDeviceFunc(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, mounter mount.HostUtils) (volumetypes.GeneratedOperations, error) + GenerateUnmountDeviceFunc(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, mounter hostutil.HostUtils) (volumetypes.GeneratedOperations, error) // Generates the function needed to check if the attach_detach controller has attached the volume plugin GenerateVerifyControllerAttachedVolumeFunc(volumeToMount VolumeToMount, nodeName types.NodeName, actualStateOfWorld ActualStateOfWorldAttacherUpdater) (volumetypes.GeneratedOperations, error) @@ -118,7 +118,7 @@ type OperationGenerator interface { GenerateUnmapVolumeFunc(volumeToUnmount MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater) (volumetypes.GeneratedOperations, error) // Generates the UnmapDevice function needed to perform the unmap of a device - GenerateUnmapDeviceFunc(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, mounter mount.HostUtils) (volumetypes.GeneratedOperations, error) + GenerateUnmapDeviceFunc(deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, mounter hostutil.HostUtils) (volumetypes.GeneratedOperations, error) // GetVolumePluginMgr returns volume plugin manager GetVolumePluginMgr() *volume.VolumePluginMgr @@ -860,7 +860,7 @@ func (og *operationGenerator) GenerateUnmountVolumeFunc( func (og *operationGenerator) GenerateUnmountDeviceFunc( deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, - hostutil mount.HostUtils) (volumetypes.GeneratedOperations, error) { + hostutil hostutil.HostUtils) (volumetypes.GeneratedOperations, error) { var pluginName string if useCSIPlugin(og.volumePluginMgr, deviceToDetach.VolumeSpec) { @@ -1244,7 +1244,7 @@ func (og *operationGenerator) GenerateUnmapVolumeFunc( func (og *operationGenerator) GenerateUnmapDeviceFunc( deviceToDetach AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, - hostutil mount.HostUtils) (volumetypes.GeneratedOperations, error) { + hostutil hostutil.HostUtils) (volumetypes.GeneratedOperations, error) { var blockVolumePlugin volume.BlockVolumePlugin var err error @@ -1779,7 +1779,7 @@ func checkNodeAffinity(og *operationGenerator, volumeToMount VolumeToMount) erro } // isDeviceOpened checks the device status if the device is in use anywhere else on the system -func isDeviceOpened(deviceToDetach AttachedVolume, hostUtil mount.HostUtils) (bool, error) { +func isDeviceOpened(deviceToDetach AttachedVolume, hostUtil hostutil.HostUtils) (bool, error) { isDevicePath, devicePathErr := hostUtil.PathIsDevice(deviceToDetach.DevicePath) var deviceOpened bool var deviceOpenedErr error