mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
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:
parent
aa52140928
commit
1c045a09db
@ -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.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
|
||||||
|
@ -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",
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
@ -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)
|
||||||
}
|
}
|
@ -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"
|
@ -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 {
|
@ -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.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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user