Merge pull request #76047 from codenrhoden/mv-nsenter-mount

Move nsenter mounter to pkg/volume/util/nsenter
This commit is contained in:
Kubernetes Prow Robot 2019-04-09 09:55:59 -07:00 committed by GitHub
commit c62cd6e3a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 375 additions and 295 deletions

View File

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

View File

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

View File

@ -15,8 +15,6 @@ go_library(
"mount_linux.go",
"mount_unsupported.go",
"mount_windows.go",
"nsenter_mount.go",
"nsenter_mount_unsupported.go",
],
importpath = "k8s.io/kubernetes/pkg/util/mount",
visibility = ["//visibility:public"],
@ -24,42 +22,13 @@ go_library(
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
] + 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": [
"//vendor/golang.org/x/sys/unix: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",
],
"@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": [
"//vendor/k8s.io/utils/keymutex:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
"//vendor/k8s.io/utils/path:go_default_library",
],
"//conditions:default": [],
@ -74,7 +43,6 @@ go_test(
"mount_linux_test.go",
"mount_test.go",
"mount_windows_test.go",
"nsenter_mount_test.go",
"safe_format_and_mount_test.go",
],
embed = [":go_default_library"],
@ -83,7 +51,6 @@ go_test(
] + select({
"@io_bazel_rules_go//go/platform:linux": [
"//vendor/k8s.io/utils/exec:go_default_library",
"//vendor/k8s.io/utils/nsenter:go_default_library",
],
"@io_bazel_rules_go//go/platform:windows": [
"//vendor/github.com/stretchr/testify/assert:go_default_library",

View File

@ -44,7 +44,7 @@ var _ Interface = &execMounter{}
// Mount runs mount(8) using given exec interface.
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 {
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.
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)
mountArgs := makeMountArgs(source, target, fstype, options)
mountArgs := MakeMountArgs(source, target, fstype, options)
output, err := m.exec.Run("mount", mountArgs...)
klog.V(5).Infof("Exec mounted %v: %v: %s", mountArgs, err, string(output))
if err != nil {
@ -116,10 +116,6 @@ func (m *execMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
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 {
return m.wrappedMounter.MakeRShared(path)
}

View File

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

View File

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

View File

@ -50,14 +50,6 @@ type Interface interface {
List() ([]MountPoint, error)
// IsMountPointMatch determines if the mountpoint matches the dir
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
// is a mountpoint.
// 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
}
// isNotMountPoint implements Mounter.IsNotMountPoint and is shared by mounter
// implementations.
func isNotMountPoint(mounter Interface, file string) (bool, error) {
// 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
func IsNotMountPoint(mounter Interface, file string) (bool, error) {
// IsLikelyNotMountPoint provides a quick check
// to determine whether file IS A mountpoint
notMnt, notMntErr := mounter.IsLikelyNotMountPoint(file)
@ -263,11 +260,11 @@ func isNotMountPoint(mounter Interface, file string) (bool, error) {
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.
// The list equals:
// 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
// needs to be included, otherwise the mount target will error as busy if you
// remount as readonly.

View File

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

View File

@ -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.
// All Linux distros are expected to be shipped with a mount utility that a support bind mounts.
mounterPath := ""
bind, bindOpts, bindRemountOpts := isBind(options)
bind, bindOpts, bindRemountOpts := IsBind(options)
if bind {
err := mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindOpts)
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.
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 {
mountArgs = append([]string{mountCmd}, mountArgs...)
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
// (CentOS 7, Debian Jessie).
mountCmd, mountArgs = addSystemdScope("systemd-run", target, mountCmd, mountArgs)
mountCmd, mountArgs = AddSystemdScope("systemd-run", target, mountCmd, mountArgs)
} else {
// No systemd-run on the host (or we failed to check it), assume kubelet
// does not run as a systemd service.
@ -176,8 +176,9 @@ func detectSystemd() bool {
return true
}
// makeMountArgs makes the arguments to the mount(8) command.
func makeMountArgs(source, target, fstype string, options []string) []string {
// MakeMountArgs makes the arguments to the mount(8) command.
// Implementation is shared with NsEnterMounter
func MakeMountArgs(source, target, fstype string, options []string) []string {
// Build mount command as follows:
// mount [-t $fstype] [-o $options] [$source] $target
mountArgs := []string{}
@ -195,8 +196,9 @@ func makeMountArgs(source, target, fstype string, options []string) []string {
return mountArgs
}
// addSystemdScope adds "system-run --scope" to given command line
func addSystemdScope(systemdRunPath, mountName, command string, args []string) (string, []string) {
// AddSystemdScope adds "system-run --scope" to given command line
// 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)
systemdRunArgs := []string{descriptionArg, "--scope", "--", command}
return systemdRunPath, append(systemdRunArgs, args...)
@ -215,7 +217,7 @@ func (mounter *Mounter) Unmount(target string) error {
// List returns a list of all mounted filesystems.
func (*Mounter) List() ([]MountPoint, error) {
return listProcMounts(procMountsPath)
return ListProcMounts(procMountsPath)
}
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))
}
func (mounter *Mounter) IsNotMountPoint(dir string) (bool, error) {
return isNotMountPoint(mounter, dir)
}
// IsLikelyNotMountPoint determines if a directory is not a mountpoint.
// 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.
@ -256,7 +254,7 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
// If open returns nil, return false with nil error.
// Otherwise, return false with 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
@ -267,7 +265,8 @@ func (mounter *Mounter) PathIsDevice(pathname string) (bool, error) {
return isDevice, err
}
func exclusiveOpenFailsOnDevice(pathname string) (bool, error) {
// ExclusiveOpenFailsOnDevice is shared with NsEnterMounter
func ExclusiveOpenFailsOnDevice(pathname string) (bool, error) {
var isDevice bool
finfo, err := os.Stat(pathname)
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
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
// 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)
if err != nil {
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
}
func listProcMounts(mountFilePath string) ([]MountPoint, error) {
// ListProcMounts is shared with NsEnterMounter
func ListProcMounts(mountFilePath string) ([]MountPoint, error) {
content, err := utilio.ConsistentRead(mountFilePath, maxListTries)
if err != nil {
return nil, err
@ -383,7 +388,7 @@ func parseProcMounts(content []byte) ([]MountPoint, error) {
}
func (mounter *Mounter) MakeRShared(path string) error {
return doMakeRShared(path, procMountInfoPath)
return DoMakeRShared(path, procMountInfoPath)
}
func (mounter *Mounter) GetFileType(pathname string) (FileType, error) {
@ -672,11 +677,11 @@ func findMountInfo(path, mountInfoPath string) (mountInfo, error) {
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
// 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.
func doMakeRShared(path string, mountInfoFilename string) error {
func DoMakeRShared(path string, mountInfoFilename string) error {
shared, err := isShared(path, mountInfoFilename)
if err != nil {
return err
@ -700,8 +705,8 @@ func doMakeRShared(path string, mountInfoFilename string) error {
return nil
}
// getSELinuxSupport is common implementation of GetSELinuxSupport on Linux.
func getSELinuxSupport(path string, mountInfoFilename string) (bool, error) {
// GetSELinux is common implementation of GetSELinuxSupport on Linux.
func GetSELinux(path string, mountInfoFilename string) (bool, error) {
info, err := findMountInfo(path, mountInfoFilename)
if err != nil {
return false, err
@ -735,11 +740,11 @@ func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
if err != nil {
return nil, err
}
return searchMountPoints(realpath, procMountInfoPath)
return SearchMountPoints(realpath, procMountInfoPath)
}
func (mounter *Mounter) GetSELinuxSupport(pathname string) (bool, error) {
return getSELinuxSupport(pathname, procMountInfoPath)
return GetSELinux(pathname, procMountInfoPath)
}
func (mounter *Mounter) GetFSGroup(pathname string) (int64, error) {
@ -747,15 +752,16 @@ func (mounter *Mounter) GetFSGroup(pathname string) (int64, error) {
if err != nil {
return 0, err
}
return getFSGroup(realpath)
return GetFSGroupLinux(realpath)
}
func (mounter *Mounter) GetMode(pathname string) (os.FileMode, error) {
return getMode(pathname)
return GetModeLinux(pathname)
}
// This implementation is shared between Linux and NsEnterMounter
func getFSGroup(pathname string) (int64, error) {
// GetFSGroupLinux is shared between Linux and NsEnterMounter
// pathname must already be evaluated for symlinks
func GetFSGroupLinux(pathname string) (int64, error) {
info, err := os.Stat(pathname)
if err != nil {
return 0, err
@ -763,8 +769,8 @@ func getFSGroup(pathname string) (int64, error) {
return int64(info.Sys().(*syscall.Stat_t).Gid), nil
}
// This implementation is shared between Linux and NsEnterMounter
func getMode(pathname string) (os.FileMode, error) {
// GetModeLinux is shared between Linux and NsEnterMounter
func GetModeLinux(pathname string) (os.FileMode, error) {
info, err := os.Stat(pathname)
if err != nil {
return 0, err
@ -772,14 +778,14 @@ func getMode(pathname string) (os.FileMode, error) {
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.
// This function assumes source cannot be device.
// 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
// root path and major:minor to represent mount source uniquely.
// This implementation is shared between Linux and NsEnterMounter
func searchMountPoints(hostSource, mountInfoPath string) ([]string, error) {
func SearchMountPoints(hostSource, mountInfoPath string) ([]string, error) {
mis, err := parseMountInfo(mountInfoPath)
if err != nil {
return nil, err

View File

@ -631,7 +631,7 @@ func TestGetSELinuxSupport(t *testing.T) {
}
for _, test := range tests {
out, err := getSELinuxSupport(test.mountPoint, filename)
out, err := GetSELinux(test.mountPoint, filename)
if err != nil {
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.WriteString(v.mountInfos)
tmpFile.Sync()
refs, err := searchMountPoints(v.source, tmpFile.Name())
refs, err := SearchMountPoints(v.source, tmpFile.Name())
if !reflect.DeepEqual(refs, v.expectedRefs) {
t.Errorf("test %q: expected Refs: %#v, got %#v", v.name, v.expectedRefs, refs)
}

View File

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

View File

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

View File

@ -72,7 +72,7 @@ func (mounter *Mounter) Mount(source string, target string, fstype string, optio
bindSource := source
// 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
bindSource = normalizeWindowsPath(source)
} else {
@ -173,11 +173,6 @@ func (mounter *Mounter) IsMountPointMatch(mp MountPoint, dir string) bool {
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.
func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
stat, err := os.Lstat(file)

View 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")
}

View File

@ -441,7 +441,7 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
return fmt.Errorf("invalid path: %s %v", m.globalPath, err)
}
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)
if err != nil && !os.IsNotExist(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)
if err != nil {
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 {
klog.Errorf("IsNotMountPoint check failed: %v", mntErr)
return err
@ -502,7 +502,7 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
klog.Errorf("Failed to unmount: %v", mntErr)
return err
}
notMnt, mntErr = m.mounter.IsNotMountPoint(dir)
notMnt, mntErr = mount.IsNotMountPoint(m.mounter, dir)
if mntErr != nil {
klog.Errorf("IsNotMountPoint check failed: %v", mntErr)
return err

View File

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

View File

@ -86,6 +86,7 @@ filegroup(
":package-srcs",
"//pkg/volume/util/fs:all-srcs",
"//pkg/volume/util/nestedpendingoperations:all-srcs",
"//pkg/volume/util/nsenter:all-srcs",
"//pkg/volume/util/operationexecutor:all-srcs",
"//pkg/volume/util/recyclerclient:all-srcs",
"//pkg/volume/util/subpath:all-srcs",

View File

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

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package mount
package nsenter
import (
"fmt"
@ -25,6 +25,7 @@ import (
"strings"
"k8s.io/klog"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/utils/nsenter"
utilpath "k8s.io/utils/path"
)
@ -36,30 +37,31 @@ const (
hostProcMountinfoPath = "/rootfs/proc/1/mountinfo"
)
// Mounter implements mount.Interface
// 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.
type NsenterMounter struct {
type Mounter struct {
ne *nsenter.Nsenter
// rootDir is location of /var/lib/kubelet directory.
rootDir string
}
// NewNsenterMounter creates a new mounter for kubelet that runs as a container.
func NewNsenterMounter(rootDir string, ne *nsenter.Nsenter) *NsenterMounter {
return &NsenterMounter{
// NewMounter creates a new mounter for kubelet that runs as a container.
func NewMounter(rootDir string, ne *nsenter.Nsenter) *Mounter {
return &Mounter{
rootDir: rootDir,
ne: ne,
}
}
// NsenterMounter implements mount.Interface
var _ = Interface(&NsenterMounter{})
// Mounter implements mount.Interface
var _ = mount.Interface(&Mounter{})
// 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()
func (n *NsenterMounter) Mount(source string, target string, fstype string, options []string) error {
bind, bindOpts, bindRemountOpts := isBind(options)
func (n *Mounter) Mount(source string, target string, fstype string, options []string) error {
bind, bindOpts, bindRemountOpts := mount.IsBind(options)
if bind {
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
// 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)
cmd, args := n.makeNsenterArgs(source, target, fstype, options)
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
// 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")
mountArgs := makeMountArgs(source, target, fstype, options)
mountArgs := mount.MakeMountArgs(source, target, fstype, options)
if systemdRunPath, hasSystemd := n.ne.SupportsSystemd(); hasSystemd {
// 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.
// * When the daemon dies (e.g. during unmount) systemd removes the
// scope automatically.
mountCmd, mountArgs = addSystemdScope(systemdRunPath, target, mountCmd, mountArgs)
mountCmd, mountArgs = mount.AddSystemdScope(systemdRunPath, target, mountCmd, mountArgs)
} else {
// Fall back to simple mount when the host has no systemd.
// 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.
func (n *NsenterMounter) Unmount(target string) error {
func (n *Mounter) Unmount(target string) error {
args := []string{target}
// 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)
@ -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.
func (*NsenterMounter) List() ([]MountPoint, error) {
return listProcMounts(hostProcMountsPath)
func (*Mounter) List() ([]mount.MountPoint, error) {
return mount.ListProcMounts(hostProcMountsPath)
}
func (m *NsenterMounter) IsNotMountPoint(dir string) (bool, error) {
return isNotMountPoint(m, dir)
}
func (*NsenterMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
// IsMountPointMatch tests if dir and mp are the same path
func (*Mounter) IsMountPointMatch(mp mount.MountPoint, dir string) bool {
deletedDir := fmt.Sprintf("%s\\040(deleted)", dir)
return (mp.Path == dir) || (mp.Path == deletedDir)
}
// IsLikelyNotMountPoint determines whether a path is a mountpoint by calling findmnt
// 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)
if err != nil {
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 an error if errno is any error other than EBUSY.
// Returns with error if pathname is not a device.
func (n *NsenterMounter) DeviceOpened(pathname string) (bool, error) {
return exclusiveOpenFailsOnDevice(pathname)
func (n *Mounter) DeviceOpened(pathname string) (bool, error) {
return mount.ExclusiveOpenFailsOnDevice(pathname)
}
// PathIsDevice uses FileInfo returned from os.Stat to check if path refers
// to a device.
func (n *NsenterMounter) PathIsDevice(pathname string) (bool, error) {
func (n *Mounter) PathIsDevice(pathname string) (bool, error) {
pathType, err := n.GetFileType(pathname)
isDevice := pathType == FileTypeCharDev || pathType == FileTypeBlockDev
isDevice := pathType == mount.FileTypeCharDev || pathType == mount.FileTypeBlockDev
return isDevice, err
}
//GetDeviceNameFromMount given a mount point, find the volume id from checking /proc/mounts
func (n *NsenterMounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) {
return getDeviceNameFromMount(n, mountPath, pluginDir)
func (n *Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) {
return mount.GetDeviceNameFromMountLinux(n, mountPath, pluginDir)
}
func (n *NsenterMounter) MakeRShared(path string) error {
return doMakeRShared(path, hostProcMountinfoPath)
// MakeRShared checks if path is shared and bind-mounts it as rshared if needed.
func (n *Mounter) MakeRShared(path string) error {
return mount.DoMakeRShared(path, hostProcMountinfoPath)
}
func (mounter *NsenterMounter) GetFileType(pathname string) (FileType, error) {
var pathType FileType
outputBytes, err := mounter.ne.Exec("stat", []string{"-L", "--printf=%F", pathname}).CombinedOutput()
// GetFileType checks for file/directory/socket/block/character devices.
func (n *Mounter) GetFileType(pathname string) (mount.FileType, error) {
var pathType mount.FileType
outputBytes, err := n.ne.Exec("stat", []string{"-L", "--printf=%F", pathname}).CombinedOutput()
if err != nil {
if strings.Contains(string(outputBytes), "No such file") {
err = fmt.Errorf("%s does not exist", pathname)
@ -251,83 +252,94 @@ func (mounter *NsenterMounter) GetFileType(pathname string) (FileType, error) {
switch string(outputBytes) {
case "socket":
return FileTypeSocket, nil
return mount.FileTypeSocket, nil
case "character special file":
return FileTypeCharDev, nil
return mount.FileTypeCharDev, nil
case "block special file":
return FileTypeBlockDev, nil
return mount.FileTypeBlockDev, nil
case "directory":
return FileTypeDirectory, nil
return mount.FileTypeDirectory, nil
case "regular file":
return FileTypeFile, nil
return mount.FileTypeFile, nil
}
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}
if _, err := mounter.ne.Exec("mkdir", args).CombinedOutput(); err != nil {
if _, err := n.ne.Exec("mkdir", args).CombinedOutput(); err != nil {
return err
}
return nil
}
func (mounter *NsenterMounter) MakeFile(pathname string) error {
// MakeFile creates an empty file.
func (n *Mounter) MakeFile(pathname string) error {
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 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
// 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 {
return false, err
}
kubeletpath := mounter.ne.KubeletPath(hostPath)
kubeletpath := n.ne.KubeletPath(hostPath)
return utilpath.Exists(utilpath.CheckFollowSymlink, kubeletpath)
}
func (mounter *NsenterMounter) EvalHostSymlinks(pathname string) (string, error) {
return mounter.ne.EvalSymlinks(pathname, true)
// EvalHostSymlinks returns the path name after evaluating symlinks.
func (n *Mounter) EvalHostSymlinks(pathname string) (string, error) {
return n.ne.EvalSymlinks(pathname, true)
}
func (mounter *NsenterMounter) GetMountRefs(pathname string) ([]string, error) {
pathExists, pathErr := PathExists(pathname)
if !pathExists || IsCorruptedMnt(pathErr) {
// GetMountRefs finds all mount references to the path, returns a
// list of paths. Path could be a mountpoint path, device or a normal
// 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
} else if pathErr != nil {
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 {
return nil, err
}
return searchMountPoints(hostpath, hostProcMountinfoPath)
return mount.SearchMountPoints(hostpath, hostProcMountinfoPath)
}
func (mounter *NsenterMounter) GetFSGroup(pathname string) (int64, error) {
hostPath, err := mounter.ne.EvalSymlinks(pathname, true /* mustExist */)
// GetFSGroup returns FSGroup of pathname.
func (n *Mounter) GetFSGroup(pathname string) (int64, error) {
hostPath, err := n.ne.EvalSymlinks(pathname, true /* mustExist */)
if err != nil {
return -1, err
}
kubeletpath := mounter.ne.KubeletPath(hostPath)
return getFSGroup(kubeletpath)
kubeletpath := n.ne.KubeletPath(hostPath)
return mount.GetFSGroupLinux(kubeletpath)
}
func (mounter *NsenterMounter) GetSELinuxSupport(pathname string) (bool, error) {
return getSELinuxSupport(pathname, hostProcMountsPath)
// GetSELinuxSupport tests if pathname is on a mount that supports SELinux.
func (n *Mounter) GetSELinuxSupport(pathname string) (bool, error) {
return mount.GetSELinux(pathname, hostProcMountsPath)
}
func (mounter *NsenterMounter) GetMode(pathname string) (os.FileMode, error) {
hostPath, err := mounter.ne.EvalSymlinks(pathname, true /* mustExist */)
// GetMode returns permissions of pathname.
func (n *Mounter) GetMode(pathname string) (os.FileMode, error) {
hostPath, err := n.ne.EvalSymlinks(pathname, true /* mustExist */)
if err != nil {
return 0, err
}
kubeletpath := mounter.ne.KubeletPath(hostPath)
return getMode(kubeletpath)
kubeletpath := n.ne.KubeletPath(hostPath)
return mount.GetModeLinux(kubeletpath)
}

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package mount
package nsenter
import (
"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")
if err := os.Mkdir(rootfsPath, 0755); err != nil {
return nil, "", "", err
@ -89,7 +89,7 @@ func newFakeNsenterMounter(tmpdir string, t *testing.T) (mounter *NsenterMounter
return nil, "", "", err
}
return NewNsenterMounter(varlibPath, ne), rootfsPath, varlibPath, nil
return NewMounter(varlibPath, ne), rootfsPath, varlibPath, nil
}
func TestNsenterExistsFile(t *testing.T) {

View 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")
}

View File

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

View File

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

View File

@ -29,7 +29,7 @@ import (
"k8s.io/utils/nsenter"
"k8s.io/kubernetes/pkg/util/mount"
nsutil "k8s.io/kubernetes/pkg/volume/util/nsenter"
)
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")
if err := os.Mkdir(rootfsPath, 0755); err != nil {
return nil, "", "", nil, err
@ -121,7 +121,7 @@ func newFakeNsenterMounter(tmpdir string, t *testing.T) (*mount.NsenterMounter,
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) {