mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 20:53:33 +00:00
Merge pull request #76047 from codenrhoden/mv-nsenter-mount
Move nsenter mounter to pkg/volume/util/nsenter
This commit is contained in:
commit
c62cd6e3a4
@ -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",
|
||||||
|
@ -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.NewMounter(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
|
||||||
|
@ -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,42 +22,13 @@ 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": [
|
||||||
"//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": [],
|
||||||
@ -74,7 +43,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"],
|
||||||
@ -83,7 +51,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",
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,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 {
|
||||||
@ -103,7 +103,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
|
||||||
@ -132,7 +132,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.
|
||||||
@ -176,8 +176,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{}
|
||||||
@ -195,8 +196,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...)
|
||||||
@ -215,7 +217,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 {
|
||||||
@ -223,10 +225,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.
|
||||||
@ -256,7 +254,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
|
||||||
@ -267,7 +265,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) {
|
||||||
@ -306,13 +305,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)
|
||||||
@ -337,7 +341,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
|
||||||
@ -383,7 +388,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) {
|
||||||
@ -672,11 +677,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
|
||||||
@ -700,8 +705,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
|
||||||
@ -735,11 +740,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) {
|
||||||
@ -747,15 +752,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
|
||||||
@ -763,8 +769,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
|
||||||
@ -772,14 +778,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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
// +build !linux
|
|
||||||
|
|
||||||
/*
|
|
||||||
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 (
|
|
||||||
"errors"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"k8s.io/utils/nsenter"
|
|
||||||
)
|
|
||||||
|
|
||||||
type NsenterMounter struct{}
|
|
||||||
|
|
||||||
func NewNsenterMounter(rootDir string, ne *nsenter.Nsenter) *NsenterMounter {
|
|
||||||
return &NsenterMounter{}
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ = Interface(&NsenterMounter{})
|
|
||||||
|
|
||||||
func (*NsenterMounter) Mount(source string, target string, fstype string, options []string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) Unmount(target string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) List() ([]MountPoint, error) {
|
|
||||||
return []MountPoint{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *NsenterMounter) IsNotMountPoint(dir string) (bool, error) {
|
|
||||||
return isNotMountPoint(m, dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
|
|
||||||
return (mp.Path == dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) IsLikelyNotMountPoint(file string) (bool, error) {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) DeviceOpened(pathname string) (bool, error) {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) PathIsDevice(pathname string) (bool, error) {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) MakeRShared(path string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) GetFileType(_ string) (FileType, error) {
|
|
||||||
return FileType("fake"), errors.New("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) MakeDir(pathname string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) MakeFile(pathname string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) ExistsPath(pathname string) (bool, error) {
|
|
||||||
return true, errors.New("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) EvalHostSymlinks(pathname string) (string, error) {
|
|
||||||
return "", errors.New("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) GetMountRefs(pathname string) ([]string, error) {
|
|
||||||
return nil, errors.New("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) GetFSGroup(pathname string) (int64, error) {
|
|
||||||
return -1, errors.New("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) GetSELinuxSupport(pathname string) (bool, error) {
|
|
||||||
return false, errors.New("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NsenterMounter) GetMode(pathname string) (os.FileMode, error) {
|
|
||||||
return 0, errors.New("not implemented")
|
|
||||||
}
|
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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",
|
||||||
|
86
pkg/volume/util/nsenter/BUILD
Normal file
86
pkg/volume/util/nsenter/BUILD
Normal 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"],
|
||||||
|
)
|
@ -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"
|
||||||
)
|
)
|
||||||
@ -36,30 +37,31 @@ const (
|
|||||||
hostProcMountinfoPath = "/rootfs/proc/1/mountinfo"
|
hostProcMountinfoPath = "/rootfs/proc/1/mountinfo"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Mounter implements mount.Interface
|
||||||
// Currently, all docker containers receive their own mount namespaces.
|
// Currently, all docker containers receive their own mount namespaces.
|
||||||
// NsenterMounter works by executing nsenter to run commands in
|
// Mounter works by executing nsenter to run commands in
|
||||||
// the host's mount namespace.
|
// the host's mount namespace.
|
||||||
type NsenterMounter struct {
|
type Mounter struct {
|
||||||
ne *nsenter.Nsenter
|
ne *nsenter.Nsenter
|
||||||
// rootDir is location of /var/lib/kubelet directory.
|
// rootDir is location of /var/lib/kubelet directory.
|
||||||
rootDir string
|
rootDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNsenterMounter creates a new mounter for kubelet that runs as a container.
|
// NewMounter creates a new mounter for kubelet that runs as a container.
|
||||||
func NewNsenterMounter(rootDir string, ne *nsenter.Nsenter) *NsenterMounter {
|
func NewMounter(rootDir string, ne *nsenter.Nsenter) *Mounter {
|
||||||
return &NsenterMounter{
|
return &Mounter{
|
||||||
rootDir: rootDir,
|
rootDir: rootDir,
|
||||||
ne: ne,
|
ne: ne,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NsenterMounter implements mount.Interface
|
// Mounter implements mount.Interface
|
||||||
var _ = Interface(&NsenterMounter{})
|
var _ = mount.Interface(&Mounter{})
|
||||||
|
|
||||||
// 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 *Mounter) 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)
|
||||||
@ -74,7 +76,7 @@ func (n *NsenterMounter) Mount(source string, target string, fstype string, opti
|
|||||||
|
|
||||||
// doNsenterMount nsenters the host's mount namespace and performs the
|
// doNsenterMount nsenters the host's mount namespace and performs the
|
||||||
// requested mount.
|
// requested mount.
|
||||||
func (n *NsenterMounter) doNsenterMount(source, target, fstype string, options []string) error {
|
func (n *Mounter) doNsenterMount(source, target, fstype string, options []string) error {
|
||||||
klog.V(5).Infof("nsenter mount %s %s %s %v", source, target, fstype, options)
|
klog.V(5).Infof("nsenter mount %s %s %s %v", source, target, fstype, options)
|
||||||
cmd, args := n.makeNsenterArgs(source, target, fstype, options)
|
cmd, args := n.makeNsenterArgs(source, target, fstype, options)
|
||||||
outputBytes, err := n.ne.Exec(cmd, args).CombinedOutput()
|
outputBytes, err := n.ne.Exec(cmd, args).CombinedOutput()
|
||||||
@ -86,9 +88,9 @@ func (n *NsenterMounter) doNsenterMount(source, target, fstype string, options [
|
|||||||
|
|
||||||
// makeNsenterArgs makes a list of argument to nsenter in order to do the
|
// makeNsenterArgs makes a list of argument to nsenter in order to do the
|
||||||
// requested mount.
|
// requested mount.
|
||||||
func (n *NsenterMounter) makeNsenterArgs(source, target, fstype string, options []string) (string, []string) {
|
func (n *Mounter) 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 +108,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:
|
||||||
@ -124,7 +126,7 @@ func (n *NsenterMounter) makeNsenterArgs(source, target, fstype string, options
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unmount runs umount(8) in the host's mount namespace.
|
// Unmount runs umount(8) in the host's mount namespace.
|
||||||
func (n *NsenterMounter) Unmount(target string) error {
|
func (n *Mounter) Unmount(target string) error {
|
||||||
args := []string{target}
|
args := []string{target}
|
||||||
// No need to execute systemd-run here, it's enough that unmount is executed
|
// No need to execute systemd-run here, it's enough that unmount is executed
|
||||||
// in the host's mount namespace. It will finish appropriate fuse daemon(s)
|
// in the host's mount namespace. It will finish appropriate fuse daemon(s)
|
||||||
@ -138,22 +140,19 @@ 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 (*Mounter) List() ([]mount.MountPoint, error) {
|
||||||
return listProcMounts(hostProcMountsPath)
|
return mount.ListProcMounts(hostProcMountsPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *NsenterMounter) IsNotMountPoint(dir string) (bool, error) {
|
// IsMountPointMatch tests if dir and mp are the same path
|
||||||
return isNotMountPoint(m, dir)
|
func (*Mounter) IsMountPointMatch(mp mount.MountPoint, dir string) bool {
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsLikelyNotMountPoint determines whether a path is a mountpoint by calling findmnt
|
// IsLikelyNotMountPoint determines whether a path is a mountpoint by calling findmnt
|
||||||
// in the host's root mount namespace.
|
// in the host's root mount namespace.
|
||||||
func (n *NsenterMounter) IsLikelyNotMountPoint(file string) (bool, error) {
|
func (n *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
|
||||||
file, err := filepath.Abs(file)
|
file, err := filepath.Abs(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, err
|
return true, err
|
||||||
@ -216,30 +215,32 @@ func parseFindMnt(out string) (string, error) {
|
|||||||
// Returns true if open returns errno EBUSY, and false if errno is nil.
|
// Returns true if open returns errno EBUSY, and false if errno is nil.
|
||||||
// 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 *Mounter) 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 *Mounter) 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 *Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) {
|
||||||
return getDeviceNameFromMount(n, mountPath, pluginDir)
|
return mount.GetDeviceNameFromMountLinux(n, mountPath, pluginDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NsenterMounter) MakeRShared(path string) error {
|
// MakeRShared checks if path is shared and bind-mounts it as rshared if needed.
|
||||||
return doMakeRShared(path, hostProcMountinfoPath)
|
func (n *Mounter) MakeRShared(path string) error {
|
||||||
|
return mount.DoMakeRShared(path, hostProcMountinfoPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mounter *NsenterMounter) GetFileType(pathname string) (FileType, error) {
|
// GetFileType checks for file/directory/socket/block/character devices.
|
||||||
var pathType FileType
|
func (n *Mounter) GetFileType(pathname string) (mount.FileType, error) {
|
||||||
outputBytes, err := mounter.ne.Exec("stat", []string{"-L", "--printf=%F", pathname}).CombinedOutput()
|
var pathType mount.FileType
|
||||||
|
outputBytes, err := n.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") {
|
||||||
err = fmt.Errorf("%s does not exist", pathname)
|
err = fmt.Errorf("%s does not exist", pathname)
|
||||||
@ -251,83 +252,94 @@ 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")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mounter *NsenterMounter) MakeDir(pathname string) error {
|
// MakeDir creates a new directory.
|
||||||
|
func (n *Mounter) MakeDir(pathname string) error {
|
||||||
args := []string{"-p", pathname}
|
args := []string{"-p", pathname}
|
||||||
if _, err := mounter.ne.Exec("mkdir", args).CombinedOutput(); err != nil {
|
if _, err := n.ne.Exec("mkdir", args).CombinedOutput(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mounter *NsenterMounter) MakeFile(pathname string) error {
|
// MakeFile creates an empty file.
|
||||||
|
func (n *Mounter) MakeFile(pathname string) error {
|
||||||
args := []string{pathname}
|
args := []string{pathname}
|
||||||
if _, err := mounter.ne.Exec("touch", args).CombinedOutput(); err != nil {
|
if _, err := n.ne.Exec("touch", args).CombinedOutput(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mounter *NsenterMounter) ExistsPath(pathname string) (bool, error) {
|
// ExistsPath checks if pathname exists.
|
||||||
|
// Error is returned on any other error than "file not found".
|
||||||
|
func (n *Mounter) ExistsPath(pathname string) (bool, error) {
|
||||||
// Resolve the symlinks but allow the target not to exist. EvalSymlinks
|
// Resolve the symlinks but allow the target not to exist. EvalSymlinks
|
||||||
// would return an generic error when the target does not exist.
|
// would return an generic error when the target does not exist.
|
||||||
hostPath, err := mounter.ne.EvalSymlinks(pathname, false /* mustExist */)
|
hostPath, err := n.ne.EvalSymlinks(pathname, false /* mustExist */)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
kubeletpath := mounter.ne.KubeletPath(hostPath)
|
kubeletpath := n.ne.KubeletPath(hostPath)
|
||||||
return utilpath.Exists(utilpath.CheckFollowSymlink, kubeletpath)
|
return utilpath.Exists(utilpath.CheckFollowSymlink, kubeletpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mounter *NsenterMounter) EvalHostSymlinks(pathname string) (string, error) {
|
// EvalHostSymlinks returns the path name after evaluating symlinks.
|
||||||
return mounter.ne.EvalSymlinks(pathname, true)
|
func (n *Mounter) EvalHostSymlinks(pathname string) (string, error) {
|
||||||
|
return n.ne.EvalSymlinks(pathname, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mounter *NsenterMounter) GetMountRefs(pathname string) ([]string, error) {
|
// GetMountRefs finds all mount references to the path, returns a
|
||||||
pathExists, pathErr := PathExists(pathname)
|
// list of paths. Path could be a mountpoint path, device or a normal
|
||||||
if !pathExists || IsCorruptedMnt(pathErr) {
|
// directory (for bind mount).
|
||||||
|
func (n *Mounter) GetMountRefs(pathname string) ([]string, error) {
|
||||||
|
pathExists, pathErr := mount.PathExists(pathname)
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
hostpath, err := mounter.ne.EvalSymlinks(pathname, true /* mustExist */)
|
hostpath, err := n.ne.EvalSymlinks(pathname, true /* mustExist */)
|
||||||
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) {
|
// GetFSGroup returns FSGroup of pathname.
|
||||||
hostPath, err := mounter.ne.EvalSymlinks(pathname, true /* mustExist */)
|
func (n *Mounter) GetFSGroup(pathname string) (int64, error) {
|
||||||
|
hostPath, err := n.ne.EvalSymlinks(pathname, true /* mustExist */)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
kubeletpath := mounter.ne.KubeletPath(hostPath)
|
kubeletpath := n.ne.KubeletPath(hostPath)
|
||||||
return getFSGroup(kubeletpath)
|
return mount.GetFSGroupLinux(kubeletpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mounter *NsenterMounter) GetSELinuxSupport(pathname string) (bool, error) {
|
// GetSELinuxSupport tests if pathname is on a mount that supports SELinux.
|
||||||
return getSELinuxSupport(pathname, hostProcMountsPath)
|
func (n *Mounter) GetSELinuxSupport(pathname string) (bool, error) {
|
||||||
|
return mount.GetSELinux(pathname, hostProcMountsPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mounter *NsenterMounter) GetMode(pathname string) (os.FileMode, error) {
|
// GetMode returns permissions of pathname.
|
||||||
hostPath, err := mounter.ne.EvalSymlinks(pathname, true /* mustExist */)
|
func (n *Mounter) GetMode(pathname string) (os.FileMode, error) {
|
||||||
|
hostPath, err := n.ne.EvalSymlinks(pathname, true /* mustExist */)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
kubeletpath := mounter.ne.KubeletPath(hostPath)
|
kubeletpath := n.ne.KubeletPath(hostPath)
|
||||||
return getMode(kubeletpath)
|
return mount.GetModeLinux(kubeletpath)
|
||||||
}
|
}
|
@ -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"
|
||||||
@ -74,7 +74,7 @@ func TestParseFindMnt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFakeNsenterMounter(tmpdir string, t *testing.T) (mounter *NsenterMounter, rootfsPath string, varlibPath string, err error) {
|
func newFakeNsenterMounter(tmpdir string, t *testing.T) (mounter *Mounter, rootfsPath string, varlibPath string, err 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, "", "", err
|
return nil, "", "", err
|
||||||
@ -89,7 +89,7 @@ func newFakeNsenterMounter(tmpdir string, t *testing.T) (mounter *NsenterMounter
|
|||||||
return nil, "", "", err
|
return nil, "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewNsenterMounter(varlibPath, ne), rootfsPath, varlibPath, nil
|
return NewMounter(varlibPath, ne), rootfsPath, varlibPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNsenterExistsFile(t *testing.T) {
|
func TestNsenterExistsFile(t *testing.T) {
|
139
pkg/volume/util/nsenter/nsenter_mount_unsupported.go
Normal file
139
pkg/volume/util/nsenter/nsenter_mount_unsupported.go
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
// +build !linux
|
||||||
|
|
||||||
|
/*
|
||||||
|
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 nsenter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"k8s.io/utils/nsenter"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/util/mount"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Mounter provides the mount.Interface implementation for unsupported
|
||||||
|
// platforms.
|
||||||
|
type Mounter struct{}
|
||||||
|
|
||||||
|
// NewMounter returns a new Mounter for the current system
|
||||||
|
func NewMounter(rootDir string, ne *nsenter.Nsenter) *Mounter {
|
||||||
|
return &Mounter{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = mount.Interface(&Mounter{})
|
||||||
|
|
||||||
|
// Mount mounts the source to the target. It is a noop for unsupported systems
|
||||||
|
func (*Mounter) Mount(source string, target string, fstype string, options []string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmount unmounts the target path from the system. it is a noop for unsupported
|
||||||
|
// systems
|
||||||
|
func (*Mounter) Unmount(target string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns a list of all mounted filesystems. It is a noop for unsupported systems
|
||||||
|
func (*Mounter) List() ([]mount.MountPoint, error) {
|
||||||
|
return []mount.MountPoint{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsMountPointMatch tests if dir and mp are the same path
|
||||||
|
func (*Mounter) IsMountPointMatch(mp mount.MountPoint, dir string) bool {
|
||||||
|
return (mp.Path == dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsLikelyNotMountPoint determines if a directory is not a mountpoint.
|
||||||
|
// It is a noop on unsupported systems
|
||||||
|
func (*Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceOpened checks if block device in use. I tis a noop for unsupported systems
|
||||||
|
func (*Mounter) DeviceOpened(pathname string) (bool, error) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathIsDevice checks if pathname refers to a device. It is a noop for unsupported
|
||||||
|
// systems
|
||||||
|
func (*Mounter) PathIsDevice(pathname string) (bool, error) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDeviceNameFromMount finds the device name from its global mount point using the
|
||||||
|
// given mountpath and plugin location. It is a noop of unsupported platforms
|
||||||
|
func (*Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeRShared checks if path is shared and bind-mounts it as rshared if needed.
|
||||||
|
// It is a noop on unsupported platforms
|
||||||
|
func (*Mounter) MakeRShared(path string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFileType checks for file/directory/socket/block/character devices.
|
||||||
|
// Always returns an error and "fake" filetype on unsupported platforms
|
||||||
|
func (*Mounter) GetFileType(_ string) (mount.FileType, error) {
|
||||||
|
return mount.FileType("fake"), errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeDir creates a new directory. Noop on unsupported platforms
|
||||||
|
func (*Mounter) MakeDir(pathname string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeFile creats an empty file. Noop on unsupported platforms
|
||||||
|
func (*Mounter) MakeFile(pathname string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExistsPath checks if pathname exists. Always returns an error on unsupported
|
||||||
|
// platforms
|
||||||
|
func (*Mounter) ExistsPath(pathname string) (bool, error) {
|
||||||
|
return true, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// EvalHostSymlinks returns the path name after evaluating symlinks. Always
|
||||||
|
// returns an error on unsupported platforms
|
||||||
|
func (*Mounter) EvalHostSymlinks(pathname string) (string, error) {
|
||||||
|
return "", errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMountRefs finds all mount references to the path, returns a
|
||||||
|
// list of paths. Always returns an error on unsupported platforms
|
||||||
|
func (*Mounter) GetMountRefs(pathname string) ([]string, error) {
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFSGroup returns FSGroup of pathname. Always returns an error on unsupported platforms
|
||||||
|
func (*Mounter) GetFSGroup(pathname string) (int64, error) {
|
||||||
|
return -1, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSELinuxSupport tests if pathname is on a mount that supports SELinux.
|
||||||
|
// Always returns an error on unsupported platforms
|
||||||
|
func (*Mounter) GetSELinuxSupport(pathname string) (bool, error) {
|
||||||
|
return false, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMode returns permissions of pathname. Always returns an error on unsupported platforms
|
||||||
|
func (*Mounter) GetMode(pathname string) (os.FileMode, error) {
|
||||||
|
return 0, errors.New("not implemented")
|
||||||
|
}
|
@ -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",
|
||||||
|
@ -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)
|
||||||
|
@ -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.Mounter, 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.NewMounter(varlibPath, ne), rootfsPath, varlibPath, ne, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNsenterSafeMakeDir(t *testing.T) {
|
func TestNsenterSafeMakeDir(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user