Move nsenter mounter to pkg/volume/util/nsenter

As part of moving pkg/util/mount out of tree, the NSEnter implementation
of mount.Interface needs to be relocated out of pkg/util/mount, as it is
K8s specific. This patch relocates that mounter implementation to
pkg/volume/util/nsenter.

Since the NSEnter mounter shares a lot of its logic with the Linux
mounter implementation, many of the previously private methods of the
Linux mounter are now made public to maintain that shared code.

Additionaly, it was observed that *all* mount.Interface implemenations
were using the same common method for IsNotMountPoint, so this patch
removes that method from the mount.Interface definition and just exports
the common implementation instead.
This commit is contained in:
Travis Rhoden 2019-04-02 13:19:27 -06:00
parent aa52140928
commit 1c045a09db
23 changed files with 194 additions and 160 deletions

View File

@ -108,6 +108,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/nsenter: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

@ -96,6 +96,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"
nsutil "k8s.io/kubernetes/pkg/volume/util/nsenter"
"k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/pkg/volume/util/subpath"
"k8s.io/utils/exec" "k8s.io/utils/exec"
"k8s.io/utils/nsenter" "k8s.io/utils/nsenter"
@ -373,7 +374,7 @@ func UnsecuredDependencies(s *options.KubeletServer) (*kubelet.Dependencies, err
if err != nil { if err != nil {
return nil, err return nil, err
} }
mounter = mount.NewNsenterMounter(s.RootDirectory, ne) mounter = nsutil.NewNsenterMounter(s.RootDirectory, ne)
// NSenter only valid on Linux // NSenter only valid on Linux
subpather = subpath.NewNSEnter(mounter, ne, s.RootDirectory) subpather = subpath.NewNSEnter(mounter, ne, s.RootDirectory)
// an exec interface which can use nsenter for flex plugin calls // an exec interface which can use nsenter for flex plugin calls

View File

@ -15,8 +15,6 @@ go_library(
"mount_linux.go", "mount_linux.go",
"mount_unsupported.go", "mount_unsupported.go",
"mount_windows.go", "mount_windows.go",
"nsenter_mount.go",
"nsenter_mount_unsupported.go",
], ],
importpath = "k8s.io/kubernetes/pkg/util/mount", importpath = "k8s.io/kubernetes/pkg/util/mount",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
@ -24,43 +22,14 @@ go_library(
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library",
] + select({ ] + select({
"@io_bazel_rules_go//go/platform:android": [
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:darwin": [
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:dragonfly": [
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:freebsd": [
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:linux": [ "@io_bazel_rules_go//go/platform:linux": [
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library", "//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/nsenter:go_default_library",
"//vendor/k8s.io/utils/path:go_default_library", "//vendor/k8s.io/utils/path:go_default_library",
], ],
"@io_bazel_rules_go//go/platform:nacl": [
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:netbsd": [
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:openbsd": [
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:plan9": [
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:solaris": [
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:windows": [ "@io_bazel_rules_go//go/platform:windows": [
"//vendor/k8s.io/utils/keymutex:go_default_library", "//vendor/k8s.io/utils/keymutex:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
"//vendor/k8s.io/utils/path:go_default_library", "//vendor/k8s.io/utils/path:go_default_library",
], ],
"//conditions:default": [], "//conditions:default": [],
@ -75,7 +44,6 @@ go_test(
"mount_linux_test.go", "mount_linux_test.go",
"mount_test.go", "mount_test.go",
"mount_windows_test.go", "mount_windows_test.go",
"nsenter_mount_test.go",
"safe_format_and_mount_test.go", "safe_format_and_mount_test.go",
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
@ -84,7 +52,6 @@ go_test(
] + select({ ] + select({
"@io_bazel_rules_go//go/platform:linux": [ "@io_bazel_rules_go//go/platform:linux": [
"//vendor/k8s.io/utils/exec:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library",
"//vendor/k8s.io/utils/nsenter: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

@ -44,7 +44,7 @@ var _ Interface = &execMounter{}
// Mount runs mount(8) using given exec interface. // Mount runs mount(8) using given exec interface.
func (m *execMounter) Mount(source string, target string, fstype string, options []string) error { func (m *execMounter) Mount(source string, target string, fstype string, options []string) error {
bind, bindOpts, bindRemountOpts := isBind(options) bind, bindOpts, bindRemountOpts := IsBind(options)
if bind { if bind {
err := m.doExecMount(source, target, fstype, bindOpts) err := m.doExecMount(source, target, fstype, bindOpts)
@ -60,7 +60,7 @@ func (m *execMounter) Mount(source string, target string, fstype string, options
// doExecMount calls exec(mount <what> <where>) using given exec interface. // doExecMount calls exec(mount <what> <where>) using given exec interface.
func (m *execMounter) doExecMount(source, target, fstype string, options []string) error { func (m *execMounter) doExecMount(source, target, fstype string, options []string) error {
klog.V(5).Infof("Exec Mounting %s %s %s %v", source, target, fstype, options) klog.V(5).Infof("Exec Mounting %s %s %s %v", source, target, fstype, options)
mountArgs := makeMountArgs(source, target, fstype, options) mountArgs := MakeMountArgs(source, target, fstype, options)
output, err := m.exec.Run("mount", mountArgs...) output, err := m.exec.Run("mount", mountArgs...)
klog.V(5).Infof("Exec mounted %v: %v: %s", mountArgs, err, string(output)) klog.V(5).Infof("Exec mounted %v: %v: %s", mountArgs, err, string(output))
if err != nil { if err != nil {
@ -116,10 +116,6 @@ func (m *execMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
return m.wrappedMounter.IsMountPointMatch(mp, dir) return m.wrappedMounter.IsMountPointMatch(mp, dir)
} }
func (m *execMounter) IsNotMountPoint(dir string) (bool, error) {
return m.wrappedMounter.IsNotMountPoint(dir)
}
func (m *execMounter) MakeRShared(path string) error { func (m *execMounter) MakeRShared(path string) error {
return m.wrappedMounter.MakeRShared(path) return m.wrappedMounter.MakeRShared(path)
} }

View File

@ -47,10 +47,6 @@ func (mounter *execMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
return (mp.Path == dir) return (mp.Path == dir)
} }
func (mounter *execMounter) IsNotMountPoint(dir string) (bool, error) {
return isNotMountPoint(mounter, dir)
}
func (mounter *execMounter) IsLikelyNotMountPoint(file string) (bool, error) { func (mounter *execMounter) IsLikelyNotMountPoint(file string) (bool, error) {
return true, nil return true, nil
} }

View File

@ -136,10 +136,6 @@ func (f *FakeMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
return mp.Path == dir return mp.Path == dir
} }
func (f *FakeMounter) IsNotMountPoint(dir string) (bool, error) {
return isNotMountPoint(f, dir)
}
func (f *FakeMounter) IsLikelyNotMountPoint(file string) (bool, error) { func (f *FakeMounter) IsLikelyNotMountPoint(file string) (bool, error) {
f.mutex.Lock() f.mutex.Lock()
defer f.mutex.Unlock() defer f.mutex.Unlock()

View File

@ -50,14 +50,6 @@ type Interface interface {
List() ([]MountPoint, error) List() ([]MountPoint, error)
// IsMountPointMatch determines if the mountpoint matches the dir // IsMountPointMatch determines if the mountpoint matches the dir
IsMountPointMatch(mp MountPoint, dir string) bool IsMountPointMatch(mp MountPoint, dir string) bool
// IsNotMountPoint determines if a directory is a mountpoint.
// It should return ErrNotExist when the directory does not exist.
// IsNotMountPoint is more expensive than IsLikelyNotMountPoint.
// IsNotMountPoint detects bind mounts in linux.
// IsNotMountPoint enumerates all the mountpoints using List() and
// the list of mountpoints may be large, then it uses
// IsMountPointMatch to evaluate whether the directory is a mountpoint
IsNotMountPoint(file string) (bool, error)
// IsLikelyNotMountPoint uses heuristics to determine if a directory // IsLikelyNotMountPoint uses heuristics to determine if a directory
// is a mountpoint. // is a mountpoint.
// It should return ErrNotExist when the directory does not exist. // It should return ErrNotExist when the directory does not exist.
@ -222,9 +214,14 @@ func GetDeviceNameFromMount(mounter Interface, mountPath string) (string, int, e
return device, refCount, nil return device, refCount, nil
} }
// isNotMountPoint implements Mounter.IsNotMountPoint and is shared by mounter // IsNotMountPoint determines if a directory is a mountpoint.
// implementations. // It should return ErrNotExist when the directory does not exist.
func isNotMountPoint(mounter Interface, file string) (bool, error) { // IsNotMountPoint is more expensive than IsLikelyNotMountPoint.
// IsNotMountPoint detects bind mounts in linux.
// IsNotMountPoint enumerates all the mountpoints using List() and
// the list of mountpoints may be large, then it uses
// IsMountPointMatch to evaluate whether the directory is a mountpoint
func IsNotMountPoint(mounter Interface, file string) (bool, error) {
// IsLikelyNotMountPoint provides a quick check // IsLikelyNotMountPoint provides a quick check
// to determine whether file IS A mountpoint // to determine whether file IS A mountpoint
notMnt, notMntErr := mounter.IsLikelyNotMountPoint(file) notMnt, notMntErr := mounter.IsLikelyNotMountPoint(file)
@ -263,11 +260,11 @@ func isNotMountPoint(mounter Interface, file string) (bool, error) {
return notMnt, nil return notMnt, nil
} }
// isBind detects whether a bind mount is being requested and makes the remount options to // IsBind detects whether a bind mount is being requested and makes the remount options to
// use in case of bind mount, due to the fact that bind mount doesn't respect mount options. // use in case of bind mount, due to the fact that bind mount doesn't respect mount options.
// The list equals: // The list equals:
// options - 'bind' + 'remount' (no duplicate) // options - 'bind' + 'remount' (no duplicate)
func isBind(options []string) (bool, []string, []string) { func IsBind(options []string) (bool, []string, []string) {
// Because we have an FD opened on the subpath bind mount, the "bind" option // Because we have an FD opened on the subpath bind mount, the "bind" option
// needs to be included, otherwise the mount target will error as busy if you // needs to be included, otherwise the mount target will error as busy if you
// remount as readonly. // remount as readonly.

View File

@ -55,7 +55,7 @@ func doCleanupMountPoint(mountPath string, mounter Interface, extensiveMountPoin
var notMnt bool var notMnt bool
var err error var err error
if extensiveMountPointCheck { if extensiveMountPointCheck {
notMnt, err = mounter.IsNotMountPoint(mountPath) notMnt, err = IsNotMountPoint(mounter, mountPath)
} else { } else {
notMnt, err = mounter.IsLikelyNotMountPoint(mountPath) notMnt, err = mounter.IsLikelyNotMountPoint(mountPath)
} }

View File

@ -81,7 +81,7 @@ func (mounter *Mounter) Mount(source string, target string, fstype string, optio
// Path to mounter binary if containerized mounter is needed. Otherwise, it is set to empty. // Path to mounter binary if containerized mounter is needed. Otherwise, it is set to empty.
// All Linux distros are expected to be shipped with a mount utility that a support bind mounts. // All Linux distros are expected to be shipped with a mount utility that a support bind mounts.
mounterPath := "" mounterPath := ""
bind, bindOpts, bindRemountOpts := isBind(options) bind, bindOpts, bindRemountOpts := IsBind(options)
if bind { if bind {
err := mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindOpts) err := mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindOpts)
if err != nil { if err != nil {
@ -99,7 +99,7 @@ func (mounter *Mounter) Mount(source string, target string, fstype string, optio
// doMount runs the mount command. mounterPath is the path to mounter binary if containerized mounter is used. // doMount runs the mount command. mounterPath is the path to mounter binary if containerized mounter is used.
func (m *Mounter) doMount(mounterPath string, mountCmd string, source string, target string, fstype string, options []string) error { func (m *Mounter) doMount(mounterPath string, mountCmd string, source string, target string, fstype string, options []string) error {
mountArgs := makeMountArgs(source, target, fstype, options) mountArgs := MakeMountArgs(source, target, fstype, options)
if len(mounterPath) > 0 { if len(mounterPath) > 0 {
mountArgs = append([]string{mountCmd}, mountArgs...) mountArgs = append([]string{mountCmd}, mountArgs...)
mountCmd = mounterPath mountCmd = mounterPath
@ -128,7 +128,7 @@ func (m *Mounter) doMount(mounterPath string, mountCmd string, source string, ta
// //
// systemd-mount is not used because it's too new for older distros // systemd-mount is not used because it's too new for older distros
// (CentOS 7, Debian Jessie). // (CentOS 7, Debian Jessie).
mountCmd, mountArgs = addSystemdScope("systemd-run", target, mountCmd, mountArgs) mountCmd, mountArgs = AddSystemdScope("systemd-run", target, mountCmd, mountArgs)
} else { } else {
// No systemd-run on the host (or we failed to check it), assume kubelet // No systemd-run on the host (or we failed to check it), assume kubelet
// does not run as a systemd service. // does not run as a systemd service.
@ -172,8 +172,9 @@ func detectSystemd() bool {
return true return true
} }
// makeMountArgs makes the arguments to the mount(8) command. // MakeMountArgs makes the arguments to the mount(8) command.
func makeMountArgs(source, target, fstype string, options []string) []string { // Implementation is shared with NsEnterMounter
func MakeMountArgs(source, target, fstype string, options []string) []string {
// Build mount command as follows: // Build mount command as follows:
// mount [-t $fstype] [-o $options] [$source] $target // mount [-t $fstype] [-o $options] [$source] $target
mountArgs := []string{} mountArgs := []string{}
@ -191,8 +192,9 @@ func makeMountArgs(source, target, fstype string, options []string) []string {
return mountArgs return mountArgs
} }
// addSystemdScope adds "system-run --scope" to given command line // AddSystemdScope adds "system-run --scope" to given command line
func addSystemdScope(systemdRunPath, mountName, command string, args []string) (string, []string) { // implementation is shared with NsEnterMounter
func AddSystemdScope(systemdRunPath, mountName, command string, args []string) (string, []string) {
descriptionArg := fmt.Sprintf("--description=Kubernetes transient mount for %s", mountName) descriptionArg := fmt.Sprintf("--description=Kubernetes transient mount for %s", mountName)
systemdRunArgs := []string{descriptionArg, "--scope", "--", command} systemdRunArgs := []string{descriptionArg, "--scope", "--", command}
return systemdRunPath, append(systemdRunArgs, args...) return systemdRunPath, append(systemdRunArgs, args...)
@ -211,7 +213,7 @@ func (mounter *Mounter) Unmount(target string) error {
// List returns a list of all mounted filesystems. // List returns a list of all mounted filesystems.
func (*Mounter) List() ([]MountPoint, error) { func (*Mounter) List() ([]MountPoint, error) {
return listProcMounts(procMountsPath) return ListProcMounts(procMountsPath)
} }
func (mounter *Mounter) IsMountPointMatch(mp MountPoint, dir string) bool { func (mounter *Mounter) IsMountPointMatch(mp MountPoint, dir string) bool {
@ -219,10 +221,6 @@ func (mounter *Mounter) IsMountPointMatch(mp MountPoint, dir string) bool {
return ((mp.Path == dir) || (mp.Path == deletedDir)) return ((mp.Path == dir) || (mp.Path == deletedDir))
} }
func (mounter *Mounter) IsNotMountPoint(dir string) (bool, error) {
return isNotMountPoint(mounter, dir)
}
// IsLikelyNotMountPoint determines if a directory is not a mountpoint. // IsLikelyNotMountPoint determines if a directory is not a mountpoint.
// It is fast but not necessarily ALWAYS correct. If the path is in fact // It is fast but not necessarily ALWAYS correct. If the path is in fact
// a bind mount from one part of a mount to another it will not be detected. // a bind mount from one part of a mount to another it will not be detected.
@ -252,7 +250,7 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, 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 (mounter *Mounter) DeviceOpened(pathname string) (bool, error) { func (mounter *Mounter) 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
@ -263,7 +261,8 @@ func (mounter *Mounter) PathIsDevice(pathname string) (bool, error) {
return isDevice, err return isDevice, err
} }
func exclusiveOpenFailsOnDevice(pathname string) (bool, error) { // ExclusiveOpenFailsOnDevice is shared with NsEnterMounter
func ExclusiveOpenFailsOnDevice(pathname string) (bool, error) {
var isDevice bool var isDevice bool
finfo, err := os.Stat(pathname) finfo, err := os.Stat(pathname)
if os.IsNotExist(err) { if os.IsNotExist(err) {
@ -302,13 +301,18 @@ func exclusiveOpenFailsOnDevice(pathname string) (bool, error) {
//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 (mounter *Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) { func (mounter *Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) {
return getDeviceNameFromMount(mounter, mountPath, pluginDir) return GetDeviceNameFromMountLinux(mounter, mountPath, pluginDir)
} }
// getDeviceNameFromMount find the device name from /proc/mounts in which func getDeviceNameFromMount(mounter Interface, mountPath, pluginDir string) (string, error) {
return GetDeviceNameFromMountLinux(mounter, mountPath, pluginDir)
}
// GetDeviceNameFromMountLinux find the device name from /proc/mounts in which
// the mount path reference should match the given plugin directory. In case no mount path reference // the mount path reference should match the given plugin 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, pluginDir string) (string, error) { // This implementation is shared with NsEnterMounter
func GetDeviceNameFromMountLinux(mounter Interface, mountPath, pluginDir 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)
@ -333,7 +337,8 @@ func getDeviceNameFromMount(mounter Interface, mountPath, pluginDir string) (str
return path.Base(mountPath), nil return path.Base(mountPath), nil
} }
func listProcMounts(mountFilePath string) ([]MountPoint, error) { // ListProcMounts is shared with NsEnterMounter
func ListProcMounts(mountFilePath string) ([]MountPoint, error) {
content, err := utilio.ConsistentRead(mountFilePath, maxListTries) content, err := utilio.ConsistentRead(mountFilePath, maxListTries)
if err != nil { if err != nil {
return nil, err return nil, err
@ -379,7 +384,7 @@ func parseProcMounts(content []byte) ([]MountPoint, error) {
} }
func (mounter *Mounter) MakeRShared(path string) error { func (mounter *Mounter) MakeRShared(path string) error {
return doMakeRShared(path, procMountInfoPath) return DoMakeRShared(path, procMountInfoPath)
} }
func (mounter *Mounter) GetFileType(pathname string) (FileType, error) { func (mounter *Mounter) GetFileType(pathname string) (FileType, error) {
@ -668,11 +673,11 @@ func findMountInfo(path, mountInfoPath string) (mountInfo, error) {
return *info, nil return *info, nil
} }
// doMakeRShared is common implementation of MakeRShared on Linux. It checks if // DoMakeRShared is common implementation of MakeRShared on Linux. It checks if
// path is shared and bind-mounts it as rshared if needed. mountCmd and // path is shared and bind-mounts it as rshared if needed. mountCmd and
// mountArgs are expected to contain mount-like command, doMakeRShared will add // mountArgs are expected to contain mount-like command, DoMakeRShared will add
// '--bind <path> <path>' and '--make-rshared <path>' to mountArgs. // '--bind <path> <path>' and '--make-rshared <path>' to mountArgs.
func doMakeRShared(path string, mountInfoFilename string) error { func DoMakeRShared(path string, mountInfoFilename string) error {
shared, err := isShared(path, mountInfoFilename) shared, err := isShared(path, mountInfoFilename)
if err != nil { if err != nil {
return err return err
@ -696,8 +701,8 @@ func doMakeRShared(path string, mountInfoFilename string) error {
return nil return nil
} }
// getSELinuxSupport is common implementation of GetSELinuxSupport on Linux. // GetSELinux is common implementation of GetSELinuxSupport on Linux.
func getSELinuxSupport(path string, mountInfoFilename string) (bool, error) { func GetSELinux(path string, mountInfoFilename string) (bool, error) {
info, err := findMountInfo(path, mountInfoFilename) info, err := findMountInfo(path, mountInfoFilename)
if err != nil { if err != nil {
return false, err return false, err
@ -731,11 +736,11 @@ func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return searchMountPoints(realpath, procMountInfoPath) return SearchMountPoints(realpath, procMountInfoPath)
} }
func (mounter *Mounter) GetSELinuxSupport(pathname string) (bool, error) { func (mounter *Mounter) GetSELinuxSupport(pathname string) (bool, error) {
return getSELinuxSupport(pathname, procMountInfoPath) return GetSELinux(pathname, procMountInfoPath)
} }
func (mounter *Mounter) GetFSGroup(pathname string) (int64, error) { func (mounter *Mounter) GetFSGroup(pathname string) (int64, error) {
@ -743,15 +748,16 @@ func (mounter *Mounter) GetFSGroup(pathname string) (int64, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
return getFSGroup(realpath) return GetFSGroupLinux(realpath)
} }
func (mounter *Mounter) GetMode(pathname string) (os.FileMode, error) { func (mounter *Mounter) GetMode(pathname string) (os.FileMode, error) {
return getMode(pathname) return GetModeLinux(pathname)
} }
// This implementation is shared between Linux and NsEnterMounter // GetFSGroupLinux is shared between Linux and NsEnterMounter
func getFSGroup(pathname string) (int64, error) { // pathname must already be evaluated for symlinks
func GetFSGroupLinux(pathname string) (int64, error) {
info, err := os.Stat(pathname) info, err := os.Stat(pathname)
if err != nil { if err != nil {
return 0, err return 0, err
@ -759,8 +765,8 @@ func getFSGroup(pathname string) (int64, error) {
return int64(info.Sys().(*syscall.Stat_t).Gid), nil return int64(info.Sys().(*syscall.Stat_t).Gid), nil
} }
// This implementation is shared between Linux and NsEnterMounter // GetModeLinux is shared between Linux and NsEnterMounter
func getMode(pathname string) (os.FileMode, error) { func GetModeLinux(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
@ -768,14 +774,14 @@ func getMode(pathname string) (os.FileMode, error) {
return info.Mode(), nil return info.Mode(), nil
} }
// searchMountPoints finds all mount references to the source, returns a list of // SearchMountPoints finds all mount references to the source, returns a list of
// mountpoints. // mountpoints.
// This function assumes source cannot be device. // This function assumes source cannot be device.
// Some filesystems may share a source name, e.g. tmpfs. And for bind mounting, // Some filesystems may share a source name, e.g. tmpfs. And for bind mounting,
// it's possible to mount a non-root path of a filesystem, so we need to use // it's possible to mount a non-root path of a filesystem, so we need to use
// 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

View File

@ -631,7 +631,7 @@ func TestGetSELinuxSupport(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
out, err := getSELinuxSupport(test.mountPoint, filename) out, err := GetSELinux(test.mountPoint, filename)
if err != nil { if err != nil {
t.Errorf("Test %s failed with error: %s", test.name, err) t.Errorf("Test %s failed with error: %s", test.name, err)
} }
@ -907,7 +907,7 @@ func TestSearchMountPoints(t *testing.T) {
tmpFile.Seek(0, 0) tmpFile.Seek(0, 0)
tmpFile.WriteString(v.mountInfos) tmpFile.WriteString(v.mountInfos)
tmpFile.Sync() tmpFile.Sync()
refs, err := searchMountPoints(v.source, tmpFile.Name()) refs, err := SearchMountPoints(v.source, tmpFile.Name())
if !reflect.DeepEqual(refs, v.expectedRefs) { if !reflect.DeepEqual(refs, v.expectedRefs) {
t.Errorf("test %q: expected Refs: %#v, got %#v", v.name, v.expectedRefs, refs) t.Errorf("test %q: expected Refs: %#v, got %#v", v.name, v.expectedRefs, refs)
} }

View File

@ -43,7 +43,7 @@ func TestIsBind(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
bind, bindOpts, bindRemountOpts := isBind(test.mountOption) bind, bindOpts, bindRemountOpts := IsBind(test.mountOption)
if bind != test.isBind { if bind != test.isBind {
t.Errorf("Expected bind to be %v but got %v", test.isBind, bind) t.Errorf("Expected bind to be %v but got %v", test.isBind, bind)
} }

View File

@ -54,10 +54,6 @@ func (mounter *Mounter) IsMountPointMatch(mp MountPoint, dir string) bool {
return (mp.Path == dir) return (mp.Path == dir)
} }
func (mounter *Mounter) IsNotMountPoint(dir string) (bool, error) {
return isNotMountPoint(mounter, dir)
}
func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) { func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
return true, unsupportedErr return true, unsupportedErr
} }

View File

@ -72,7 +72,7 @@ func (mounter *Mounter) Mount(source string, target string, fstype string, optio
bindSource := source bindSource := source
// tell it's going to mount azure disk or azure file according to options // tell it's going to mount azure disk or azure file according to options
if bind, _, _ := isBind(options); bind { if bind, _, _ := IsBind(options); bind {
// mount azure disk // mount azure disk
bindSource = normalizeWindowsPath(source) bindSource = normalizeWindowsPath(source)
} else { } else {
@ -173,11 +173,6 @@ func (mounter *Mounter) IsMountPointMatch(mp MountPoint, dir string) bool {
return mp.Path == dir return mp.Path == dir
} }
// IsNotMountPoint determines if a directory is a mountpoint.
func (mounter *Mounter) IsNotMountPoint(dir string) (bool, error) {
return isNotMountPoint(mounter, dir)
}
// IsLikelyNotMountPoint determines if a directory is not a mountpoint. // IsLikelyNotMountPoint determines if a directory is not a mountpoint.
func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) { func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
stat, err := os.Lstat(file) stat, err := os.Lstat(file)

View File

@ -441,7 +441,7 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
return fmt.Errorf("invalid path: %s %v", m.globalPath, err) return fmt.Errorf("invalid path: %s %v", m.globalPath, err)
} }
notMnt, err := m.mounter.IsNotMountPoint(dir) notMnt, err := mount.IsNotMountPoint(m.mounter, dir)
klog.V(4).Infof("LocalVolume mount setup: PodDir(%s) VolDir(%s) Mounted(%t) Error(%v), ReadOnly(%t)", dir, m.globalPath, !notMnt, err, m.readOnly) klog.V(4).Infof("LocalVolume mount setup: PodDir(%s) VolDir(%s) Mounted(%t) Error(%v), ReadOnly(%t)", dir, m.globalPath, !notMnt, err, m.readOnly)
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
klog.Errorf("cannot validate mount point: %s %v", dir, err) klog.Errorf("cannot validate mount point: %s %v", dir, err)
@ -492,7 +492,7 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
err = m.mounter.Mount(globalPath, dir, "", mountOptions) err = m.mounter.Mount(globalPath, dir, "", mountOptions)
if err != nil { if err != nil {
klog.Errorf("Mount of volume %s failed: %v", dir, err) klog.Errorf("Mount of volume %s failed: %v", dir, err)
notMnt, mntErr := m.mounter.IsNotMountPoint(dir) notMnt, mntErr := mount.IsNotMountPoint(m.mounter, dir)
if mntErr != nil { if mntErr != nil {
klog.Errorf("IsNotMountPoint check failed: %v", mntErr) klog.Errorf("IsNotMountPoint check failed: %v", mntErr)
return err return err
@ -502,7 +502,7 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
klog.Errorf("Failed to unmount: %v", mntErr) klog.Errorf("Failed to unmount: %v", mntErr)
return err return err
} }
notMnt, mntErr = m.mounter.IsNotMountPoint(dir) notMnt, mntErr = mount.IsNotMountPoint(m.mounter, dir)
if mntErr != nil { if mntErr != nil {
klog.Errorf("IsNotMountPoint check failed: %v", mntErr) klog.Errorf("IsNotMountPoint check failed: %v", mntErr)
return err return err

View File

@ -238,7 +238,7 @@ func (b *nfsMounter) SetUp(fsGroup *int64) error {
} }
func (b *nfsMounter) SetUpAt(dir string, fsGroup *int64) error { func (b *nfsMounter) SetUpAt(dir string, fsGroup *int64) error {
notMnt, err := b.mounter.IsNotMountPoint(dir) notMnt, err := mount.IsNotMountPoint(b.mounter, dir)
klog.V(4).Infof("NFS mount set up: %s %v %v", dir, !notMnt, err) klog.V(4).Infof("NFS mount set up: %s %v %v", dir, !notMnt, err)
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
return err return err
@ -257,7 +257,7 @@ func (b *nfsMounter) SetUpAt(dir string, fsGroup *int64) error {
mountOptions := util.JoinMountOptions(b.mountOptions, options) mountOptions := util.JoinMountOptions(b.mountOptions, options)
err = b.mounter.Mount(source, dir, "nfs", mountOptions) err = b.mounter.Mount(source, dir, "nfs", mountOptions)
if err != nil { if err != nil {
notMnt, mntErr := b.mounter.IsNotMountPoint(dir) notMnt, mntErr := mount.IsNotMountPoint(b.mounter, dir)
if mntErr != nil { if mntErr != nil {
klog.Errorf("IsNotMountPoint check failed: %v", mntErr) klog.Errorf("IsNotMountPoint check failed: %v", mntErr)
return err return err
@ -267,7 +267,7 @@ func (b *nfsMounter) SetUpAt(dir string, fsGroup *int64) error {
klog.Errorf("Failed to unmount: %v", mntErr) klog.Errorf("Failed to unmount: %v", mntErr)
return err return err
} }
notMnt, mntErr := b.mounter.IsNotMountPoint(dir) notMnt, mntErr := mount.IsNotMountPoint(b.mounter, dir)
if mntErr != nil { if mntErr != nil {
klog.Errorf("IsNotMountPoint check failed: %v", mntErr) klog.Errorf("IsNotMountPoint check failed: %v", mntErr)
return err return err

View File

@ -86,6 +86,7 @@ filegroup(
":package-srcs", ":package-srcs",
"//pkg/volume/util/fs:all-srcs", "//pkg/volume/util/fs:all-srcs",
"//pkg/volume/util/nestedpendingoperations:all-srcs", "//pkg/volume/util/nestedpendingoperations:all-srcs",
"//pkg/volume/util/nsenter: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",
"//pkg/volume/util/subpath:all-srcs", "//pkg/volume/util/subpath:all-srcs",

View File

@ -0,0 +1,86 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"nsenter_mount.go",
"nsenter_mount_unsupported.go",
],
importpath = "k8s.io/kubernetes/pkg/volume/util/nsenter",
visibility = ["//visibility:public"],
deps = select({
"@io_bazel_rules_go//go/platform:android": [
"//pkg/util/mount:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:darwin": [
"//pkg/util/mount:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:dragonfly": [
"//pkg/util/mount:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:freebsd": [
"//pkg/util/mount:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:linux": [
"//pkg/util/mount:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
"//vendor/k8s.io/utils/path:go_default_library",
],
"@io_bazel_rules_go//go/platform:nacl": [
"//pkg/util/mount:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:netbsd": [
"//pkg/util/mount:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:openbsd": [
"//pkg/util/mount:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:plan9": [
"//pkg/util/mount:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:solaris": [
"//pkg/util/mount:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:windows": [
"//pkg/util/mount:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"//conditions:default": [],
}),
)
go_test(
name = "go_default_test",
srcs = ["nsenter_mount_test.go"],
embed = [":go_default_library"],
deps = select({
"@io_bazel_rules_go//go/platform:linux": [
"//vendor/k8s.io/utils/nsenter: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

@ -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 nsenter
import ( import (
"fmt" "fmt"
@ -25,6 +25,7 @@ import (
"strings" "strings"
"k8s.io/klog" "k8s.io/klog"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/utils/nsenter" "k8s.io/utils/nsenter"
utilpath "k8s.io/utils/path" utilpath "k8s.io/utils/path"
) )
@ -54,12 +55,12 @@ func NewNsenterMounter(rootDir string, ne *nsenter.Nsenter) *NsenterMounter {
} }
// NsenterMounter implements mount.Interface // NsenterMounter implements mount.Interface
var _ = Interface(&NsenterMounter{}) var _ = mount.Interface(&NsenterMounter{})
// Mount runs mount(8) in the host's root mount namespace. Aside from this // Mount runs mount(8) in the host's root mount namespace. Aside from this
// aspect, Mount has the same semantics as the mounter returned by mount.New() // aspect, Mount has the same semantics as the mounter returned by mount.New()
func (n *NsenterMounter) Mount(source string, target string, fstype string, options []string) error { func (n *NsenterMounter) Mount(source string, target string, fstype string, options []string) error {
bind, bindOpts, bindRemountOpts := isBind(options) bind, bindOpts, bindRemountOpts := mount.IsBind(options)
if bind { if bind {
err := n.doNsenterMount(source, target, fstype, bindOpts) err := n.doNsenterMount(source, target, fstype, bindOpts)
@ -88,7 +89,7 @@ func (n *NsenterMounter) doNsenterMount(source, target, fstype string, options [
// requested mount. // requested mount.
func (n *NsenterMounter) makeNsenterArgs(source, target, fstype string, options []string) (string, []string) { func (n *NsenterMounter) makeNsenterArgs(source, target, fstype string, options []string) (string, []string) {
mountCmd := n.ne.AbsHostPath("mount") mountCmd := n.ne.AbsHostPath("mount")
mountArgs := makeMountArgs(source, target, fstype, options) mountArgs := mount.MakeMountArgs(source, target, fstype, options)
if systemdRunPath, hasSystemd := n.ne.SupportsSystemd(); hasSystemd { if systemdRunPath, hasSystemd := n.ne.SupportsSystemd(); hasSystemd {
// Complete command line: // Complete command line:
@ -106,7 +107,7 @@ func (n *NsenterMounter) makeNsenterArgs(source, target, fstype string, options
// Kubelet container can be restarted and the fuse daemon survives. // Kubelet container can be restarted and the fuse daemon survives.
// * When the daemon dies (e.g. during unmount) systemd removes the // * When the daemon dies (e.g. during unmount) systemd removes the
// scope automatically. // scope automatically.
mountCmd, mountArgs = addSystemdScope(systemdRunPath, target, mountCmd, mountArgs) mountCmd, mountArgs = mount.AddSystemdScope(systemdRunPath, target, mountCmd, mountArgs)
} else { } else {
// Fall back to simple mount when the host has no systemd. // Fall back to simple mount when the host has no systemd.
// Complete command line: // Complete command line:
@ -138,15 +139,11 @@ func (n *NsenterMounter) Unmount(target string) error {
} }
// List returns a list of all mounted filesystems in the host's mount namespace. // List returns a list of all mounted filesystems in the host's mount namespace.
func (*NsenterMounter) List() ([]MountPoint, error) { func (*NsenterMounter) List() ([]mount.MountPoint, error) {
return listProcMounts(hostProcMountsPath) return mount.ListProcMounts(hostProcMountsPath)
} }
func (m *NsenterMounter) IsNotMountPoint(dir string) (bool, error) { func (*NsenterMounter) IsMountPointMatch(mp mount.MountPoint, dir string) bool {
return isNotMountPoint(m, dir)
}
func (*NsenterMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
deletedDir := fmt.Sprintf("%s\\040(deleted)", dir) deletedDir := fmt.Sprintf("%s\\040(deleted)", dir)
return (mp.Path == dir) || (mp.Path == deletedDir) return (mp.Path == dir) || (mp.Path == deletedDir)
} }
@ -217,28 +214,28 @@ func parseFindMnt(out string) (string, error) {
// Returns an error if errno is any error other than EBUSY. // Returns an error if errno is any error other than EBUSY.
// Returns with error if pathname is not a device. // Returns with error if pathname is not a device.
func (n *NsenterMounter) DeviceOpened(pathname string) (bool, error) { func (n *NsenterMounter) DeviceOpened(pathname string) (bool, error) {
return exclusiveOpenFailsOnDevice(pathname) return mount.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 (n *NsenterMounter) PathIsDevice(pathname string) (bool, error) { func (n *NsenterMounter) PathIsDevice(pathname string) (bool, error) {
pathType, err := n.GetFileType(pathname) pathType, err := n.GetFileType(pathname)
isDevice := pathType == FileTypeCharDev || pathType == FileTypeBlockDev isDevice := pathType == mount.FileTypeCharDev || pathType == mount.FileTypeBlockDev
return isDevice, err return isDevice, err
} }
//GetDeviceNameFromMount given a mount point, find the volume id from checking /proc/mounts //GetDeviceNameFromMount given a mount point, find the volume id from checking /proc/mounts
func (n *NsenterMounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) { func (n *NsenterMounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) {
return getDeviceNameFromMount(n, mountPath, pluginDir) return mount.GetDeviceNameFromMountLinux(n, mountPath, pluginDir)
} }
func (n *NsenterMounter) MakeRShared(path string) error { func (n *NsenterMounter) MakeRShared(path string) error {
return doMakeRShared(path, hostProcMountinfoPath) return mount.DoMakeRShared(path, hostProcMountinfoPath)
} }
func (mounter *NsenterMounter) GetFileType(pathname string) (FileType, error) { func (mounter *NsenterMounter) GetFileType(pathname string) (mount.FileType, error) {
var pathType FileType var pathType mount.FileType
outputBytes, err := mounter.ne.Exec("stat", []string{"-L", "--printf=%F", pathname}).CombinedOutput() outputBytes, err := mounter.ne.Exec("stat", []string{"-L", "--printf=%F", pathname}).CombinedOutput()
if err != nil { if err != nil {
if strings.Contains(string(outputBytes), "No such file") { if strings.Contains(string(outputBytes), "No such file") {
@ -251,15 +248,15 @@ func (mounter *NsenterMounter) GetFileType(pathname string) (FileType, error) {
switch string(outputBytes) { switch string(outputBytes) {
case "socket": case "socket":
return FileTypeSocket, nil return mount.FileTypeSocket, nil
case "character special file": case "character special file":
return FileTypeCharDev, nil return mount.FileTypeCharDev, nil
case "block special file": case "block special file":
return FileTypeBlockDev, nil return mount.FileTypeBlockDev, nil
case "directory": case "directory":
return FileTypeDirectory, nil return mount.FileTypeDirectory, nil
case "regular file": case "regular file":
return FileTypeFile, nil return mount.FileTypeFile, nil
} }
return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device") return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device")
@ -297,8 +294,8 @@ func (mounter *NsenterMounter) EvalHostSymlinks(pathname string) (string, error)
} }
func (mounter *NsenterMounter) GetMountRefs(pathname string) ([]string, error) { func (mounter *NsenterMounter) GetMountRefs(pathname string) ([]string, error) {
pathExists, pathErr := PathExists(pathname) pathExists, pathErr := mount.PathExists(pathname)
if !pathExists || IsCorruptedMnt(pathErr) { if !pathExists || mount.IsCorruptedMnt(pathErr) {
return []string{}, nil return []string{}, nil
} else if pathErr != nil { } else if pathErr != nil {
return nil, fmt.Errorf("Error checking path %s: %v", pathname, pathErr) return nil, fmt.Errorf("Error checking path %s: %v", pathname, pathErr)
@ -307,7 +304,7 @@ func (mounter *NsenterMounter) GetMountRefs(pathname string) ([]string, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return searchMountPoints(hostpath, hostProcMountinfoPath) return mount.SearchMountPoints(hostpath, hostProcMountinfoPath)
} }
func (mounter *NsenterMounter) GetFSGroup(pathname string) (int64, error) { func (mounter *NsenterMounter) GetFSGroup(pathname string) (int64, error) {
@ -316,11 +313,11 @@ func (mounter *NsenterMounter) GetFSGroup(pathname string) (int64, error) {
return -1, err return -1, err
} }
kubeletpath := mounter.ne.KubeletPath(hostPath) kubeletpath := mounter.ne.KubeletPath(hostPath)
return getFSGroup(kubeletpath) return mount.GetFSGroupLinux(kubeletpath)
} }
func (mounter *NsenterMounter) GetSELinuxSupport(pathname string) (bool, error) { func (mounter *NsenterMounter) GetSELinuxSupport(pathname string) (bool, error) {
return getSELinuxSupport(pathname, hostProcMountsPath) return mount.GetSELinux(pathname, hostProcMountsPath)
} }
func (mounter *NsenterMounter) GetMode(pathname string) (os.FileMode, error) { func (mounter *NsenterMounter) GetMode(pathname string) (os.FileMode, error) {
@ -329,5 +326,5 @@ func (mounter *NsenterMounter) GetMode(pathname string) (os.FileMode, error) {
return 0, err return 0, err
} }
kubeletpath := mounter.ne.KubeletPath(hostPath) kubeletpath := mounter.ne.KubeletPath(hostPath)
return getMode(kubeletpath) return mount.GetModeLinux(kubeletpath)
} }

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 nsenter
import ( import (
"io/ioutil" "io/ioutil"

View File

@ -16,13 +16,15 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package mount package nsenter
import ( import (
"errors" "errors"
"os" "os"
"k8s.io/utils/nsenter" "k8s.io/utils/nsenter"
"k8s.io/kubernetes/pkg/util/mount"
) )
type NsenterMounter struct{} type NsenterMounter struct{}
@ -31,7 +33,7 @@ func NewNsenterMounter(rootDir string, ne *nsenter.Nsenter) *NsenterMounter {
return &NsenterMounter{} return &NsenterMounter{}
} }
var _ = Interface(&NsenterMounter{}) var _ = mount.Interface(&NsenterMounter{})
func (*NsenterMounter) Mount(source string, target string, fstype string, options []string) error { func (*NsenterMounter) Mount(source string, target string, fstype string, options []string) error {
return nil return nil
@ -41,15 +43,11 @@ func (*NsenterMounter) Unmount(target string) error {
return nil return nil
} }
func (*NsenterMounter) List() ([]MountPoint, error) { func (*NsenterMounter) List() ([]mount.MountPoint, error) {
return []MountPoint{}, nil return []mount.MountPoint{}, nil
} }
func (m *NsenterMounter) IsNotMountPoint(dir string) (bool, error) { func (*NsenterMounter) IsMountPointMatch(mp mount.MountPoint, dir string) bool {
return isNotMountPoint(m, dir)
}
func (*NsenterMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
return (mp.Path == dir) return (mp.Path == dir)
} }
@ -73,8 +71,8 @@ func (*NsenterMounter) MakeRShared(path string) error {
return nil return nil
} }
func (*NsenterMounter) GetFileType(_ string) (FileType, error) { func (*NsenterMounter) GetFileType(_ string) (mount.FileType, error) {
return FileType("fake"), errors.New("not implemented") return mount.FileType("fake"), errors.New("not implemented")
} }
func (*NsenterMounter) MakeDir(pathname string) error { func (*NsenterMounter) MakeDir(pathname string) error {

View File

@ -74,6 +74,7 @@ go_test(
deps = select({ deps = select({
"@io_bazel_rules_go//go/platform:linux": [ "@io_bazel_rules_go//go/platform:linux": [
"//pkg/util/mount:go_default_library", "//pkg/util/mount:go_default_library",
"//pkg/volume/util/nsenter:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library", "//vendor/golang.org/x/sys/unix:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library", "//vendor/k8s.io/utils/nsenter:go_default_library",

View File

@ -101,7 +101,7 @@ func safeOpenSubPath(mounter mount.Interface, subpath Subpath) (int, error) {
func prepareSubpathTarget(mounter mount.Interface, subpath Subpath) (bool, string, error) { func prepareSubpathTarget(mounter mount.Interface, subpath Subpath) (bool, string, error) {
// Early check for already bind-mounted subpath. // Early check for already bind-mounted subpath.
bindPathTarget := getSubpathBindTarget(subpath) bindPathTarget := getSubpathBindTarget(subpath)
notMount, err := mounter.IsNotMountPoint(bindPathTarget) notMount, err := mount.IsNotMountPoint(mounter, bindPathTarget)
if err != nil { if err != nil {
if !os.IsNotExist(err) { if !os.IsNotExist(err) {
return false, "", fmt.Errorf("error checking path %s for mount: %s", bindPathTarget, err) return false, "", fmt.Errorf("error checking path %s for mount: %s", bindPathTarget, err)

View File

@ -29,7 +29,7 @@ import (
"k8s.io/utils/nsenter" "k8s.io/utils/nsenter"
"k8s.io/kubernetes/pkg/util/mount" nsutil "k8s.io/kubernetes/pkg/volume/util/nsenter"
) )
func TestCheckDeviceInode(t *testing.T) { func TestCheckDeviceInode(t *testing.T) {
@ -106,7 +106,7 @@ func TestCheckDeviceInode(t *testing.T) {
} }
} }
func newFakeNsenterMounter(tmpdir string, t *testing.T) (*mount.NsenterMounter, string, string, *nsenter.Nsenter, error) { func newFakeNsenterMounter(tmpdir string, t *testing.T) (*nsutil.NsenterMounter, string, string, *nsenter.Nsenter, error) {
rootfsPath := filepath.Join(tmpdir, "rootfs") rootfsPath := filepath.Join(tmpdir, "rootfs")
if err := os.Mkdir(rootfsPath, 0755); err != nil { if err := os.Mkdir(rootfsPath, 0755); err != nil {
return nil, "", "", nil, err return nil, "", "", nil, err
@ -121,7 +121,7 @@ func newFakeNsenterMounter(tmpdir string, t *testing.T) (*mount.NsenterMounter,
return nil, "", "", nil, err return nil, "", "", nil, err
} }
return mount.NewNsenterMounter(varlibPath, ne), rootfsPath, varlibPath, ne, nil return nsutil.NewNsenterMounter(varlibPath, ne), rootfsPath, varlibPath, ne, nil
} }
func TestNsenterSafeMakeDir(t *testing.T) { func TestNsenterSafeMakeDir(t *testing.T) {