Fix pkg/volume/util/nsenter linting errors

k3s-v1.15.3
Travis Rhoden 2019-04-08 10:43:54 -06:00
parent 1c045a09db
commit 2253807760
5 changed files with 111 additions and 65 deletions

View File

@ -374,7 +374,7 @@ func UnsecuredDependencies(s *options.KubeletServer) (*kubelet.Dependencies, err
if err != nil {
return nil, err
}
mounter = nsutil.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

@ -37,29 +37,30 @@ 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 _ = mount.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 {
func (n *Mounter) Mount(source string, target string, fstype string, options []string) error {
bind, bindOpts, bindRemountOpts := mount.IsBind(options)
if bind {
@ -75,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()
@ -87,7 +88,7 @@ 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 := mount.MakeMountArgs(source, target, fstype, options)
@ -125,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)
@ -139,18 +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() ([]mount.MountPoint, error) {
func (*Mounter) List() ([]mount.MountPoint, error) {
return mount.ListProcMounts(hostProcMountsPath)
}
func (*NsenterMounter) IsMountPointMatch(mp mount.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
@ -213,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) {
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 == 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) {
func (n *Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) {
return mount.GetDeviceNameFromMountLinux(n, mountPath, pluginDir)
}
func (n *NsenterMounter) MakeRShared(path string) error {
// MakeRShared checks if path is shared and bind-mounts it as rshared if needed.
func (n *Mounter) MakeRShared(path string) error {
return mount.DoMakeRShared(path, hostProcMountinfoPath)
}
func (mounter *NsenterMounter) GetFileType(pathname string) (mount.FileType, error) {
// GetFileType checks for file/directory/socket/block/character devices.
func (n *Mounter) GetFileType(pathname string) (mount.FileType, error) {
var pathType mount.FileType
outputBytes, err := mounter.ne.Exec("stat", []string{"-L", "--printf=%F", pathname}).CombinedOutput()
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)
@ -262,69 +266,80 @@ func (mounter *NsenterMounter) GetFileType(pathname string) (mount.FileType, err
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) {
// 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 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)
kubeletpath := n.ne.KubeletPath(hostPath)
return mount.GetFSGroupLinux(kubeletpath)
}
func (mounter *NsenterMounter) GetSELinuxSupport(pathname string) (bool, error) {
// 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)
kubeletpath := n.ne.KubeletPath(hostPath)
return mount.GetModeLinux(kubeletpath)
}

View File

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

@ -27,82 +27,113 @@ import (
"k8s.io/kubernetes/pkg/util/mount"
)
type NsenterMounter struct{}
// Mounter provides the mount.Interface implementation for unsupported
// platforms.
type Mounter struct{}
func NewNsenterMounter(rootDir string, ne *nsenter.Nsenter) *NsenterMounter {
return &NsenterMounter{}
// NewMounter returns a new Mounter for the current system
func NewMounter(rootDir string, ne *nsenter.Nsenter) *Mounter {
return &Mounter{}
}
var _ = mount.Interface(&NsenterMounter{})
var _ = mount.Interface(&Mounter{})
func (*NsenterMounter) Mount(source string, target string, fstype string, options []string) error {
// 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
}
func (*NsenterMounter) Unmount(target string) error {
// Unmount unmounts the target path from the system. it is a noop for unsupported
// systems
func (*Mounter) Unmount(target string) error {
return nil
}
func (*NsenterMounter) List() ([]mount.MountPoint, error) {
// 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
}
func (*NsenterMounter) IsMountPointMatch(mp mount.MountPoint, dir string) bool {
// IsMountPointMatch tests if dir and mp are the same path
func (*Mounter) IsMountPointMatch(mp mount.MountPoint, dir string) bool {
return (mp.Path == dir)
}
func (*NsenterMounter) IsLikelyNotMountPoint(file string) (bool, error) {
// 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
}
func (*NsenterMounter) DeviceOpened(pathname string) (bool, error) {
// DeviceOpened checks if block device in use. I tis a noop for unsupported systems
func (*Mounter) DeviceOpened(pathname string) (bool, error) {
return false, nil
}
func (*NsenterMounter) PathIsDevice(pathname string) (bool, error) {
// 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
}
func (*NsenterMounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) {
// 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
}
func (*NsenterMounter) MakeRShared(path string) error {
// 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
}
func (*NsenterMounter) GetFileType(_ string) (mount.FileType, error) {
// 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")
}
func (*NsenterMounter) MakeDir(pathname string) error {
// MakeDir creates a new directory. Noop on unsupported platforms
func (*Mounter) MakeDir(pathname string) error {
return nil
}
func (*NsenterMounter) MakeFile(pathname string) error {
// MakeFile creats an empty file. Noop on unsupported platforms
func (*Mounter) MakeFile(pathname string) error {
return nil
}
func (*NsenterMounter) ExistsPath(pathname string) (bool, error) {
// 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")
}
func (*NsenterMounter) EvalHostSymlinks(pathname string) (string, error) {
// 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")
}
func (*NsenterMounter) GetMountRefs(pathname string) ([]string, error) {
// 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")
}
func (*NsenterMounter) GetFSGroup(pathname string) (int64, error) {
// 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")
}
func (*NsenterMounter) GetSELinuxSupport(pathname string) (bool, error) {
// 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")
}
func (*NsenterMounter) GetMode(pathname string) (os.FileMode, error) {
// 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

@ -106,7 +106,7 @@ func TestCheckDeviceInode(t *testing.T) {
}
}
func newFakeNsenterMounter(tmpdir string, t *testing.T) (*nsutil.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) (*nsutil.NsenterMounter,
return nil, "", "", nil, err
}
return nsutil.NewNsenterMounter(varlibPath, ne), rootfsPath, varlibPath, ne, nil
return nsutil.NewMounter(varlibPath, ne), rootfsPath, varlibPath, ne, nil
}
func TestNsenterSafeMakeDir(t *testing.T) {