mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Fix most linting issues in pkg/util/mount
This patch adds comments to exported items that were missing them in order to make the linter happy. Only code changes that were limited to the scope of this package were made. There are other linting issues that will effect callers, and that will be done a seperate patch.
This commit is contained in:
parent
072528e5f6
commit
b47184e954
@ -18,11 +18,12 @@ package mount
|
||||
|
||||
import "k8s.io/utils/exec"
|
||||
|
||||
// NewOsExec returns a new Exec interface implementation based on exec()
|
||||
func NewOsExec() Exec {
|
||||
return &osExec{}
|
||||
}
|
||||
|
||||
// Real implementation of Exec interface that uses simple util.Exec
|
||||
// Real implementation of Exec interface that uses simple utils.Exec
|
||||
type osExec struct{}
|
||||
|
||||
var _ Exec = &osExec{}
|
||||
@ -32,16 +33,18 @@ func (e *osExec) Run(cmd string, args ...string) ([]byte, error) {
|
||||
return exe.Command(cmd, args...).CombinedOutput()
|
||||
}
|
||||
|
||||
// NewFakeExec returns a new FakeExec
|
||||
func NewFakeExec(run runHook) *FakeExec {
|
||||
return &FakeExec{runHook: run}
|
||||
}
|
||||
|
||||
// Fake for testing.
|
||||
// FakeExec for testing.
|
||||
type FakeExec struct {
|
||||
runHook runHook
|
||||
}
|
||||
type runHook func(cmd string, args ...string) ([]byte, error)
|
||||
|
||||
// Run executes the command using the optional runhook, if given
|
||||
func (f *FakeExec) Run(cmd string, args ...string) ([]byte, error) {
|
||||
if f.runHook != nil {
|
||||
return f.runHook(cmd, args...)
|
||||
|
@ -38,9 +38,12 @@ type FakeMounter struct {
|
||||
|
||||
var _ Interface = &FakeMounter{}
|
||||
|
||||
// Values for FakeAction.Action
|
||||
const FakeActionMount = "mount"
|
||||
const FakeActionUnmount = "unmount"
|
||||
const (
|
||||
// FakeActionMount is the string for specifying mount as FakeAction.Action
|
||||
FakeActionMount = "mount"
|
||||
// FakeActionUnmount is the string for specifying unmount as FakeAction.Action
|
||||
FakeActionUnmount = "unmount"
|
||||
)
|
||||
|
||||
// FakeAction objects are logged every time a fake mount or unmount is called.
|
||||
type FakeAction struct {
|
||||
@ -50,6 +53,7 @@ type FakeAction struct {
|
||||
FSType string // applies only to "mount" actions
|
||||
}
|
||||
|
||||
// ResetLog clears all the log entries in FakeMounter
|
||||
func (f *FakeMounter) ResetLog() {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
@ -57,6 +61,7 @@ func (f *FakeMounter) ResetLog() {
|
||||
f.Log = []FakeAction{}
|
||||
}
|
||||
|
||||
// Mount records the mount event and updates the in-memory mount points for FakeMounter
|
||||
func (f *FakeMounter) Mount(source string, target string, fstype string, options []string) error {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
@ -99,6 +104,7 @@ func (f *FakeMounter) Mount(source string, target string, fstype string, options
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unmount records the unmount event and updates the in-memory mount points for FakeMounter
|
||||
func (f *FakeMounter) Unmount(target string) error {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
@ -124,6 +130,7 @@ func (f *FakeMounter) Unmount(target string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// List returns all the in-memory mountpoints for FakeMounter
|
||||
func (f *FakeMounter) List() ([]MountPoint, error) {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
@ -131,10 +138,13 @@ func (f *FakeMounter) List() ([]MountPoint, error) {
|
||||
return f.MountPoints, nil
|
||||
}
|
||||
|
||||
// IsMountPointMatch tests if dir and mp are the same path
|
||||
func (f *FakeMounter) IsMountPointMatch(mp MountPoint, dir string) bool {
|
||||
return mp.Path == dir
|
||||
}
|
||||
|
||||
// IsLikelyNotMountPoint determines whether a path is a mountpoint by checking
|
||||
// if the absolute path to file is in the in-memory mountpoints
|
||||
func (f *FakeMounter) IsLikelyNotMountPoint(file string) (bool, error) {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
@ -165,6 +175,8 @@ func (f *FakeMounter) IsLikelyNotMountPoint(file string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// GetMountRefs finds all mount references to the path, returns a
|
||||
// list of paths.
|
||||
func (f *FakeMounter) GetMountRefs(pathname string) ([]string, error) {
|
||||
realpath, err := filepath.EvalSymlinks(pathname)
|
||||
if err != nil {
|
||||
@ -174,6 +186,7 @@ func (f *FakeMounter) GetMountRefs(pathname string) ([]string, error) {
|
||||
return getMountRefsByDev(f, realpath)
|
||||
}
|
||||
|
||||
// FakeHostUtil is a fake mount.HostUtils implementation for testing
|
||||
type FakeHostUtil struct {
|
||||
MountPoints []MountPoint
|
||||
Filesystem map[string]FileType
|
||||
@ -183,6 +196,8 @@ type FakeHostUtil struct {
|
||||
|
||||
var _ HostUtils = &FakeHostUtil{}
|
||||
|
||||
// DeviceOpened checks if block device referenced by pathname is in use by
|
||||
// checking if is listed as a device in the in-memory mountpoint table.
|
||||
func (hu *FakeHostUtil) DeviceOpened(pathname string) (bool, error) {
|
||||
hu.mutex.Lock()
|
||||
defer hu.mutex.Unlock()
|
||||
@ -195,18 +210,24 @@ func (hu *FakeHostUtil) DeviceOpened(pathname string) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// PathIsDevice always returns true
|
||||
func (hu *FakeHostUtil) PathIsDevice(pathname string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// GetDeviceNameFromMount given a mount point, find the volume id
|
||||
func (hu *FakeHostUtil) GetDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) {
|
||||
return getDeviceNameFromMount(mounter, mountPath, pluginMountDir)
|
||||
}
|
||||
|
||||
// MakeRShared checks if path is shared and bind-mounts it as rshared if needed.
|
||||
// No-op for testing
|
||||
func (hu *FakeHostUtil) MakeRShared(path string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetFileType checks for file/directory/socket/block/character devices.
|
||||
// Defaults to Directory if otherwise unspecified.
|
||||
func (hu *FakeHostUtil) GetFileType(pathname string) (FileType, error) {
|
||||
if t, ok := hu.Filesystem[pathname]; ok {
|
||||
return t, nil
|
||||
@ -214,14 +235,19 @@ func (hu *FakeHostUtil) GetFileType(pathname string) (FileType, error) {
|
||||
return FileType("Directory"), nil
|
||||
}
|
||||
|
||||
// MakeDir creates a new directory.
|
||||
// No-op for testing
|
||||
func (hu *FakeHostUtil) MakeDir(pathname string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MakeFile creates a new file.
|
||||
// No-op for testing
|
||||
func (hu *FakeHostUtil) MakeFile(pathname string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExistsPath checks if pathname exists.
|
||||
func (hu *FakeHostUtil) ExistsPath(pathname string) (bool, error) {
|
||||
if _, ok := hu.Filesystem[pathname]; ok {
|
||||
return true, nil
|
||||
@ -229,18 +255,26 @@ func (hu *FakeHostUtil) ExistsPath(pathname string) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// EvalHostSymlinks returns the path name after evaluating symlinks.
|
||||
// No-op for testing
|
||||
func (hu *FakeHostUtil) EvalHostSymlinks(pathname string) (string, error) {
|
||||
return pathname, nil
|
||||
}
|
||||
|
||||
// GetFSGroup returns FSGroup of pathname.
|
||||
// Not implemented for testing
|
||||
func (hu *FakeHostUtil) GetFSGroup(pathname string) (int64, error) {
|
||||
return -1, errors.New("GetFSGroup not implemented")
|
||||
}
|
||||
|
||||
// GetSELinuxSupport tests if pathname is on a mount that supports SELinux.
|
||||
// Not implemented for testing
|
||||
func (hu *FakeHostUtil) GetSELinuxSupport(pathname string) (bool, error) {
|
||||
return false, errors.New("GetSELinuxSupport not implemented")
|
||||
}
|
||||
|
||||
// GetMode returns permissions of pathname.
|
||||
// Not implemented for testing
|
||||
func (hu *FakeHostUtil) GetMode(pathname string) (os.FileMode, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ limitations under the License.
|
||||
|
||||
// TODO(thockin): This whole pkg is pretty linux-centric. As soon as we have
|
||||
// an alternate platform, we will need to abstract further.
|
||||
|
||||
package mount
|
||||
|
||||
import (
|
||||
@ -25,32 +26,42 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// FileType enumerates the known set of possible file types.
|
||||
type FileType string
|
||||
|
||||
const (
|
||||
// Default mount command if mounter path is not specified
|
||||
defaultMountCommand = "mount"
|
||||
FileTypeDirectory FileType = "Directory"
|
||||
FileTypeFile FileType = "File"
|
||||
FileTypeSocket FileType = "Socket"
|
||||
FileTypeCharDev FileType = "CharDevice"
|
||||
FileTypeBlockDev FileType = "BlockDevice"
|
||||
// Default mount command if mounter path is not specified.
|
||||
defaultMountCommand = "mount"
|
||||
|
||||
// FileTypeBlockDev defines a constant for the block device FileType.
|
||||
FileTypeBlockDev FileType = "BlockDevice"
|
||||
// FileTypeCharDev defines a constant for the character device FileType.
|
||||
FileTypeCharDev FileType = "CharDevice"
|
||||
// FileTypeDirectory defines a constant for the directory FileType.
|
||||
FileTypeDirectory FileType = "Directory"
|
||||
// FileTypeFile defines a constant for the file FileType.
|
||||
FileTypeFile FileType = "File"
|
||||
// FileTypeSocket defines a constant for the socket FileType.
|
||||
FileTypeSocket FileType = "Socket"
|
||||
// FileTypeUnknown defines a constant for an unknown FileType.
|
||||
FileTypeUnknown FileType = ""
|
||||
)
|
||||
|
||||
// Interface defines the set of methods to allow for mount operations on a system.
|
||||
type Interface interface {
|
||||
// Mount mounts source to target as fstype with given options.
|
||||
Mount(source string, target string, fstype string, options []string) error
|
||||
// Unmount unmounts given target.
|
||||
Unmount(target string) error
|
||||
// List returns a list of all mounted filesystems. This can be large.
|
||||
// On some platforms, reading mounts is not guaranteed consistent (i.e.
|
||||
// it could change between chunked reads). This is guaranteed to be
|
||||
// consistent.
|
||||
// On some platforms, reading mounts directly from the OS is not guaranteed
|
||||
// consistent (i.e. it could change between chunked reads). This is guaranteed
|
||||
// to be consistent.
|
||||
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
|
||||
// IsLikelyNotMountPoint uses heuristics to determine if a directory
|
||||
// is a mountpoint.
|
||||
// is not a mountpoint.
|
||||
// It should return ErrNotExist when the directory does not exist.
|
||||
// IsLikelyNotMountPoint does NOT properly detect all mountpoint types
|
||||
// most notably linux bind mounts and symbolic link.
|
||||
@ -61,32 +72,28 @@ type Interface interface {
|
||||
GetMountRefs(pathname string) ([]string, error)
|
||||
}
|
||||
|
||||
// HostUtils defines the set of methods for interacting with paths on a host.
|
||||
type HostUtils interface {
|
||||
// DeviceOpened determines if the device is in use elsewhere
|
||||
// DeviceOpened determines if the device (e.g. /dev/sdc) is in use elsewhere
|
||||
// on the system, i.e. still mounted.
|
||||
DeviceOpened(pathname string) (bool, error)
|
||||
// PathIsDevice determines if a path is a device.
|
||||
PathIsDevice(pathname string) (bool, error)
|
||||
// GetDeviceNameFromMount finds the device name by checking the mount path
|
||||
// to get the global mount path within its plugin directory
|
||||
// to get the global mount path within its plugin directory.
|
||||
GetDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error)
|
||||
// MakeRShared checks that given path is on a mount with 'rshared' mount
|
||||
// propagation. If not, it bind-mounts the path as rshared.
|
||||
MakeRShared(path string) error
|
||||
// GetFileType checks for file/directory/socket/block/character devices.
|
||||
// Will operate in the host mount namespace if kubelet is running in a container
|
||||
GetFileType(pathname string) (FileType, error)
|
||||
// MakeFile creates an empty file.
|
||||
// Will operate in the host mount namespace if kubelet is running in a container
|
||||
MakeFile(pathname string) error
|
||||
// MakeDir creates a new directory.
|
||||
// Will operate in the host mount namespace if kubelet is running in a container
|
||||
MakeDir(pathname string) error
|
||||
// Will operate in the host mount namespace if kubelet is running in a container.
|
||||
// Error is returned on any other error than "file not found".
|
||||
ExistsPath(pathname string) (bool, error)
|
||||
// EvalHostSymlinks returns the path name after evaluating symlinks.
|
||||
// Will operate in the host mount namespace if kubelet is running in a container.
|
||||
EvalHostSymlinks(pathname string) (string, error)
|
||||
// GetFSGroup returns FSGroup of the path.
|
||||
GetFSGroup(pathname string) (int64, error)
|
||||
@ -97,25 +104,7 @@ type HostUtils interface {
|
||||
GetMode(pathname string) (os.FileMode, error)
|
||||
}
|
||||
|
||||
type Subpath struct {
|
||||
// index of the VolumeMount for this container
|
||||
VolumeMountIndex int
|
||||
// Full path to the subpath directory on the host
|
||||
Path string
|
||||
// name of the volume that is a valid directory name.
|
||||
VolumeName string
|
||||
// Full path to the volume path
|
||||
VolumePath string
|
||||
// Path to the pod's directory, including pod UID
|
||||
PodDir string
|
||||
// Name of the container
|
||||
ContainerName string
|
||||
}
|
||||
|
||||
// Exec executes command where mount utilities are. This can be either the host,
|
||||
// container where kubelet runs or even a remote pod with mount utilities.
|
||||
// Usual k8s.io/utils/exec interface is not used because kubelet.RunInContainer does
|
||||
// not provide stdin/stdout/stderr streams.
|
||||
// Exec is an interface for executing commands on systems.
|
||||
type Exec interface {
|
||||
// Run executes a command and returns its stdout + stderr combined in one
|
||||
// stream.
|
||||
@ -123,14 +112,14 @@ type Exec interface {
|
||||
}
|
||||
|
||||
// Compile-time check to ensure all Mounter implementations satisfy
|
||||
// the mount interface
|
||||
// the mount interface.
|
||||
var _ Interface = &Mounter{}
|
||||
|
||||
// Compile-time check to ensure all HostUtil implementations satisfy
|
||||
// the HostUtils Interface
|
||||
// the HostUtils Interface.
|
||||
var _ HostUtils = &hostUtil{}
|
||||
|
||||
// This represents a single line in /proc/mounts or /etc/fstab.
|
||||
// MountPoint represents a single line in /proc/mounts or /etc/fstab.
|
||||
type MountPoint struct {
|
||||
Device string
|
||||
Path string
|
||||
@ -166,7 +155,7 @@ func getMountRefsByDev(mounter Interface, mountPath string) ([]string, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Finding the device mounted to mountPath
|
||||
// Finding the device mounted to mountPath.
|
||||
diskDev := ""
|
||||
for i := range mps {
|
||||
if mountPath == mps[i].Path {
|
||||
@ -187,8 +176,8 @@ func getMountRefsByDev(mounter Interface, mountPath string) ([]string, error) {
|
||||
return refs, nil
|
||||
}
|
||||
|
||||
// GetDeviceNameFromMount: given a mnt point, find the device from /proc/mounts
|
||||
// returns the device name, reference count, and error code
|
||||
// GetDeviceNameFromMount given a mnt point, find the device from /proc/mounts
|
||||
// returns the device name, reference count, and error code.
|
||||
func GetDeviceNameFromMount(mounter Interface, mountPath string) (string, int, error) {
|
||||
mps, err := mounter.List()
|
||||
if err != nil {
|
||||
@ -196,7 +185,7 @@ func GetDeviceNameFromMount(mounter Interface, mountPath string) (string, int, e
|
||||
}
|
||||
|
||||
// Find the device name.
|
||||
// FIXME if multiple devices mounted on the same mount path, only the first one is returned
|
||||
// FIXME if multiple devices mounted on the same mount path, only the first one is returned.
|
||||
device := ""
|
||||
// If mountPath is symlink, need get its target path.
|
||||
slTarget, err := filepath.EvalSymlinks(mountPath)
|
||||
@ -226,10 +215,10 @@ func GetDeviceNameFromMount(mounter Interface, mountPath string) (string, int, e
|
||||
// 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
|
||||
// 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
|
||||
// to determine whether file IS A mountpoint.
|
||||
notMnt, notMntErr := mounter.IsLikelyNotMountPoint(file)
|
||||
if notMntErr != nil && os.IsPermission(notMntErr) {
|
||||
// We were not allowed to do the simple stat() check, e.g. on NFS with
|
||||
@ -240,12 +229,12 @@ func IsNotMountPoint(mounter Interface, file string) (bool, error) {
|
||||
if notMntErr != nil {
|
||||
return notMnt, notMntErr
|
||||
}
|
||||
// identified as mountpoint, so return this fact
|
||||
// identified as mountpoint, so return this fact.
|
||||
if notMnt == false {
|
||||
return notMnt, nil
|
||||
}
|
||||
|
||||
// Resolve any symlinks in file, kernel would do the same and use the resolved path in /proc/mounts
|
||||
// Resolve any symlinks in file, kernel would do the same and use the resolved path in /proc/mounts.
|
||||
hu := NewHostUtil()
|
||||
resolvedFile, err := hu.EvalHostSymlinks(file)
|
||||
if err != nil {
|
||||
@ -253,7 +242,7 @@ func IsNotMountPoint(mounter Interface, file string) (bool, error) {
|
||||
}
|
||||
|
||||
// check all mountpoints since IsLikelyNotMountPoint
|
||||
// is not reliable for some mountpoint types
|
||||
// is not reliable for some mountpoint types.
|
||||
mountPoints, mountPointsErr := mounter.List()
|
||||
if mountPointsErr != nil {
|
||||
return notMnt, mountPointsErr
|
||||
@ -312,6 +301,7 @@ func checkForNetDev(options []string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// HasMountRefs checks if the given mountPath has mountRefs.
|
||||
// TODO: this is a workaround for the unmount device issue caused by gci mounter.
|
||||
// In GCI cluster, if gci mounter is used for mounting, the container started by mounter
|
||||
// script will cause additional mounts created in the container. Since these mounts are
|
||||
@ -319,7 +309,6 @@ func checkForNetDev(options []string) bool {
|
||||
// mount references. Current solution is to filter out those mount paths that contain
|
||||
// the string of original mount path.
|
||||
// Plan to work on better approach to solve this issue.
|
||||
|
||||
func HasMountRefs(mountPath string, mountRefs []string) bool {
|
||||
for _, ref := range mountRefs {
|
||||
if !strings.Contains(ref, mountPath) {
|
||||
@ -336,19 +325,19 @@ func PathWithinBase(fullPath, basePath string) bool {
|
||||
return false
|
||||
}
|
||||
if StartsWithBackstep(rel) {
|
||||
// Needed to escape the base path
|
||||
// Needed to escape the base path.
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// StartsWithBackstep checks if the given path starts with a backstep segment
|
||||
// StartsWithBackstep checks if the given path starts with a backstep segment.
|
||||
func StartsWithBackstep(rel string) bool {
|
||||
// normalize to / and check for ../
|
||||
return rel == ".." || strings.HasPrefix(filepath.ToSlash(rel), "../")
|
||||
}
|
||||
|
||||
// getFileType checks for file/directory/socket and block/character devices
|
||||
// getFileType checks for file/directory/socket and block/character devices.
|
||||
func getFileType(pathname string) (FileType, error) {
|
||||
var pathType FileType
|
||||
info, err := os.Stat(pathname)
|
||||
@ -360,7 +349,7 @@ func getFileType(pathname string) (FileType, error) {
|
||||
return pathType, err
|
||||
}
|
||||
|
||||
// checks whether the mode is the target mode
|
||||
// checks whether the mode is the target mode.
|
||||
isSpecificMode := func(mode, targetMode os.FileMode) bool {
|
||||
return mode&targetMode == targetMode
|
||||
}
|
||||
|
@ -23,11 +23,10 @@ import (
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
// CleanupMountPoint unmounts the given path and
|
||||
// deletes the remaining directory if successful.
|
||||
// if extensiveMountPointCheck is true
|
||||
// IsNotMountPoint will be called instead of IsLikelyNotMountPoint.
|
||||
// IsNotMountPoint is more expensive but properly handles bind mounts within the same fs.
|
||||
// CleanupMountPoint unmounts the given path and deletes the remaining directory
|
||||
// if successful. If extensiveMountPointCheck is true IsNotMountPoint will be
|
||||
// called instead of IsLikelyNotMountPoint. IsNotMountPoint is more expensive
|
||||
// but properly handles bind mounts within the same fs.
|
||||
func CleanupMountPoint(mountPath string, mounter Interface, extensiveMountPointCheck bool) error {
|
||||
// mounter.ExistsPath cannot be used because for containerized kubelet, we need to check
|
||||
// the path in the kubelet container, not on the host.
|
||||
@ -87,8 +86,8 @@ func doCleanupMountPoint(mountPath string, mounter Interface, extensiveMountPoin
|
||||
return fmt.Errorf("Failed to unmount path %v", mountPath)
|
||||
}
|
||||
|
||||
// TODO: clean this up to use pkg/util/file/FileExists
|
||||
// PathExists returns true if the specified path exists.
|
||||
// TODO: clean this up to use pkg/util/file/FileExists
|
||||
func PathExists(path string) (bool, error) {
|
||||
_, err := os.Stat(path)
|
||||
if err == nil {
|
||||
@ -97,7 +96,6 @@ func PathExists(path string) (bool, error) {
|
||||
return false, nil
|
||||
} else if IsCorruptedMnt(err) {
|
||||
return true, err
|
||||
} else {
|
||||
return false, err
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
@ -102,14 +102,14 @@ 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 {
|
||||
func (mounter *Mounter) doMount(mounterPath string, mountCmd string, source string, target string, fstype string, options []string) error {
|
||||
mountArgs := MakeMountArgs(source, target, fstype, options)
|
||||
if len(mounterPath) > 0 {
|
||||
mountArgs = append([]string{mountCmd}, mountArgs...)
|
||||
mountCmd = mounterPath
|
||||
}
|
||||
|
||||
if m.withSystemd {
|
||||
if mounter.withSystemd {
|
||||
// Try to run mount via systemd-run --scope. This will escape the
|
||||
// service where kubelet runs and any fuse daemons will be started in a
|
||||
// specific scope. kubelet service than can be restarted without killing
|
||||
@ -145,7 +145,7 @@ func (m *Mounter) doMount(mounterPath string, mountCmd string, source string, ta
|
||||
if err != nil {
|
||||
args := strings.Join(mountArgs, " ")
|
||||
klog.Errorf("Mount failed: %v\nMounting command: %s\nMounting arguments: %s\nOutput: %s\n", err, mountCmd, args, string(output))
|
||||
return fmt.Errorf("mount failed: %v\nMounting command: %s\nMounting arguments: %s\nOutput: %s\n",
|
||||
return fmt.Errorf("mount failed: %v\nMounting command: %s\nMounting arguments: %s\nOutput: %s",
|
||||
err, mountCmd, args, string(output))
|
||||
}
|
||||
return err
|
||||
@ -210,7 +210,7 @@ func (mounter *Mounter) Unmount(target string) error {
|
||||
command := exec.Command("umount", target)
|
||||
output, err := command.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unmount failed: %v\nUnmounting arguments: %s\nOutput: %s\n", err, target, string(output))
|
||||
return fmt.Errorf("unmount failed: %v\nUnmounting arguments: %s\nOutput: %s", err, target, string(output))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -220,6 +220,7 @@ func (*Mounter) List() ([]MountPoint, error) {
|
||||
return ListProcMounts(procMountsPath)
|
||||
}
|
||||
|
||||
// IsMountPointMatch returns true if the path in mp is the same as dir
|
||||
func (mounter *Mounter) IsMountPointMatch(mp MountPoint, dir string) bool {
|
||||
deletedDir := fmt.Sprintf("%s\\040(deleted)", dir)
|
||||
return ((mp.Path == dir) || (mp.Path == deletedDir))
|
||||
@ -249,6 +250,9 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// GetMountRefs finds all mount references to pathname, returns a
|
||||
// list of paths. Path could be a mountpoint path, device or a normal
|
||||
// directory (for bind mount).
|
||||
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
|
||||
pathExists, pathErr := PathExists(pathname)
|
||||
if !pathExists {
|
||||
@ -291,7 +295,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
|
||||
case isExitError && ee.ExitStatus() == fsckErrorsCorrected:
|
||||
klog.Infof("Device %s has errors which were corrected by fsck.", source)
|
||||
case isExitError && ee.ExitStatus() == fsckErrorsUncorrected:
|
||||
return fmt.Errorf("'fsck' found errors on device %s but could not correct them: %s.", source, string(out))
|
||||
return fmt.Errorf("'fsck' found errors on device %s but could not correct them: %s", source, string(out))
|
||||
case isExitError && ee.ExitStatus() > fsckErrorsUncorrected:
|
||||
klog.Infof("`fsck` error %s", string(out))
|
||||
}
|
||||
@ -337,16 +341,14 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
|
||||
}
|
||||
klog.Errorf("format of disk %q failed: type:(%q) target:(%q) options:(%q)error:(%v)", source, fstype, target, options, err)
|
||||
return err
|
||||
} else {
|
||||
// Disk is already formatted and failed to mount
|
||||
if len(fstype) == 0 || fstype == existingFormat {
|
||||
// This is mount error
|
||||
return mountErr
|
||||
} else {
|
||||
// Block device is formatted with unexpected filesystem, let the user know
|
||||
return fmt.Errorf("failed to mount the volume as %q, it already contains %s. Mount error: %v", fstype, existingFormat, mountErr)
|
||||
}
|
||||
}
|
||||
// Disk is already formatted and failed to mount
|
||||
if len(fstype) == 0 || fstype == existingFormat {
|
||||
// This is mount error
|
||||
return mountErr
|
||||
}
|
||||
// Block device is formatted with unexpected filesystem, let the user know
|
||||
return fmt.Errorf("failed to mount the volume as %q, it already contains %s. Mount error: %v", fstype, existingFormat, mountErr)
|
||||
}
|
||||
return mountErr
|
||||
}
|
||||
@ -453,6 +455,8 @@ func parseProcMounts(content []byte) ([]MountPoint, error) {
|
||||
type hostUtil struct {
|
||||
}
|
||||
|
||||
// NewHostUtil returns a struct that implements the HostUtils interface on
|
||||
// linux platforms
|
||||
func NewHostUtil() HostUtils {
|
||||
return &hostUtil{}
|
||||
}
|
||||
@ -668,7 +672,7 @@ func parseMountInfo(filename string) ([]mountInfo, error) {
|
||||
info.optionalFields = append(info.optionalFields, fields[i])
|
||||
}
|
||||
// Parse the rest 3 fields.
|
||||
i += 1
|
||||
i++
|
||||
if len(fields)-i < 3 {
|
||||
return nil, fmt.Errorf("expect 3 fields in %s, got %d", line, len(fields)-i)
|
||||
}
|
||||
|
@ -23,11 +23,12 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// Mounter implements mount.Interface for unsupported platforms
|
||||
type Mounter struct {
|
||||
mounterPath string
|
||||
}
|
||||
|
||||
var unsupportedErr = errors.New("util/mount on this platform is not supported")
|
||||
var errUnsupported = errors.New("util/mount on this platform is not supported")
|
||||
|
||||
// New returns a mount.Interface for the current system.
|
||||
// It provides options to override the default mounter behavior.
|
||||
@ -38,28 +39,34 @@ func New(mounterPath string) Interface {
|
||||
}
|
||||
}
|
||||
|
||||
// Mount always returns an error on unsupported platforms
|
||||
func (mounter *Mounter) Mount(source string, target string, fstype string, options []string) error {
|
||||
return unsupportedErr
|
||||
return errUnsupported
|
||||
}
|
||||
|
||||
// Unmount always returns an error on unsupported platforms
|
||||
func (mounter *Mounter) Unmount(target string) error {
|
||||
return unsupportedErr
|
||||
return errUnsupported
|
||||
}
|
||||
|
||||
// List always returns an error on unsupported platforms
|
||||
func (mounter *Mounter) List() ([]MountPoint, error) {
|
||||
return []MountPoint{}, unsupportedErr
|
||||
return []MountPoint{}, errUnsupported
|
||||
}
|
||||
|
||||
// IsMountPointMatch returns true if the path in mp is the same as dir
|
||||
func (mounter *Mounter) IsMountPointMatch(mp MountPoint, dir string) bool {
|
||||
return (mp.Path == dir)
|
||||
}
|
||||
|
||||
// IsLikelyNotMountPoint always returns an error on unsupported platforms
|
||||
func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
|
||||
return true, unsupportedErr
|
||||
return true, errUnsupported
|
||||
}
|
||||
|
||||
// GetMountRefs always returns an error on unsupported platforms
|
||||
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
return nil, errUnsupported
|
||||
}
|
||||
|
||||
func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, fstype string, options []string) error {
|
||||
@ -67,68 +74,70 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
|
||||
}
|
||||
|
||||
func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) {
|
||||
return true, unsupportedErr
|
||||
return true, errUnsupported
|
||||
}
|
||||
|
||||
func getDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) {
|
||||
return "", unsupportedErr
|
||||
return "", errUnsupported
|
||||
}
|
||||
|
||||
type hostUtil struct{}
|
||||
|
||||
// NewHostUtil returns a struct that implements the HostUtils interface on
|
||||
// unsupported platforms
|
||||
func NewHostUtil() HostUtils {
|
||||
return &hostUtil{}
|
||||
}
|
||||
|
||||
// DeviceOpened determines if the device is in use elsewhere
|
||||
func (hu *hostUtil) DeviceOpened(pathname string) (bool, error) {
|
||||
return false, unsupportedErr
|
||||
return false, errUnsupported
|
||||
}
|
||||
|
||||
// PathIsDevice determines if a path is a device.
|
||||
func (hu *hostUtil) PathIsDevice(pathname string) (bool, error) {
|
||||
return true, unsupportedErr
|
||||
return true, errUnsupported
|
||||
}
|
||||
|
||||
// GetDeviceNameFromMount finds the device name by checking the mount path
|
||||
// to get the global mount path within its plugin directory
|
||||
func (hu *hostUtil) GetDeviceNameFromMount(mounter Interface, mountPath, pluginMountDir string) (string, error) {
|
||||
return "", unsupportedErr
|
||||
return "", errUnsupported
|
||||
}
|
||||
|
||||
func (hu *hostUtil) MakeRShared(path string) error {
|
||||
return unsupportedErr
|
||||
return errUnsupported
|
||||
}
|
||||
|
||||
func (hu *hostUtil) GetFileType(pathname string) (FileType, error) {
|
||||
return FileType("fake"), unsupportedErr
|
||||
return FileType("fake"), errUnsupported
|
||||
}
|
||||
|
||||
func (hu *hostUtil) MakeFile(pathname string) error {
|
||||
return unsupportedErr
|
||||
return errUnsupported
|
||||
}
|
||||
|
||||
func (hu *hostUtil) MakeDir(pathname string) error {
|
||||
return unsupportedErr
|
||||
return errUnsupported
|
||||
}
|
||||
|
||||
func (hu *hostUtil) ExistsPath(pathname string) (bool, error) {
|
||||
return true, unsupportedErr
|
||||
return true, errUnsupported
|
||||
}
|
||||
|
||||
// EvalHostSymlinks returns the path name after evaluating symlinks
|
||||
func (hu *hostUtil) EvalHostSymlinks(pathname string) (string, error) {
|
||||
return "", unsupportedErr
|
||||
return "", errUnsupported
|
||||
}
|
||||
|
||||
func (hu *hostUtil) GetFSGroup(pathname string) (int64, error) {
|
||||
return -1, unsupportedErr
|
||||
return -1, errUnsupported
|
||||
}
|
||||
|
||||
func (hu *hostUtil) GetSELinuxSupport(pathname string) (bool, error) {
|
||||
return false, unsupportedErr
|
||||
return false, errUnsupported
|
||||
}
|
||||
|
||||
func (hu *hostUtil) GetMode(pathname string) (os.FileMode, error) {
|
||||
return 0, unsupportedErr
|
||||
return 0, errUnsupported
|
||||
}
|
||||
|
@ -311,6 +311,8 @@ func getAllParentLinks(path string) ([]string, error) {
|
||||
|
||||
type hostUtil struct{}
|
||||
|
||||
// NewHostUtil returns a struct that implements the HostUtils interface on
|
||||
// windows platforms
|
||||
func NewHostUtil() HostUtils {
|
||||
return &hostUtil{}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
fakeexec "k8s.io/utils/exec/testing"
|
||||
@ -83,7 +84,7 @@ func TestSafeFormatAndMount(t *testing.T) {
|
||||
execScripts: []ExecArgs{
|
||||
{"fsck", []string{"-a", "/dev/foo"}, "", &fakeexec.FakeExitError{Status: 4}},
|
||||
},
|
||||
expectedError: fmt.Errorf("'fsck' found errors on device /dev/foo but could not correct them: ."),
|
||||
expectedError: fmt.Errorf("'fsck' found errors on device /dev/foo but could not correct them"),
|
||||
},
|
||||
{
|
||||
description: "Test 'fsck' fails with exit status 1 (errors found and corrected)",
|
||||
@ -234,7 +235,7 @@ func TestSafeFormatAndMount(t *testing.T) {
|
||||
t.Errorf("test \"%s\" the correct device was not mounted", test.description)
|
||||
}
|
||||
} else {
|
||||
if err == nil || test.expectedError.Error() != err.Error() {
|
||||
if err == nil || !strings.HasPrefix(err.Error(), test.expectedError.Error()) {
|
||||
t.Errorf("test \"%s\" unexpected error: \n [%v]. \nExpecting [%v]", test.description, err, test.expectedError)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user