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.
This commit is contained in:
Travis Rhoden 2019-08-22 23:18:23 -06:00
parent e176e47719
commit 935c23f2ad
No known key found for this signature in database
GPG Key ID: 6B4B921EC4ECF91A
51 changed files with 496 additions and 364 deletions

View File

@ -107,6 +107,7 @@ go_library(
"//pkg/volume/scaleio:go_default_library", "//pkg/volume/scaleio:go_default_library",
"//pkg/volume/secret:go_default_library", "//pkg/volume/secret:go_default_library",
"//pkg/volume/storageos: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/util/subpath:go_default_library",
"//pkg/volume/vsphere_volume:go_default_library", "//pkg/volume/vsphere_volume:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",

View File

@ -97,6 +97,7 @@ import (
"k8s.io/kubernetes/pkg/util/rlimit" "k8s.io/kubernetes/pkg/util/rlimit"
"k8s.io/kubernetes/pkg/version" "k8s.io/kubernetes/pkg/version"
"k8s.io/kubernetes/pkg/version/verflag" "k8s.io/kubernetes/pkg/version/verflag"
"k8s.io/kubernetes/pkg/volume/util/hostutil"
"k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/pkg/volume/util/subpath"
"k8s.io/utils/exec" "k8s.io/utils/exec"
) )
@ -369,7 +370,7 @@ func UnsecuredDependencies(s *options.KubeletServer) (*kubelet.Dependencies, err
mounter := mount.New(s.ExperimentalMounterPath) mounter := mount.New(s.ExperimentalMounterPath)
subpather := subpath.New(mounter) subpather := subpath.New(mounter)
hu := mount.NewHostUtil() hu := hostutil.NewHostUtil()
var pluginRunner = exec.New() var pluginRunner = exec.New()
var dockerClientConfig *dockershim.ClientConfig var dockerClientConfig *dockershim.ClientConfig

View File

@ -112,6 +112,7 @@ go_library(
"//pkg/volume/csi:go_default_library", "//pkg/volume/csi:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/exec: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/subpath:go_default_library",
"//pkg/volume/util/types:go_default_library", "//pkg/volume/util/types:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library",
@ -220,6 +221,7 @@ go_test(
"//pkg/volume/hostpath:go_default_library", "//pkg/volume/hostpath:go_default_library",
"//pkg/volume/testing:go_default_library", "//pkg/volume/testing: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/subpath:go_default_library", "//pkg/volume/util/subpath: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",

View File

@ -117,6 +117,7 @@ import (
"k8s.io/kubernetes/pkg/util/selinux" "k8s.io/kubernetes/pkg/util/selinux"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/csi" "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/subpath"
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler" "k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
utilexec "k8s.io/utils/exec" utilexec "k8s.io/utils/exec"
@ -254,7 +255,7 @@ type Dependencies struct {
OnHeartbeatFailure func() OnHeartbeatFailure func()
KubeClient clientset.Interface KubeClient clientset.Interface
Mounter mount.Interface Mounter mount.Interface
HostUtil mount.HostUtils HostUtil hostutil.HostUtils
OOMAdjuster *oom.OOMAdjuster OOMAdjuster *oom.OOMAdjuster
OSInterface kubecontainer.OSInterface OSInterface kubecontainer.OSInterface
PodConfig *config.PodConfig PodConfig *config.PodConfig
@ -1105,7 +1106,7 @@ type Kubelet struct {
mounter mount.Interface mounter mount.Interface
// hostutil to interact with filesystems // hostutil to interact with filesystems
hostutil mount.HostUtils hostutil hostutil.HostUtils
// subpather to execute subpath actions // subpather to execute subpath actions
subpather subpath.Interface subpather subpath.Interface

View File

@ -59,8 +59,8 @@ import (
"k8s.io/kubernetes/pkg/kubelet/status" "k8s.io/kubernetes/pkg/kubelet/status"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/kubernetes/pkg/kubelet/util/format" "k8s.io/kubernetes/pkg/kubelet/util/format"
mountutil "k8s.io/kubernetes/pkg/util/mount"
volumeutil "k8s.io/kubernetes/pkg/volume/util" 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/subpath"
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler" "k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
volumevalidation "k8s.io/kubernetes/pkg/volume/validation" 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. // 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: // Kubernetes only mounts on /etc/hosts if:
// - container is not an infrastructure (pause) container // - container is not an infrastructure (pause) container
// - container is not already mounting on /etc/hosts // - container is not already mounting on /etc/hosts

View File

@ -22,13 +22,13 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "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" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
_ "k8s.io/kubernetes/pkg/apis/core/install" _ "k8s.io/kubernetes/pkg/apis/core/install"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/util/mount"
volumetest "k8s.io/kubernetes/pkg/volume/testing" volumetest "k8s.io/kubernetes/pkg/volume/testing"
"k8s.io/kubernetes/pkg/volume/util/hostutil"
"k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/pkg/volume/util/subpath"
) )
@ -241,7 +241,7 @@ func TestMakeMounts(t *testing.T) {
for name, tc := range testCases { for name, tc := range testCases {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
fhu := &mount.FakeHostUtil{} fhu := hostutil.NewFakeHostUtil(nil)
fsp := &subpath.FakeSubpath{} fsp := &subpath.FakeSubpath{}
pod := v1.Pod{ pod := v1.Pod{
Spec: v1.PodSpec{ Spec: v1.PodSpec{

View File

@ -27,7 +27,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
@ -48,12 +48,12 @@ import (
containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" containertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
"k8s.io/kubernetes/pkg/kubelet/server/portforward" "k8s.io/kubernetes/pkg/kubelet/server/portforward"
"k8s.io/kubernetes/pkg/kubelet/server/remotecommand" "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" "k8s.io/kubernetes/pkg/volume/util/subpath"
) )
func TestDisabledSubpath(t *testing.T) { func TestDisabledSubpath(t *testing.T) {
fhu := &mount.FakeHostUtil{} fhu := hostutil.NewFakeHostUtil(nil)
fsp := &subpath.FakeSubpath{} fsp := &subpath.FakeSubpath{}
pod := v1.Pod{ pod := v1.Pod{
Spec: v1.PodSpec{ Spec: v1.PodSpec{

View File

@ -20,9 +20,9 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" 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" "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{} fsp := &subpath.FakeSubpath{}
mounts, _, _ := makeMounts(&pod, "/pod", &container, "fakepodname", "", "", podVolumes, fhu, fsp, nil) mounts, _, _ := makeMounts(&pod, "/pod", &container, "fakepodname", "", "", podVolumes, fhu, fsp, nil)

View File

@ -76,6 +76,7 @@ import (
_ "k8s.io/kubernetes/pkg/volume/hostpath" _ "k8s.io/kubernetes/pkg/volume/hostpath"
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"
"k8s.io/kubernetes/pkg/volume/util/hostutil"
"k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/pkg/volume/util/subpath"
) )
@ -162,7 +163,7 @@ func newTestKubeletWithImageList(
kubelet.heartbeatClient = fakeKubeClient kubelet.heartbeatClient = fakeKubeClient
kubelet.os = &containertest.FakeOS{} kubelet.os = &containertest.FakeOS{}
kubelet.mounter = &mount.FakeMounter{} kubelet.mounter = &mount.FakeMounter{}
kubelet.hostutil = &mount.FakeHostUtil{} kubelet.hostutil = hostutil.NewFakeHostUtil(nil)
kubelet.subpather = &subpath.FakeSubpath{} kubelet.subpather = &subpath.FakeSubpath{}
kubelet.hostname = testKubeletHostname kubelet.hostname = testKubeletHostname

View File

@ -46,6 +46,7 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"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/hostutil"
) )
func TestRunOnce(t *testing.T) { func TestRunOnce(t *testing.T) {
@ -85,7 +86,7 @@ func TestRunOnce(t *testing.T) {
hostname: testKubeletHostname, hostname: testKubeletHostname,
nodeName: testKubeletHostname, nodeName: testKubeletHostname,
runtimeState: newRuntimeState(time.Second), runtimeState: newRuntimeState(time.Second),
hostutil: &mount.FakeHostUtil{}, hostutil: hostutil.NewFakeHostUtil(nil),
} }
kb.containerManager = cm.NewStubContainerManager() kb.containerManager = cm.NewStubContainerManager()

View File

@ -44,6 +44,7 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
execmnt "k8s.io/kubernetes/pkg/volume/util/exec" execmnt "k8s.io/kubernetes/pkg/volume/util/exec"
"k8s.io/kubernetes/pkg/volume/util/hostutil"
"k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/pkg/volume/util/subpath"
) )
@ -160,7 +161,7 @@ func (kvh *kubeletVolumeHost) GetSubpather() subpath.Interface {
return kvh.kubelet.subpather return kvh.kubelet.subpather
} }
func (kvh *kubeletVolumeHost) GetHostUtil() mount.HostUtils { func (kvh *kubeletVolumeHost) GetHostUtil() hostutil.HostUtils {
return kvh.kubelet.hostutil return kvh.kubelet.hostutil
} }

View File

@ -26,6 +26,7 @@ go_library(
"//pkg/util/mount:go_default_library", "//pkg/util/mount: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/hostutil:go_default_library",
"//pkg/volume/util/operationexecutor:go_default_library", "//pkg/volume/util/operationexecutor:go_default_library",
"//pkg/volume/util/types:go_default_library", "//pkg/volume/util/types:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library",
@ -58,6 +59,7 @@ go_test(
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/testing:go_default_library", "//pkg/volume/testing: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/types: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",

View File

@ -18,6 +18,7 @@ go_library(
"//pkg/util/mount:go_default_library", "//pkg/util/mount: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/hostutil:go_default_library",
"//pkg/volume/util/nestedpendingoperations:go_default_library", "//pkg/volume/util/nestedpendingoperations:go_default_library",
"//pkg/volume/util/operationexecutor:go_default_library", "//pkg/volume/util/operationexecutor:go_default_library",
"//pkg/volume/util/types:go_default_library", "//pkg/volume/util/types:go_default_library",
@ -44,6 +45,7 @@ go_test(
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/testing:go_default_library", "//pkg/volume/testing: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/operationexecutor:go_default_library", "//pkg/volume/util/operationexecutor: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

@ -26,7 +26,7 @@ import (
"path" "path"
"time" "time"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
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"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
@ -40,6 +40,7 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
volumepkg "k8s.io/kubernetes/pkg/volume" volumepkg "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/nestedpendingoperations" "k8s.io/kubernetes/pkg/volume/util/nestedpendingoperations"
"k8s.io/kubernetes/pkg/volume/util/operationexecutor" "k8s.io/kubernetes/pkg/volume/util/operationexecutor"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types" volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
@ -100,7 +101,7 @@ func NewReconciler(
populatorHasAddedPods func() bool, populatorHasAddedPods func() bool,
operationExecutor operationexecutor.OperationExecutor, operationExecutor operationexecutor.OperationExecutor,
mounter mount.Interface, mounter mount.Interface,
hostutil mount.HostUtils, hostutil hostutil.HostUtils,
volumePluginMgr *volumepkg.VolumePluginMgr, volumePluginMgr *volumepkg.VolumePluginMgr,
kubeletPodsDir string) Reconciler { kubeletPodsDir string) Reconciler {
return &reconciler{ return &reconciler{
@ -132,7 +133,7 @@ type reconciler struct {
populatorHasAddedPods func() bool populatorHasAddedPods func() bool
operationExecutor operationexecutor.OperationExecutor operationExecutor operationexecutor.OperationExecutor
mounter mount.Interface mounter mount.Interface
hostutil mount.HostUtils hostutil hostutil.HostUtils
volumePluginMgr *volumepkg.VolumePluginMgr volumePluginMgr *volumepkg.VolumePluginMgr
kubeletPodsDir string kubeletPodsDir string
timeOfLastSync time.Time timeOfLastSync time.Time

View File

@ -22,7 +22,7 @@ import (
"time" "time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"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/runtime" "k8s.io/apimachinery/pkg/runtime"
@ -40,6 +40,7 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumetesting "k8s.io/kubernetes/pkg/volume/testing" volumetesting "k8s.io/kubernetes/pkg/volume/testing"
"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/operationexecutor" "k8s.io/kubernetes/pkg/volume/util/operationexecutor"
) )
@ -84,7 +85,7 @@ func Test_Run_Positive_DoNothing(t *testing.T) {
hasAddedPods, hasAddedPods,
oex, oex,
&mount.FakeMounter{}, &mount.FakeMounter{},
&mount.FakeHostUtil{}, hostutil.NewFakeHostUtil(nil),
volumePluginMgr, volumePluginMgr,
kubeletPodsDir) kubeletPodsDir)
@ -128,7 +129,7 @@ func Test_Run_Positive_VolumeAttachAndMount(t *testing.T) {
hasAddedPods, hasAddedPods,
oex, oex,
&mount.FakeMounter{}, &mount.FakeMounter{},
&mount.FakeHostUtil{}, hostutil.NewFakeHostUtil(nil),
volumePluginMgr, volumePluginMgr,
kubeletPodsDir) kubeletPodsDir)
pod := &v1.Pod{ pod := &v1.Pod{
@ -206,7 +207,7 @@ func Test_Run_Positive_VolumeMountControllerAttachEnabled(t *testing.T) {
hasAddedPods, hasAddedPods,
oex, oex,
&mount.FakeMounter{}, &mount.FakeMounter{},
&mount.FakeHostUtil{}, hostutil.NewFakeHostUtil(nil),
volumePluginMgr, volumePluginMgr,
kubeletPodsDir) kubeletPodsDir)
pod := &v1.Pod{ pod := &v1.Pod{
@ -285,7 +286,7 @@ func Test_Run_Positive_VolumeAttachMountUnmountDetach(t *testing.T) {
hasAddedPods, hasAddedPods,
oex, oex,
&mount.FakeMounter{}, &mount.FakeMounter{},
&mount.FakeHostUtil{}, hostutil.NewFakeHostUtil(nil),
volumePluginMgr, volumePluginMgr,
kubeletPodsDir) kubeletPodsDir)
pod := &v1.Pod{ pod := &v1.Pod{
@ -375,7 +376,7 @@ func Test_Run_Positive_VolumeUnmountControllerAttachEnabled(t *testing.T) {
hasAddedPods, hasAddedPods,
oex, oex,
&mount.FakeMounter{}, &mount.FakeMounter{},
&mount.FakeHostUtil{}, hostutil.NewFakeHostUtil(nil),
volumePluginMgr, volumePluginMgr,
kubeletPodsDir) kubeletPodsDir)
pod := &v1.Pod{ pod := &v1.Pod{
@ -502,7 +503,7 @@ func Test_Run_Positive_VolumeAttachAndMap(t *testing.T) {
hasAddedPods, hasAddedPods,
oex, oex,
&mount.FakeMounter{}, &mount.FakeMounter{},
&mount.FakeHostUtil{}, hostutil.NewFakeHostUtil(nil),
volumePluginMgr, volumePluginMgr,
kubeletPodsDir) kubeletPodsDir)
@ -608,7 +609,7 @@ func Test_Run_Positive_BlockVolumeMapControllerAttachEnabled(t *testing.T) {
hasAddedPods, hasAddedPods,
oex, oex,
&mount.FakeMounter{}, &mount.FakeMounter{},
&mount.FakeHostUtil{}, hostutil.NewFakeHostUtil(nil),
volumePluginMgr, volumePluginMgr,
kubeletPodsDir) kubeletPodsDir)
@ -709,7 +710,7 @@ func Test_Run_Positive_BlockVolumeAttachMapUnmapDetach(t *testing.T) {
hasAddedPods, hasAddedPods,
oex, oex,
&mount.FakeMounter{}, &mount.FakeMounter{},
&mount.FakeHostUtil{}, hostutil.NewFakeHostUtil(nil),
volumePluginMgr, volumePluginMgr,
kubeletPodsDir) kubeletPodsDir)
@ -823,7 +824,7 @@ func Test_Run_Positive_VolumeUnmapControllerAttachEnabled(t *testing.T) {
hasAddedPods, hasAddedPods,
oex, oex,
&mount.FakeMounter{}, &mount.FakeMounter{},
&mount.FakeHostUtil{}, hostutil.NewFakeHostUtil(nil),
volumePluginMgr, volumePluginMgr,
kubeletPodsDir) kubeletPodsDir)
@ -993,7 +994,7 @@ func Test_GenerateUnmapDeviceFunc_Plugin_Not_Found(t *testing.T) {
nil, /* fakeRecorder */ nil, /* fakeRecorder */
false, /* checkNodeCapabilitiesBeforeMount */ false, /* checkNodeCapabilitiesBeforeMount */
nil)) nil))
var hostutil mount.HostUtils var hostutil hostutil.HostUtils
volumeMode := v1.PersistentVolumeBlock volumeMode := v1.PersistentVolumeBlock
tmpSpec := &volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{VolumeMode: &volumeMode}}} tmpSpec := &volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{VolumeMode: &volumeMode}}}
deviceToDetach := operationexecutor.AttachedVolume{VolumeSpec: tmpSpec, PluginName: "fake-file-plugin"} deviceToDetach := operationexecutor.AttachedVolume{VolumeSpec: tmpSpec, PluginName: "fake-file-plugin"}
@ -1096,7 +1097,7 @@ func Test_Run_Positive_VolumeFSResizeControllerAttachEnabled(t *testing.T) {
hasAddedPods, hasAddedPods,
oex, oex,
&mount.FakeMounter{}, &mount.FakeMounter{},
&mount.FakeHostUtil{}, hostutil.NewFakeHostUtil(nil),
volumePluginMgr, volumePluginMgr,
kubeletPodsDir) kubeletPodsDir)
@ -1278,7 +1279,7 @@ func Test_Run_Positive_VolumeMountControllerAttachEnabledRace(t *testing.T) {
hasAddedPods, hasAddedPods,
oex, oex,
&mount.FakeMounter{}, &mount.FakeMounter{},
&mount.FakeHostUtil{}, hostutil.NewFakeHostUtil(nil),
volumePluginMgr, volumePluginMgr,
kubeletPodsDir) kubeletPodsDir)
pod := &v1.Pod{ pod := &v1.Pod{

View File

@ -44,6 +44,7 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"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/operationexecutor" "k8s.io/kubernetes/pkg/volume/util/operationexecutor"
"k8s.io/kubernetes/pkg/volume/util/types" "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler" "k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
@ -153,7 +154,7 @@ func NewVolumeManager(
volumePluginMgr *volume.VolumePluginMgr, volumePluginMgr *volume.VolumePluginMgr,
kubeContainerRuntime container.Runtime, kubeContainerRuntime container.Runtime,
mounter mount.Interface, mounter mount.Interface,
hostutil mount.HostUtils, hostutil hostutil.HostUtils,
kubeletPodsDir string, kubeletPodsDir string,
recorder record.EventRecorder, recorder record.EventRecorder,
checkNodeCapabilitiesBeforeMount bool, checkNodeCapabilitiesBeforeMount bool,

View File

@ -46,6 +46,7 @@ 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"
"k8s.io/kubernetes/pkg/volume/util/hostutil"
"k8s.io/kubernetes/pkg/volume/util/types" "k8s.io/kubernetes/pkg/volume/util/types"
) )
@ -301,7 +302,7 @@ func newTestVolumeManager(tmpDir string, podManager kubepod.Manager, kubeClient
plugMgr, plugMgr,
&containertest.FakeRuntime{}, &containertest.FakeRuntime{},
&mount.FakeMounter{}, &mount.FakeMounter{},
&mount.FakeHostUtil{}, hostutil.NewFakeHostUtil(nil),
"", "",
fakeRecorder, fakeRecorder,
false, /* experimentalCheckNodeCapabilitiesBeforeMount */ false, /* experimentalCheckNodeCapabilitiesBeforeMount */

View File

@ -35,6 +35,7 @@ go_library(
"//pkg/volume/emptydir:go_default_library", "//pkg/volume/emptydir:go_default_library",
"//pkg/volume/projected:go_default_library", "//pkg/volume/projected:go_default_library",
"//pkg/volume/secret:go_default_library", "//pkg/volume/secret:go_default_library",
"//pkg/volume/util/hostutil:go_default_library",
"//pkg/volume/util/subpath:go_default_library", "//pkg/volume/util/subpath: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

@ -36,6 +36,7 @@ import (
"k8s.io/kubernetes/pkg/volume/emptydir" "k8s.io/kubernetes/pkg/volume/emptydir"
"k8s.io/kubernetes/pkg/volume/projected" "k8s.io/kubernetes/pkg/volume/projected"
"k8s.io/kubernetes/pkg/volume/secret" "k8s.io/kubernetes/pkg/volume/secret"
"k8s.io/kubernetes/pkg/volume/util/hostutil"
"k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/pkg/volume/util/subpath"
"k8s.io/kubernetes/test/utils" "k8s.io/kubernetes/test/utils"
@ -75,7 +76,7 @@ func NewHollowKubelet(
OOMAdjuster: oom.NewFakeOOMAdjuster(), OOMAdjuster: oom.NewFakeOOMAdjuster(),
Mounter: mount.New("" /* default mount path */), Mounter: mount.New("" /* default mount path */),
Subpather: &subpath.FakeSubpath{}, Subpather: &subpath.FakeSubpath{},
HostUtil: &mount.FakeHostUtil{}, HostUtil: hostutil.NewFakeHostUtil(nil),
} }
return &HollowKubelet{ return &HollowKubelet{

View File

@ -6,11 +6,6 @@ go_library(
"doc.go", "doc.go",
"exec.go", "exec.go",
"fake.go", "fake.go",
"fake_hostutil.go",
"hostutil.go",
"hostutil_linux.go",
"hostutil_unsupported.go",
"hostutil_windows.go",
"mount.go", "mount.go",
"mount_helper_common.go", "mount_helper_common.go",
"mount_helper_unix.go", "mount_helper_unix.go",
@ -38,9 +33,7 @@ go_library(
"//vendor/k8s.io/utils/io:go_default_library", "//vendor/k8s.io/utils/io:go_default_library",
], ],
"@io_bazel_rules_go//go/platform:linux": [ "@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/io:go_default_library",
"//vendor/k8s.io/utils/path:go_default_library",
], ],
"@io_bazel_rules_go//go/platform:nacl": [ "@io_bazel_rules_go//go/platform:nacl": [
"//vendor/k8s.io/utils/io:go_default_library", "//vendor/k8s.io/utils/io:go_default_library",
@ -68,8 +61,6 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = [
"hostutil_linux_test.go",
"hostutil_windows_test.go",
"mount_helper_test.go", "mount_helper_test.go",
"mount_helper_unix_test.go", "mount_helper_unix_test.go",
"mount_helper_windows_test.go", "mount_helper_windows_test.go",
@ -82,9 +73,6 @@ go_test(
deps = [ deps = [
"//vendor/k8s.io/utils/exec/testing:go_default_library", "//vendor/k8s.io/utils/exec/testing:go_default_library",
] + select({ ] + select({
"@io_bazel_rules_go//go/platform:linux": [
"//vendor/k8s.io/utils/exec:go_default_library",
],
"@io_bazel_rules_go//go/platform:windows": [ "@io_bazel_rules_go//go/platform:windows": [
"//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",
], ],

View File

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

View File

@ -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. // Resolve any symlinks in file, kernel would do the same and use the resolved path in /proc/mounts.
hu := NewHostUtil() resolvedFile, err := filepath.EvalSymlinks(file)
resolvedFile, err := hu.EvalHostSymlinks(file)
if err != nil { if err != nil {
return true, err return true, err
} }

View File

@ -55,38 +55,38 @@ func IsCorruptedMnt(err error) bool {
return underlyingError == syscall.ENOTCONN || underlyingError == syscall.ESTALE || underlyingError == syscall.EIO || underlyingError == syscall.EACCES return underlyingError == syscall.ENOTCONN || underlyingError == syscall.ESTALE || underlyingError == syscall.EIO || underlyingError == syscall.EACCES
} }
// This represents a single line in /proc/<pid>/mountinfo. // MountInfo represents a single line in /proc/<pid>/mountinfo.
type mountInfo struct { type MountInfo struct {
// Unique ID for the mount (maybe reused after umount). // 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). // 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. // 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. // 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. // Mount source, filesystem-specific information. e.g. device, tmpfs name.
source string Source string
// Mount point, the pathname of the mount point. // Mount point, the pathname of the mount point.
mountPoint string MountPoint string
// Optional fieds, zero or more fields of the form "tag[:value]". // Optional fieds, zero or more fields of the form "tag[:value]".
optionalFields []string OptionalFields []string
// The filesystem type in the form "type[.subtype]". // The filesystem type in the form "type[.subtype]".
fsType string FsType string
// Per-mount options. // Per-mount options.
mountOptions []string MountOptions []string
// Per-superblock options. // Per-superblock options.
superOptions []string SuperOptions []string
} }
// parseMountInfo parses /proc/xxx/mountinfo. // ParseMountInfo parses /proc/xxx/mountinfo.
func parseMountInfo(filename string) ([]mountInfo, error) { func ParseMountInfo(filename string) ([]MountInfo, error) {
content, err := utilio.ConsistentRead(filename, maxListTries) content, err := utilio.ConsistentRead(filename, maxListTries)
if err != nil { if err != nil {
return []mountInfo{}, err return []MountInfo{}, err
} }
contentStr := string(content) contentStr := string(content)
infos := []mountInfo{} infos := []MountInfo{}
for _, line := range strings.Split(contentStr, "\n") { for _, line := range strings.Split(contentStr, "\n") {
if line == "" { if line == "" {
@ -106,27 +106,27 @@ func parseMountInfo(filename string) ([]mountInfo, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
info := mountInfo{ info := MountInfo{
id: id, ID: id,
parentID: parentID, ParentID: parentID,
majorMinor: fields[2], MajorMinor: fields[2],
root: fields[3], Root: fields[3],
mountPoint: fields[4], MountPoint: fields[4],
mountOptions: strings.Split(fields[5], ","), MountOptions: strings.Split(fields[5], ","),
} }
// All fields until "-" are "optional fields". // All fields until "-" are "optional fields".
i := 6 i := 6
for ; i < len(fields) && fields[i] != "-"; i++ { 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. // Parse the rest 3 fields.
i++ i++
if len(fields)-i < 3 { if len(fields)-i < 3 {
return nil, fmt.Errorf("expect 3 fields in %s, got %d", line, len(fields)-i) return nil, fmt.Errorf("expect 3 fields in %s, got %d", line, len(fields)-i)
} }
info.fsType = fields[i] info.FsType = fields[i]
info.source = fields[i+1] info.Source = fields[i+1]
info.superOptions = strings.Split(fields[i+2], ",") info.SuperOptions = strings.Split(fields[i+2], ",")
infos = append(infos, info) infos = append(infos, info)
} }
return infos, nil return infos, nil

View File

@ -92,107 +92,107 @@ func TestParseMountInfo(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
id int id int
expectedInfo mountInfo expectedInfo MountInfo
}{ }{
{ {
"simple bind mount", "simple bind mount",
189, 189,
mountInfo{ MountInfo{
id: 189, ID: 189,
parentID: 80, ParentID: 80,
majorMinor: "8:1", MajorMinor: "8:1",
root: "/var/lib/kubelet", Root: "/var/lib/kubelet",
source: "/dev/sda1", Source: "/dev/sda1",
mountPoint: "/var/lib/kubelet", MountPoint: "/var/lib/kubelet",
optionalFields: []string{"shared:30"}, OptionalFields: []string{"shared:30"},
fsType: "ext4", FsType: "ext4",
mountOptions: []string{"rw", "relatime"}, MountOptions: []string{"rw", "relatime"},
superOptions: []string{"rw", "commit=30", "data=ordered"}, SuperOptions: []string{"rw", "commit=30", "data=ordered"},
}, },
}, },
{ {
"bind mount a directory", "bind mount a directory",
222, 222,
mountInfo{ MountInfo{
id: 222, ID: 222,
parentID: 24, ParentID: 24,
majorMinor: "253:0", MajorMinor: "253:0",
root: "/tmp/src", Root: "/tmp/src",
source: "/dev/mapper/vagrant--vg-root", Source: "/dev/mapper/vagrant--vg-root",
mountPoint: "/mnt/dst", MountPoint: "/mnt/dst",
optionalFields: []string{"shared:1"}, OptionalFields: []string{"shared:1"},
fsType: "ext4", FsType: "ext4",
mountOptions: []string{"rw", "relatime"}, MountOptions: []string{"rw", "relatime"},
superOptions: []string{"rw", "errors=remount-ro", "data=ordered"}, SuperOptions: []string{"rw", "errors=remount-ro", "data=ordered"},
}, },
}, },
{ {
"more than one optional fields", "more than one optional fields",
224, 224,
mountInfo{ MountInfo{
id: 224, ID: 224,
parentID: 62, ParentID: 62,
majorMinor: "253:0", MajorMinor: "253:0",
root: "/var/lib/docker/devicemapper/test/shared", Root: "/var/lib/docker/devicemapper/test/shared",
source: "/dev/mapper/ssd-root", Source: "/dev/mapper/ssd-root",
mountPoint: "/var/lib/docker/devicemapper/test/shared", MountPoint: "/var/lib/docker/devicemapper/test/shared",
optionalFields: []string{"master:1", "shared:44"}, OptionalFields: []string{"master:1", "shared:44"},
fsType: "ext4", FsType: "ext4",
mountOptions: []string{"rw", "relatime"}, MountOptions: []string{"rw", "relatime"},
superOptions: []string{"rw", "seclabel", "data=ordered"}, SuperOptions: []string{"rw", "seclabel", "data=ordered"},
}, },
}, },
{ {
"cgroup-mountpoint", "cgroup-mountpoint",
28, 28,
mountInfo{ MountInfo{
id: 28, ID: 28,
parentID: 18, ParentID: 18,
majorMinor: "0:24", MajorMinor: "0:24",
root: "/", Root: "/",
source: "tmpfs", Source: "tmpfs",
mountPoint: "/sys/fs/cgroup", MountPoint: "/sys/fs/cgroup",
optionalFields: []string{"shared:9"}, OptionalFields: []string{"shared:9"},
fsType: "tmpfs", FsType: "tmpfs",
mountOptions: []string{"ro", "nosuid", "nodev", "noexec"}, MountOptions: []string{"ro", "nosuid", "nodev", "noexec"},
superOptions: []string{"ro", "mode=755"}, SuperOptions: []string{"ro", "mode=755"},
}, },
}, },
{ {
"cgroup-subsystem-systemd-mountpoint", "cgroup-subsystem-systemd-mountpoint",
29, 29,
mountInfo{ MountInfo{
id: 29, ID: 29,
parentID: 28, ParentID: 28,
majorMinor: "0:25", MajorMinor: "0:25",
root: "/", Root: "/",
source: "cgroup", Source: "cgroup",
mountPoint: "/sys/fs/cgroup/systemd", MountPoint: "/sys/fs/cgroup/systemd",
optionalFields: []string{"shared:10"}, OptionalFields: []string{"shared:10"},
fsType: "cgroup", FsType: "cgroup",
mountOptions: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}, MountOptions: []string{"rw", "nosuid", "nodev", "noexec", "relatime"},
superOptions: []string{"rw", "xattr", "release_agent=/lib/systemd/systemd-cgroups-agent", "name=systemd"}, SuperOptions: []string{"rw", "xattr", "release_agent=/lib/systemd/systemd-cgroups-agent", "name=systemd"},
}, },
}, },
{ {
"cgroup-subsystem-cpuset-mountpoint", "cgroup-subsystem-cpuset-mountpoint",
31, 31,
mountInfo{ MountInfo{
id: 31, ID: 31,
parentID: 28, ParentID: 28,
majorMinor: "0:27", MajorMinor: "0:27",
root: "/", Root: "/",
source: "cgroup", Source: "cgroup",
mountPoint: "/sys/fs/cgroup/cpuset", MountPoint: "/sys/fs/cgroup/cpuset",
optionalFields: []string{"shared:13"}, OptionalFields: []string{"shared:13"},
fsType: "cgroup", FsType: "cgroup",
mountOptions: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}, MountOptions: []string{"rw", "nosuid", "nodev", "noexec", "relatime"},
superOptions: []string{"rw", "cpuset"}, SuperOptions: []string{"rw", "cpuset"},
}, },
}, },
} }
infos, err := parseMountInfo(filename) infos, err := ParseMountInfo(filename)
if err != nil { if err != nil {
t.Fatalf("Cannot parse %s: %s", filename, err) t.Fatalf("Cannot parse %s: %s", filename, err)
} }
@ -200,7 +200,7 @@ func TestParseMountInfo(t *testing.T) {
for _, test := range tests { for _, test := range tests {
found := false found := false
for _, info := range infos { for _, info := range infos {
if info.id == test.id { if info.ID == test.id {
found = true found = true
if !reflect.DeepEqual(info, test.expectedInfo) { if !reflect.DeepEqual(info, test.expectedInfo) {
t.Errorf("Test case %q:\n expected: %+v\n got: %+v", test.name, test.expectedInfo, info) t.Errorf("Test case %q:\n expected: %+v\n got: %+v", test.name, test.expectedInfo, info)

View File

@ -447,7 +447,7 @@ func parseProcMounts(content []byte) ([]MountPoint, error) {
// root path and major:minor to represent mount source uniquely. // root path and major:minor to represent mount source uniquely.
// This implementation is shared between Linux and NsEnterMounter // This implementation is shared between Linux and NsEnterMounter
func SearchMountPoints(hostSource, mountInfoPath string) ([]string, error) { func SearchMountPoints(hostSource, mountInfoPath string) ([]string, error) {
mis, err := parseMountInfo(mountInfoPath) mis, err := ParseMountInfo(mountInfoPath)
if err != nil { if err != nil {
return nil, err 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 // We need search in backward order because it's possible for later mounts
// to overlap earlier mounts. // to overlap earlier mounts.
for i := len(mis) - 1; i >= 0; i-- { 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. // If it's a mount point or path under a mount point.
mountID = mis[i].id mountID = mis[i].ID
rootPath = filepath.Join(mis[i].root, strings.TrimPrefix(hostSource, mis[i].mountPoint)) rootPath = filepath.Join(mis[i].Root, strings.TrimPrefix(hostSource, mis[i].MountPoint))
majorMinor = mis[i].majorMinor majorMinor = mis[i].MajorMinor
break break
} }
} }
@ -475,12 +475,12 @@ func SearchMountPoints(hostSource, mountInfoPath string) ([]string, error) {
var refs []string var refs []string
for i := range mis { for i := range mis {
if mis[i].id == mountID { if mis[i].ID == mountID {
// Ignore mount entry for mount source itself. // Ignore mount entry for mount source itself.
continue continue
} }
if mis[i].root == rootPath && mis[i].majorMinor == majorMinor { if mis[i].Root == rootPath && mis[i].MajorMinor == majorMinor {
refs = append(refs, mis[i].mountPoint) refs = append(refs, mis[i].MountPoint)
} }
} }

View File

@ -70,7 +70,3 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) { func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) {
return true, errUnsupported return true, errUnsupported
} }
func getDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) {
return "", errUnsupported
}

View File

@ -27,6 +27,7 @@ import (
"k8s.io/klog" "k8s.io/klog"
"k8s.io/utils/keymutex" "k8s.io/utils/keymutex"
utilpath "k8s.io/utils/path"
) )
// Mounter provides the default implementation of mount.Interface // Mounter provides the default implementation of mount.Interface
@ -176,8 +177,7 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
if err != nil { if err != nil {
return true, fmt.Errorf("readlink error: %v", err) return true, fmt.Errorf("readlink error: %v", err)
} }
hu := NewHostUtil() exists, err := utilpath.Exists(utilpath.CheckFollowSymlink, target)
exists, err := hu.PathExists(target)
if err != nil { if err != nil {
return true, err return true, err
} }

View File

@ -21,6 +21,7 @@ go_library(
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/util/mount:go_default_library", "//pkg/util/mount:go_default_library",
"//pkg/volume/util/fs: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/recyclerclient:go_default_library",
"//pkg/volume/util/subpath:go_default_library", "//pkg/volume/util/subpath:go_default_library",
"//staging/src/k8s.io/api/authentication/v1:go_default_library", "//staging/src/k8s.io/api/authentication/v1:go_default_library",

View File

@ -17,6 +17,7 @@ go_library(
"//pkg/util/mount:go_default_library", "//pkg/util/mount: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/hostutil:go_default_library",
"//pkg/volume/util/recyclerclient:go_default_library", "//pkg/volume/util/recyclerclient: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",
@ -31,9 +32,9 @@ go_test(
srcs = ["host_path_test.go"], srcs = ["host_path_test.go"],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/util/mount:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/testing: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/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

@ -28,6 +28,7 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"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/recyclerclient" "k8s.io/kubernetes/pkg/volume/util/recyclerclient"
"k8s.io/kubernetes/pkg/volume/validation" "k8s.io/kubernetes/pkg/volume/validation"
) )
@ -207,7 +208,7 @@ type hostPathMounter struct {
*hostPath *hostPath
readOnly bool readOnly bool
mounter mount.Interface mounter mount.Interface
hu mount.HostUtils hu hostutil.HostUtils
} }
var _ volume.Mounter = &hostPathMounter{} var _ volume.Mounter = &hostPathMounter{}
@ -361,7 +362,7 @@ type hostPathTypeChecker interface {
type fileTypeChecker struct { type fileTypeChecker struct {
path string path string
exists bool exists bool
hu mount.HostUtils hu hostutil.HostUtils
} }
func (ftc *fileTypeChecker) Exists() bool { func (ftc *fileTypeChecker) Exists() bool {
@ -423,12 +424,12 @@ func (ftc *fileTypeChecker) GetPath() string {
return ftc.path 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} return &fileTypeChecker{path: path, hu: hu}
} }
// checkType checks whether the given path is the exact pathType // 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) return checkTypeInternal(newFileTypeChecker(path, hu), pathType)
} }

View File

@ -21,15 +21,15 @@ import (
"os" "os"
"testing" "testing"
"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"
"k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
utilmount "k8s.io/kubernetes/pkg/util/mount"
"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/hostutil"
utilpath "k8s.io/utils/path" utilpath "k8s.io/utils/path"
) )
@ -358,13 +358,13 @@ func TestOSFileTypeChecker(t *testing.T) {
{ {
name: "Existing Folder", name: "Existing Folder",
path: "/tmp/ExistingFolder", path: "/tmp/ExistingFolder",
desiredType: string(utilmount.FileTypeDirectory), desiredType: string(hostutil.FileTypeDirectory),
isDir: true, isDir: true,
}, },
{ {
name: "Existing File", name: "Existing File",
path: "/tmp/ExistingFolder/foo", path: "/tmp/ExistingFolder/foo",
desiredType: string(utilmount.FileTypeFile), desiredType: string(hostutil.FileTypeFile),
isFile: true, isFile: true,
}, },
{ {
@ -388,11 +388,10 @@ func TestOSFileTypeChecker(t *testing.T) {
} }
for i, tc := range testCases { for i, tc := range testCases {
fakeFTC := &utilmount.FakeHostUtil{ fakeFTC := hostutil.NewFakeHostUtil(
Filesystem: map[string]utilmount.FileType{ map[string]hostutil.FileType{
tc.path: utilmount.FileType(tc.desiredType), tc.path: hostutil.FileType(tc.desiredType),
}, })
}
oftc := newFileTypeChecker(tc.path, fakeFTC) oftc := newFileTypeChecker(tc.path, fakeFTC)
path := oftc.GetPath() path := oftc.GetPath()

View File

@ -13,6 +13,7 @@ go_library(
"//pkg/util/mount:go_default_library", "//pkg/util/mount: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/hostutil: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",
@ -36,6 +37,7 @@ go_test(
"//pkg/util/mount:go_default_library", "//pkg/util/mount:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/testing: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/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",
@ -45,6 +47,7 @@ go_test(
"//pkg/util/mount:go_default_library", "//pkg/util/mount:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/testing: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/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",
@ -54,6 +57,7 @@ go_test(
"//pkg/util/mount:go_default_library", "//pkg/util/mount:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/testing: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/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,6 +33,7 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"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/validation" "k8s.io/kubernetes/pkg/volume/validation"
"k8s.io/utils/keymutex" "k8s.io/utils/keymutex"
utilstrings "k8s.io/utils/strings" utilstrings "k8s.io/utils/strings"
@ -246,9 +247,9 @@ func (plugin *localVolumePlugin) getGlobalLocalPath(spec *volume.Spec) (string,
return "", err return "", err
} }
switch fileType { switch fileType {
case mount.FileTypeDirectory: case hostutil.FileTypeDirectory:
return spec.PersistentVolume.Spec.Local.Path, nil return spec.PersistentVolume.Spec.Local.Path, nil
case mount.FileTypeBlockDev: case hostutil.FileTypeBlockDev:
return filepath.Join(plugin.generateBlockDeviceBaseGlobalPath(), spec.Name()), nil return filepath.Join(plugin.generateBlockDeviceBaseGlobalPath(), spec.Name()), nil
default: default:
return "", fmt.Errorf("only directory and block device are supported") return "", fmt.Errorf("only directory and block device are supported")
@ -260,7 +261,7 @@ var _ volume.DeviceMountableVolumePlugin = &localVolumePlugin{}
type deviceMounter struct { type deviceMounter struct {
plugin *localVolumePlugin plugin *localVolumePlugin
mounter *mount.SafeFormatAndMount mounter *mount.SafeFormatAndMount
hostUtil mount.HostUtils hostUtil hostutil.HostUtils
} }
var _ volume.DeviceMounter = &deviceMounter{} var _ volume.DeviceMounter = &deviceMounter{}
@ -332,11 +333,11 @@ func (dm *deviceMounter) MountDevice(spec *volume.Spec, devicePath string, devic
} }
switch fileType { 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 // 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 mount.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:
@ -410,7 +411,7 @@ type localVolume struct {
globalPath string globalPath string
// Mounter interface that provides system calls to mount the global path to the pod local path. // Mounter interface that provides system calls to mount the global path to the pod local path.
mounter mount.Interface mounter mount.Interface
hostUtil mount.HostUtils hostUtil hostutil.HostUtils
plugin *localVolumePlugin plugin *localVolumePlugin
volume.MetricsProvider volume.MetricsProvider
} }

View File

@ -26,13 +26,14 @@ import (
"runtime" "runtime"
"testing" "testing"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
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"
utiltesting "k8s.io/client-go/util/testing" utiltesting "k8s.io/client-go/util/testing"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"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/hostutil"
) )
const ( const (
@ -109,10 +110,10 @@ func getDeviceMountablePluginWithBlockPath(t *testing.T, isBlockDevice bool) (st
} }
plugMgr := volume.VolumePluginMgr{} plugMgr := volume.VolumePluginMgr{}
var pathToFSType map[string]mount.FileType var pathToFSType map[string]hostutil.FileType
if isBlockDevice { if isBlockDevice {
pathToFSType = map[string]mount.FileType{ pathToFSType = map[string]hostutil.FileType{
tmpDir: mount.FileTypeBlockDev, tmpDir: hostutil.FileTypeBlockDev,
} }
} }

View File

@ -23,7 +23,7 @@ import (
"sync" "sync"
authenticationv1 "k8s.io/api/authentication/v1" authenticationv1 "k8s.io/api/authentication/v1"
"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"
@ -39,6 +39,7 @@ import (
"k8s.io/klog" "k8s.io/klog"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/util/mount" "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/recyclerclient"
"k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/pkg/volume/util/subpath"
) )
@ -341,8 +342,8 @@ type KubeletVolumeHost interface {
CSIDriversSynced() cache.InformerSynced CSIDriversSynced() cache.InformerSynced
// WaitForCacheSync is a helper function that waits for cache sync for CSIDriverLister // WaitForCacheSync is a helper function that waits for cache sync for CSIDriverLister
WaitForCacheSync() error WaitForCacheSync() error
// Returns HostUtils Interface // Returns hostutil.HostUtils
GetHostUtil() mount.HostUtils GetHostUtil() hostutil.HostUtils
} }
// AttachDetachVolumeHost is a AttachDetach Controller specific interface that plugins can use // AttachDetachVolumeHost is a AttachDetach Controller specific interface that plugins can use

View File

@ -16,6 +16,7 @@ go_library(
"//pkg/util/mount:go_default_library", "//pkg/util/mount: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/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/volumepathhandler:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library",

View File

@ -28,7 +28,7 @@ import (
"time" "time"
authenticationv1 "k8s.io/api/authentication/v1" authenticationv1 "k8s.io/api/authentication/v1"
"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"
@ -43,6 +43,7 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
. "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/recyclerclient" "k8s.io/kubernetes/pkg/volume/util/recyclerclient"
"k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/pkg/volume/util/subpath"
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler" "k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
@ -70,7 +71,7 @@ type fakeVolumeHost struct {
pluginMgr VolumePluginMgr pluginMgr VolumePluginMgr
cloud cloudprovider.Interface cloud cloudprovider.Interface
mounter mount.Interface mounter mount.Interface
hostUtil mount.HostUtils hostUtil hostutil.HostUtils
exec mount.Exec exec mount.Exec
nodeLabels map[string]string nodeLabels map[string]string
nodeName string nodeName string
@ -105,12 +106,10 @@ func NewFakeVolumeHostWithCSINodeName(rootDir string, kubeClient clientset.Inter
return volHost 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 := &fakeVolumeHost{rootDir: rootDir, kubeClient: kubeClient, cloud: cloud}
host.mounter = &mount.FakeMounter{} host.mounter = &mount.FakeMounter{}
host.hostUtil = &mount.FakeHostUtil{ host.hostUtil = hostutil.NewFakeHostUtil(pathToTypeMap)
Filesystem: pathToTypeMap,
}
host.exec = mount.NewFakeExec(nil) host.exec = mount.NewFakeExec(nil)
host.pluginMgr.InitPlugins(plugins, nil /* prober */, host) host.pluginMgr.InitPlugins(plugins, nil /* prober */, host)
host.subpather = &subpath.FakeSubpath{} host.subpather = &subpath.FakeSubpath{}
@ -118,7 +117,7 @@ func newFakeVolumeHost(rootDir string, kubeClient clientset.Interface, plugins [
return host 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) volHost := newFakeVolumeHost(rootDir, kubeClient, plugins, nil, pathToTypeMap)
return volHost return volHost
} }
@ -159,7 +158,7 @@ func (f *fakeVolumeHost) GetMounter(pluginName string) mount.Interface {
return f.mounter return f.mounter
} }
func (f *fakeVolumeHost) GetHostUtil() mount.HostUtils { func (f *fakeVolumeHost) GetHostUtil() hostutil.HostUtils {
return f.hostUtil return f.hostUtil
} }

View File

@ -94,6 +94,7 @@ filegroup(
"//pkg/volume/util/exec:all-srcs", "//pkg/volume/util/exec:all-srcs",
"//pkg/volume/util/fs:all-srcs", "//pkg/volume/util/fs:all-srcs",
"//pkg/volume/util/fsquota:all-srcs", "//pkg/volume/util/fsquota:all-srcs",
"//pkg/volume/util/hostutil:all-srcs",
"//pkg/volume/util/nestedpendingoperations:all-srcs", "//pkg/volume/util/nestedpendingoperations:all-srcs",
"//pkg/volume/util/operationexecutor:all-srcs", "//pkg/volume/util/operationexecutor:all-srcs",
"//pkg/volume/util/recyclerclient:all-srcs", "//pkg/volume/util/recyclerclient:all-srcs",

View File

@ -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"],
)

View File

@ -14,22 +14,36 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package mount package hostutil
import ( import (
"errors" "errors"
"os" "os"
"sync" "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 { type FakeHostUtil struct {
MountPoints []MountPoint MountPoints []mount.MountPoint
Filesystem map[string]FileType Filesystem map[string]FileType
mutex sync.Mutex 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{} var _ HostUtils = &FakeHostUtil{}
// DeviceOpened checks if block device referenced by pathname is in use by // 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 // 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) return getDeviceNameFromMount(mounter, mountPath, pluginMountDir)
} }

View File

@ -14,14 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// TODO(thockin): This whole pkg is pretty linux-centric. As soon as we have package hostutil
// an alternate platform, we will need to abstract further.
package mount
import ( import (
"fmt" "fmt"
"os" "os"
"k8s.io/kubernetes/pkg/util/mount"
) )
// FileType enumerates the known set of possible file types. // FileType enumerates the known set of possible file types.
@ -51,7 +50,7 @@ type HostUtils interface {
PathIsDevice(pathname string) (bool, error) PathIsDevice(pathname string) (bool, error)
// GetDeviceNameFromMount finds the device name by checking the mount path // GetDeviceNameFromMount finds the device name by checking the mount path
// to get the global mount path within its plugin directory. // 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 // MakeRShared checks that given path is on a mount with 'rshared' mount
// propagation. If not, it bind-mounts the path as rshared. // propagation. If not, it bind-mounts the path as rshared.
MakeRShared(path string) error MakeRShared(path string) error
@ -72,8 +71,8 @@ type HostUtils interface {
} }
// Compile-time check to ensure all HostUtil implementations satisfy // Compile-time check to ensure all HostUtil implementations satisfy
// the HostUtils Interface. // the Interface.
var _ HostUtils = &hostUtil{} var _ HostUtils = &HostUtil{}
// getFileType checks for file/directory/socket and block/character devices. // getFileType checks for file/directory/socket and block/character devices.
func getFileType(pathname string) (FileType, error) { func getFileType(pathname string) (FileType, error) {

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package mount package hostutil
import ( import (
"fmt" "fmt"
@ -27,17 +27,26 @@ import (
"syscall" "syscall"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
"k8s.io/klog" "k8s.io/klog"
utilpath "k8s.io/utils/path" 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 // NewHostUtil returns a struct that implements the HostUtils interface on
// linux platforms // linux platforms
func NewHostUtil() HostUtils { func NewHostUtil() *HostUtil {
return &hostUtil{} return &HostUtil{}
} }
// DeviceOpened checks if block device in use by calling Open with O_EXCL flag. // 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 errno EBUSY, return true with nil error.
// If open returns nil, return false with nil error. // If open returns nil, return false with nil error.
// Otherwise, return false with 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) return ExclusiveOpenFailsOnDevice(pathname)
} }
// PathIsDevice uses FileInfo returned from os.Stat to check if path refers // PathIsDevice uses FileInfo returned from os.Stat to check if path refers
// to a device. // to a device.
func (hu *hostUtil) PathIsDevice(pathname string) (bool, error) { func (hu *HostUtil) PathIsDevice(pathname string) (bool, error) {
pathType, err := hu.GetFileType(pathname) pathType, err := hu.GetFileType(pathname)
isDevice := pathType == FileTypeCharDev || pathType == FileTypeBlockDev isDevice := pathType == FileTypeCharDev || pathType == FileTypeBlockDev
return isDevice, err return isDevice, err
@ -95,20 +104,15 @@ func ExclusiveOpenFailsOnDevice(pathname string) (bool, error) {
return false, errno return false, errno
} }
//GetDeviceNameFromMount: given a mount point, find the device name from its global mount point // 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) { func (hu *HostUtil) GetDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) {
return GetDeviceNameFromMountLinux(mounter, mountPath, pluginMountDir) return getDeviceNameFromMount(mounter, mountPath, pluginMountDir)
} }
func getDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) { // getDeviceNameFromMountLinux find the device name from /proc/mounts in which
return GetDeviceNameFromMountLinux(mounter, mountPath, pluginMountDir)
}
// 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 // 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 // matches, returns the volume name taken from its given mountPath
// This implementation is shared with NsEnterMounter func getDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) {
func GetDeviceNameFromMountLinux(mounter Interface, mountPath, pluginMountDir string) (string, error) {
refs, err := mounter.GetMountRefs(mountPath) refs, err := mounter.GetMountRefs(mountPath)
if err != nil { if err != nil {
klog.V(4).Infof("GetMountRefs failed for mount path %q: %v", mountPath, err) 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 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) 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) 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) 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) return filepath.EvalSymlinks(pathname)
} }
@ -157,7 +169,7 @@ func isShared(mount string, mountInfoPath string) (bool, error) {
} }
// parse optional parameters // parse optional parameters
for _, opt := range info.optionalFields { for _, opt := range info.OptionalFields {
if strings.HasPrefix(opt, "shared:") { if strings.HasPrefix(opt, "shared:") {
return true, nil return true, nil
} }
@ -165,23 +177,23 @@ func isShared(mount string, mountInfoPath string) (bool, error) {
return false, nil return false, nil
} }
func findMountInfo(path, mountInfoPath string) (mountInfo, error) { func findMountInfo(path, mountInfoPath string) (mount.MountInfo, error) {
infos, err := parseMountInfo(mountInfoPath) infos, err := mount.ParseMountInfo(mountInfoPath)
if err != nil { if err != nil {
return mountInfo{}, err return mount.MountInfo{}, err
} }
// process /proc/xxx/mountinfo in backward order and find the first mount // 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 // 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-- { for i := len(infos) - 1; i >= 0; i-- {
if PathWithinBase(path, infos[i].mountPoint) { if mount.PathWithinBase(path, infos[i].MountPoint) {
info = &infos[i] info = &infos[i]
break break
} }
} }
if info == nil { 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 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. // "seclabel" can be both in mount options and super options.
for _, opt := range info.superOptions { for _, opt := range info.SuperOptions {
if opt == "seclabel" { if opt == "seclabel" {
return true, nil return true, nil
} }
} }
for _, opt := range info.mountOptions { for _, opt := range info.MountOptions {
if opt == "seclabel" { if opt == "seclabel" {
return true, nil return true, nil
} }
@ -235,12 +247,14 @@ func GetSELinux(path string, mountInfoFilename string) (bool, error) {
return false, nil 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) return GetSELinux(pathname, procMountInfoPath)
} }
// GetOwner returns the integer ID for the user and group of the given path // 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) realpath, err := filepath.EvalSymlinks(pathname)
if err != nil { if err != nil {
return -1, -1, err return -1, -1, err
@ -248,7 +262,8 @@ func (hu *hostUtil) GetOwner(pathname string) (int64, int64, error) {
return GetOwnerLinux(realpath) 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) return GetModeLinux(pathname)
} }

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package mount package hostutil
import ( import (
"fmt" "fmt"
@ -311,3 +311,17 @@ func isOperationNotPermittedError(err error) bool {
} }
return false 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
}

View File

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

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package mount package hostutil
import ( import (
"fmt" "fmt"
@ -26,27 +26,28 @@ import (
"strings" "strings"
"k8s.io/klog" "k8s.io/klog"
utilpath "k8s.io/utils/path" 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 // NewHostUtil returns a struct that implements HostUtils on Windows platforms
// windows platforms func NewHostUtil() *HostUtil {
func NewHostUtil() HostUtils { return &HostUtil{}
return &hostUtil{}
} }
// GetDeviceNameFromMount given a mnt point, find the device // 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) return getDeviceNameFromMount(mounter, mountPath, pluginMountDir)
} }
// getDeviceNameFromMount find the device(drive) name in which // 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 // 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 // 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) refs, err := mounter.GetMountRefs(mountPath)
if err != nil { if err != nil {
klog.V(4).Infof("GetMountRefs failed for mount path %q: %v", mountPath, err) 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 { if len(refs) == 0 {
return "", fmt.Errorf("directory %s is not mounted", mountPath) return "", fmt.Errorf("directory %s is not mounted", mountPath)
} }
basemountPath := NormalizeWindowsPath(pluginMountDir) basemountPath := mount.NormalizeWindowsPath(pluginMountDir)
for _, ref := range refs { for _, ref := range refs {
if strings.Contains(ref, basemountPath) { if strings.Contains(ref, basemountPath) {
volumeID, err := filepath.Rel(NormalizeWindowsPath(basemountPath), ref) volumeID, err := filepath.Rel(mount.NormalizeWindowsPath(basemountPath), ref)
if err != nil { if err != nil {
klog.Errorf("Failed to get volume id from mount %s - %v", mountPath, err) klog.Errorf("Failed to get volume id from mount %s - %v", mountPath, err)
return "", err return "", err
@ -71,49 +72,51 @@ func getDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string)
} }
// DeviceOpened determines if the device is in use elsewhere // 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 return false, nil
} }
// PathIsDevice determines if a path is a device. // 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 return false, nil
} }
// MakeRShared checks that given path is on a mount with 'rshared' mount // MakeRShared checks that given path is on a mount with 'rshared' mount
// propagation. Empty implementation here. // propagation. Empty implementation here.
func (hu *hostUtil) MakeRShared(path string) error { func (hu *HostUtil) MakeRShared(path string) error {
return nil return nil
} }
// GetFileType checks for sockets/block/character devices // 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) return getFileType(pathname)
} }
// PathExists checks whether the path exists // 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) return utilpath.Exists(utilpath.CheckFollowSymlink, pathname)
} }
// EvalHostSymlinks returns the path name after evaluating symlinks // 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) return filepath.EvalSymlinks(pathname)
} }
// GetOwner returns the integer ID for the user and group of the given path // 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 // Note that on windows, it always returns 0. We actually don't set Group on
// windows platform, see SetVolumeOwnership implementation. // 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 return -1, -1, nil
} }
func (hu *hostUtil) GetSELinuxSupport(pathname string) (bool, error) { // GetSELinuxSupport returns a boolean indicating support for SELinux.
// Windows does not support SELinux. // Windows does not support SELinux.
func (hu *HostUtil) GetSELinuxSupport(pathname string) (bool, error) {
return false, nil 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) info, err := os.Stat(pathname)
if err != nil { if err != nil {
return 0, err return 0, err

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package mount package hostutil
import ( import (
"io/ioutil" "io/ioutil"

View File

@ -21,6 +21,7 @@ go_library(
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/csi:go_default_library", "//pkg/volume/csi: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/nestedpendingoperations:go_default_library", "//pkg/volume/util/nestedpendingoperations:go_default_library",
"//pkg/volume/util/types:go_default_library", "//pkg/volume/util/types:go_default_library",
"//pkg/volume/util/volumepathhandler:go_default_library", "//pkg/volume/util/volumepathhandler:go_default_library",
@ -48,13 +49,13 @@ go_test(
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/util/mount:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/awsebs:go_default_library", "//pkg/volume/awsebs:go_default_library",
"//pkg/volume/csi:go_default_library", "//pkg/volume/csi:go_default_library",
"//pkg/volume/csi/testing:go_default_library", "//pkg/volume/csi/testing:go_default_library",
"//pkg/volume/gcepd:go_default_library", "//pkg/volume/gcepd:go_default_library",
"//pkg/volume/testing:go_default_library", "//pkg/volume/testing:go_default_library",
"//pkg/volume/util/hostutil:go_default_library",
"//pkg/volume/util/types: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",

View File

@ -19,10 +19,10 @@ package operationexecutor
import ( import (
"time" "time"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util/hostutil"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types" volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
@ -64,7 +64,7 @@ func (f *fakeOGCounter) GenerateVolumesAreAttachedFunc(attachedVolumes []Attache
return f.recordFuncCall("GenerateVolumesAreAttachedFunc"), nil 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 return f.recordFuncCall("GenerateUnmountDeviceFunc"), nil
} }
@ -80,7 +80,7 @@ func (f *fakeOGCounter) GenerateUnmapVolumeFunc(volumeToUnmount MountedVolume, a
return f.recordFuncCall("GenerateUnmapVolumeFunc"), nil 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 return f.recordFuncCall("GenerateUnmapDeviceFunc"), nil
} }

View File

@ -26,13 +26,14 @@ import (
"k8s.io/klog" "k8s.io/klog"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/csi" "k8s.io/kubernetes/pkg/volume/csi"
"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/nestedpendingoperations" "k8s.io/kubernetes/pkg/volume/util/nestedpendingoperations"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types" volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler" "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 // global map path. If number of reference is zero, remove global map path
// directory and free a volume for detach. // directory and free a volume for detach.
// It then updates the actual state of the world to reflect that. // 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 // VerifyControllerAttachedVolume checks if the specified volume is present
// in the specified nodes AttachedVolumes Status field. It uses kubeClient // in the specified nodes AttachedVolumes Status field. It uses kubeClient
@ -824,7 +825,7 @@ func (oe *operationExecutor) UnmountVolume(
func (oe *operationExecutor) UnmountDevice( func (oe *operationExecutor) UnmountDevice(
deviceToDetach AttachedVolume, deviceToDetach AttachedVolume,
actualStateOfWorld ActualStateOfWorldMounterUpdater, actualStateOfWorld ActualStateOfWorldMounterUpdater,
hostutil mount.HostUtils) error { hostutil hostutil.HostUtils) error {
fsVolume, err := util.CheckVolumeModeFilesystem(deviceToDetach.VolumeSpec) fsVolume, err := util.CheckVolumeModeFilesystem(deviceToDetach.VolumeSpec)
if err != nil { if err != nil {
return err return err

View File

@ -21,12 +21,12 @@ import (
"testing" "testing"
"time" "time"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
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"
"k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util/hostutil"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types" volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
) )
@ -433,7 +433,7 @@ func (fopg *fakeOperationGenerator) GenerateVolumesAreAttachedFunc(attachedVolum
OperationFunc: opFunc, OperationFunc: opFunc,
}, nil }, 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) { opFunc := func() (error, error) {
startOperationAndBlock(fopg.ch, fopg.quit) startOperationAndBlock(fopg.ch, fopg.quit)
return nil, nil return nil, nil
@ -506,7 +506,7 @@ func (fopg *fakeOperationGenerator) GenerateUnmapVolumeFunc(volumeToUnmount Moun
}, nil }, 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) { opFunc := func() (error, error) {
startOperationAndBlock(fopg.ch, fopg.quit) startOperationAndBlock(fopg.ch, fopg.quit)
return nil, nil return nil, nil

View File

@ -36,10 +36,10 @@ import (
"k8s.io/klog" "k8s.io/klog"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
kevents "k8s.io/kubernetes/pkg/kubelet/events" kevents "k8s.io/kubernetes/pkg/kubelet/events"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/csi" "k8s.io/kubernetes/pkg/volume/csi"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/hostutil"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types" volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler" "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) GenerateVolumesAreAttachedFunc(attachedVolumes []AttachedVolume, nodeName types.NodeName, actualStateOfWorld ActualStateOfWorldAttacherUpdater) (volumetypes.GeneratedOperations, error)
// Generates the UnMountDevice function needed to perform the unmount of a device // 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 // 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) 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) GenerateUnmapVolumeFunc(volumeToUnmount MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater) (volumetypes.GeneratedOperations, error)
// Generates the UnmapDevice function needed to perform the unmap of a device // 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 returns volume plugin manager
GetVolumePluginMgr() *volume.VolumePluginMgr GetVolumePluginMgr() *volume.VolumePluginMgr
@ -860,7 +860,7 @@ func (og *operationGenerator) GenerateUnmountVolumeFunc(
func (og *operationGenerator) GenerateUnmountDeviceFunc( func (og *operationGenerator) GenerateUnmountDeviceFunc(
deviceToDetach AttachedVolume, deviceToDetach AttachedVolume,
actualStateOfWorld ActualStateOfWorldMounterUpdater, actualStateOfWorld ActualStateOfWorldMounterUpdater,
hostutil mount.HostUtils) (volumetypes.GeneratedOperations, error) { hostutil hostutil.HostUtils) (volumetypes.GeneratedOperations, error) {
var pluginName string var pluginName string
if useCSIPlugin(og.volumePluginMgr, deviceToDetach.VolumeSpec) { if useCSIPlugin(og.volumePluginMgr, deviceToDetach.VolumeSpec) {
@ -1244,7 +1244,7 @@ func (og *operationGenerator) GenerateUnmapVolumeFunc(
func (og *operationGenerator) GenerateUnmapDeviceFunc( func (og *operationGenerator) GenerateUnmapDeviceFunc(
deviceToDetach AttachedVolume, deviceToDetach AttachedVolume,
actualStateOfWorld ActualStateOfWorldMounterUpdater, actualStateOfWorld ActualStateOfWorldMounterUpdater,
hostutil mount.HostUtils) (volumetypes.GeneratedOperations, error) { hostutil hostutil.HostUtils) (volumetypes.GeneratedOperations, error) {
var blockVolumePlugin volume.BlockVolumePlugin var blockVolumePlugin volume.BlockVolumePlugin
var err error 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 // 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) isDevicePath, devicePathErr := hostUtil.PathIsDevice(deviceToDetach.DevicePath)
var deviceOpened bool var deviceOpened bool
var deviceOpenedErr error var deviceOpenedErr error