diff --git a/staging/src/k8s.io/legacy-cloud-providers/openstack/util/file/file.go b/staging/src/k8s.io/legacy-cloud-providers/openstack/util/file/file.go index 70d26c4ef74..846c2d294a6 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/openstack/util/file/file.go +++ b/staging/src/k8s.io/legacy-cloud-providers/openstack/util/file/file.go @@ -20,8 +20,8 @@ import ( "os" ) -// FileExists checks if specified file exists. -func FileExists(filename string) (bool, error) { +// Exists checks if specified file exists. +func Exists(filename string) (bool, error) { if _, err := os.Stat(filename); os.IsNotExist(err) { return false, nil } else if err != nil { @@ -30,8 +30,8 @@ func FileExists(filename string) (bool, error) { return true, nil } -// FileOrSymlinkExists checks if specified file or symlink exists. -func FileOrSymlinkExists(filename string) (bool, error) { +// OrSymlinkExists checks if specified file or symlink exists. +func OrSymlinkExists(filename string) (bool, error) { if _, err := os.Lstat(filename); os.IsNotExist(err) { return false, nil } else if err != nil { diff --git a/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount.go b/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount.go index a1a874bdce0..4e8924ab4cd 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount.go +++ b/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount.go @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and 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 provides a linux-centric library for mounting filesystems/ +// Vendored for the OpenStack provider and will be removed in 1.17 package mount import ( @@ -25,8 +25,10 @@ import ( "strings" ) +// FileType is one of the types of supported Linux file types. type FileType string +// A complete list of the support file types in the mount package. const ( // Default mount command if mounter path is not specified defaultMountCommand = "mount" @@ -38,6 +40,7 @@ const ( FileTypeBlockDev FileType = "BlockDevice" ) +// Interface is the general interface to filesystem mounts. type Interface interface { // Mount mounts source to target as fstype with given options. Mount(source string, target string, fstype string, options []string) error @@ -47,9 +50,9 @@ type Interface interface { // On some platforms, reading mounts is not guaranteed consistent (i.e. // it could change between chunked reads). This is guaranteed to be // consistent. - List() ([]MountPoint, error) + List() ([]MntPoint, error) // IsMountPointMatch determines if the mountpoint matches the dir - IsMountPointMatch(mp MountPoint, dir string) bool + IsMountPointMatch(mp MntPoint, 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. @@ -126,6 +129,7 @@ type Interface interface { GetMode(pathname string) (os.FileMode, error) } +// Subpath is the string path of the volume mount. type Subpath struct { // index of the VolumeMount for this container VolumeMountIndex int @@ -155,8 +159,8 @@ type Exec interface { // the mount interface var _ Interface = &Mounter{} -// This represents a single line in /proc/mounts or /etc/fstab. -type MountPoint struct { +// MntPoint represents a single line in /proc/mounts or /etc/fstab. +type MntPoint struct { Device string Path string Type string @@ -212,8 +216,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 when 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 { @@ -334,14 +338,14 @@ func checkForNetDev(options []string) bool { return false } -// TODO: this is a workaround for the unmount device issue caused by gci mounter. +// HasMountRefs checks the mountPath contains any of the mountRefs. +// 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 // irrelevant to the original mounts, they should be not considered when checking the // 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 { count := 0 for _, ref := range mountRefs { diff --git a/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount_linux.go b/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount_linux.go index d83c82347e1..5bc6ef59bed 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount_linux.go +++ b/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount_linux.go @@ -106,14 +106,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 @@ -149,7 +149,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 @@ -212,21 +212,23 @@ 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 } // List returns a list of all mounted filesystems. -func (*Mounter) List() ([]MountPoint, error) { +func (*Mounter) List() ([]MntPoint, error) { return listProcMounts(procMountsPath) } -func (mounter *Mounter) IsMountPointMatch(mp MountPoint, dir string) bool { +// IsMountPointMatch determines if a directory is a mountpoint. +func (mounter *Mounter) IsMountPointMatch(mp MntPoint, dir string) bool { deletedDir := fmt.Sprintf("%s\\040(deleted)", dir) return ((mp.Path == dir) || (mp.Path == deletedDir)) } +// IsNotMountPoint determines if a directory is not a mountpoint. func (mounter *Mounter) IsNotMountPoint(dir string) (bool, error) { return IsNotMountPoint(mounter, dir) } @@ -308,7 +310,8 @@ func exclusiveOpenFailsOnDevice(pathname string) (bool, error) { return false, errno } -//GetDeviceNameFromMount: given a mount point, find the device name from its global mount point +// GetDeviceNameFromMount when given a mount point, finds the device name from its global +// mount point func (mounter *Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) { return getDeviceNameFromMount(mounter, mountPath, pluginDir) } @@ -341,7 +344,7 @@ func getDeviceNameFromMount(mounter Interface, mountPath, pluginDir string) (str return path.Base(mountPath), nil } -func listProcMounts(mountFilePath string) ([]MountPoint, error) { +func listProcMounts(mountFilePath string) ([]MntPoint, error) { content, err := utilio.ConsistentRead(mountFilePath, maxListTries) if err != nil { return nil, err @@ -349,8 +352,8 @@ func listProcMounts(mountFilePath string) ([]MountPoint, error) { return parseProcMounts(content) } -func parseProcMounts(content []byte) ([]MountPoint, error) { - out := []MountPoint{} +func parseProcMounts(content []byte) ([]MntPoint, error) { + out := []MntPoint{} lines := strings.Split(string(content), "\n") for _, line := range lines { if line == "" { @@ -362,7 +365,7 @@ func parseProcMounts(content []byte) ([]MountPoint, error) { return nil, fmt.Errorf("wrong number of fields (expected %d, got %d): %s", expectedNumFieldsPerLine, len(fields), line) } - mp := MountPoint{ + mp := MntPoint{ Device: fields[0], Path: fields[1], Type: fields[2], @@ -386,14 +389,17 @@ func parseProcMounts(content []byte) ([]MountPoint, error) { return out, nil } +// MakeRShared makes the bind mount rshared if needed. func (mounter *Mounter) MakeRShared(path string) error { return doMakeRShared(path, procMountInfoPath) } +// GetFileType returns the string FileType of the path. func (mounter *Mounter) GetFileType(pathname string) (FileType, error) { return getFileType(pathname) } +// MakeDir creates a directory at the specified path. func (mounter *Mounter) MakeDir(pathname string) error { err := os.MkdirAll(pathname, os.FileMode(0755)) if err != nil { @@ -404,6 +410,7 @@ func (mounter *Mounter) MakeDir(pathname string) error { return nil } +// MakeFile creates a file with permissions 0644 at the specified path. func (mounter *Mounter) MakeFile(pathname string) error { f, err := os.OpenFile(pathname, os.O_CREATE, os.FileMode(0644)) defer f.Close() @@ -415,10 +422,12 @@ func (mounter *Mounter) MakeFile(pathname string) error { return nil } +// ExistsPath returns true if the specified path exists. func (mounter *Mounter) ExistsPath(pathname string) (bool, error) { - return utilfile.FileExists(pathname) + return utilfile.Exists(pathname) } +// EvalHostSymlinks returns the actual path a symlink points to. func (mounter *Mounter) EvalHostSymlinks(pathname string) (string, error) { return filepath.EvalSymlinks(pathname) } @@ -444,11 +453,11 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, ee, isExitError := err.(utilexec.ExitError) switch { case err == utilexec.ErrExecutableNotFound: - klog.Warning("'fsck' not found on system; continuing mount without running 'fsck'.") + klog.Warning("'fsck' not found on system; continuing mount without running 'fsck'") case isExitError && ee.ExitStatus() == fsckErrorsCorrected: - klog.Infof("Device %s has errors which were corrected by fsck.", source) + 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)) } @@ -494,16 +503,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 } @@ -643,7 +650,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) } @@ -725,6 +732,7 @@ func getSELinuxSupport(path string, mountInfoFilename string) (bool, error) { return false, nil } +// PrepareSafeSubpath safely creates a new subpath. func (mounter *Mounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) { newHostPath, err = doBindSubPath(mounter, subPath) @@ -863,6 +871,7 @@ func doBindSubPath(mounter Interface, subpath Subpath) (hostPath string, err err return bindPathTarget, nil } +// CleanSubPaths cleans up the subpath mounts for the volume in the pod directory. func (mounter *Mounter) CleanSubPaths(podDir string, volumeName string) error { return doCleanSubPaths(mounter, podDir, volumeName) } @@ -993,6 +1002,7 @@ func removeEmptyDirs(baseDir, endDir string) error { return nil } +// SafeMakeDir safely creates a subdirectory at the specified path base func (mounter *Mounter) SafeMakeDir(subdir string, base string, perm os.FileMode) error { realBase, err := filepath.EvalSymlinks(base) if err != nil { @@ -1004,6 +1014,7 @@ func (mounter *Mounter) SafeMakeDir(subdir string, base string, perm os.FileMode return doSafeMakeDir(realFullPath, realBase, perm) } +// GetMountRefs finds all of the mount references to the source. func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) { if _, err := os.Stat(pathname); os.IsNotExist(err) { return []string{}, nil @@ -1017,10 +1028,12 @@ func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) { return searchMountPoints(realpath, procMountInfoPath) } +// GetSELinuxSupport is common implementation of GetSELinuxSupport on Linux. func (mounter *Mounter) GetSELinuxSupport(pathname string) (bool, error) { return getSELinuxSupport(pathname, procMountInfoPath) } +// GetFSGroup returns the filesystem group for the path name. func (mounter *Mounter) GetFSGroup(pathname string) (int64, error) { realpath, err := filepath.EvalSymlinks(pathname) if err != nil { @@ -1029,6 +1042,7 @@ func (mounter *Mounter) GetFSGroup(pathname string) (int64, error) { return getFSGroup(realpath) } +// GetMode returns the unix filesystem mode for the path. func (mounter *Mounter) GetMode(pathname string) (os.FileMode, error) { return getMode(pathname) } diff --git a/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount_unsupported.go b/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount_unsupported.go index cd6f1a28f28..3429a47ef20 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount_unsupported.go +++ b/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount_unsupported.go @@ -23,11 +23,12 @@ import ( "os" ) +// Mounter provides the default unsupported implementation of mount.Interface 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,48 +39,58 @@ func New(mounterPath string) Interface { } } +// Mount returns an error func (mounter *Mounter) Mount(source string, target string, fstype string, options []string) error { - return unsupportedErr + return errUnsupported } +// Unmount returns an error func (mounter *Mounter) Unmount(target string) error { - return unsupportedErr + return errUnsupported } -func (mounter *Mounter) List() ([]MountPoint, error) { - return []MountPoint{}, unsupportedErr +// List returns an error +func (mounter *Mounter) List() ([]MntPoint, error) { + return []MntPoint{}, errUnsupported } -func (mounter *Mounter) IsMountPointMatch(mp MountPoint, dir string) bool { +// IsMountPointMatch returns an error +func (mounter *Mounter) IsMountPointMatch(mp MntPoint, dir string) bool { return (mp.Path == dir) } +// IsNotMountPoint returns an error func (mounter *Mounter) IsNotMountPoint(dir string) (bool, error) { return IsNotMountPoint(mounter, dir) } +// IsLikelyNotMountPoint returns an error func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) { - return true, unsupportedErr + return true, errUnsupported } +// GetDeviceNameFromMount returns an error func (mounter *Mounter) GetDeviceNameFromMount(mountPath, pluginDir string) (string, error) { - return "", unsupportedErr + return "", errUnsupported } func getDeviceNameFromMount(mounter Interface, mountPath, pluginDir string) (string, error) { - return "", unsupportedErr + return "", errUnsupported } +// DeviceOpened returns an error func (mounter *Mounter) DeviceOpened(pathname string) (bool, error) { - return false, unsupportedErr + return false, errUnsupported } +// PathIsDevice returns an error func (mounter *Mounter) PathIsDevice(pathname string) (bool, error) { - return true, unsupportedErr + return true, errUnsupported } +// MakeRShared returns an error func (mounter *Mounter) MakeRShared(path string) error { - return unsupportedErr + return errUnsupported } func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, fstype string, options []string) error { @@ -87,53 +98,65 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, } func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) { - return true, unsupportedErr + return true, errUnsupported } +// GetFileType returns an error func (mounter *Mounter) GetFileType(pathname string) (FileType, error) { - return FileType("fake"), unsupportedErr + return FileType("fake"), errUnsupported } +// MakeDir returns an error func (mounter *Mounter) MakeDir(pathname string) error { - return unsupportedErr + return errUnsupported } +// MakeFile returns an error func (mounter *Mounter) MakeFile(pathname string) error { - return unsupportedErr + return errUnsupported } +// ExistsPath returns an error func (mounter *Mounter) ExistsPath(pathname string) (bool, error) { return true, errors.New("not implemented") } +// EvalHostSymlinks returns an error func (mounter *Mounter) EvalHostSymlinks(pathname string) (string, error) { - return "", unsupportedErr + return "", errUnsupported } +// PrepareSafeSubpath returns an error func (mounter *Mounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) { - return subPath.Path, nil, unsupportedErr + return subPath.Path, nil, errUnsupported } +// CleanSubPaths returns an error func (mounter *Mounter) CleanSubPaths(podDir string, volumeName string) error { - return unsupportedErr + return errUnsupported } +// SafeMakeDir returns an error func (mounter *Mounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error { - return unsupportedErr + return errUnsupported } +// GetMountRefs returns an error func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) { return nil, errors.New("not implemented") } +// GetFSGroup returns an error func (mounter *Mounter) GetFSGroup(pathname string) (int64, error) { return -1, errors.New("not implemented") } +// GetSELinuxSupport returns an error func (mounter *Mounter) GetSELinuxSupport(pathname string) (bool, error) { return false, errors.New("not implemented") } +// GetMode returns an error func (mounter *Mounter) GetMode(pathname string) (os.FileMode, error) { return 0, errors.New("not implemented") } diff --git a/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount_windows.go b/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount_windows.go index 04a808df64d..d3c8194049e 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount_windows.go +++ b/staging/src/k8s.io/legacy-cloud-providers/openstack/util/mount/mount_windows.go @@ -121,12 +121,12 @@ func (mounter *Mounter) Unmount(target string) error { } // List returns a list of all mounted filesystems. todo -func (mounter *Mounter) List() ([]MountPoint, error) { - return []MountPoint{}, nil +func (mounter *Mounter) List() ([]MntPoint, error) { + return []MntPoint{}, nil } // IsMountPointMatch determines if the mountpoint matches the dir -func (mounter *Mounter) IsMountPointMatch(mp MountPoint, dir string) bool { +func (mounter *Mounter) IsMountPointMatch(mp MntPoint, dir string) bool { return mp.Path == dir } @@ -210,7 +210,7 @@ func (mounter *Mounter) GetFileType(pathname string) (FileType, error) { return getFileType(pathname) } -// MakeFile creates a new directory +// MakeDir creates a new directory func (mounter *Mounter) MakeDir(pathname string) error { err := os.MkdirAll(pathname, os.FileMode(0755)) if err != nil { @@ -235,7 +235,7 @@ func (mounter *Mounter) MakeFile(pathname string) error { // ExistsPath checks whether the path exists func (mounter *Mounter) ExistsPath(pathname string) (bool, error) { - return utilfile.FileExists(pathname) + return utilfile.Exists(pathname) } // EvalHostSymlinks returns the path name after evaluating symlinks @@ -344,7 +344,7 @@ func lockPath(path string) (uintptr, error) { return uintptr(fd), err } -// Lock all directories in subPath and check they're not symlinks. +// PrepareSafeSubpath locks all directories in subPath and check they're not symlinks. func (mounter *Mounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) { handles, err := lockAndCheckSubPath(subPath.VolumePath, subPath.Path) @@ -355,7 +355,7 @@ func (mounter *Mounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, return subPath.Path, cleanupAction, err } -// No bind-mounts for subpaths are necessary on Windows +// CleanSubPaths no bind-mounts for subpaths are necessary on Windows func (mounter *Mounter) CleanSubPaths(podDir string, volumeName string) error { return nil } @@ -468,17 +468,19 @@ func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) { return []string{pathname}, nil } -// Note that on windows, it always returns 0. We actually don't set FSGroup on +// GetFSGroup always returns 0. We actually don't set FSGroup on // windows platform, see SetVolumeOwnership implementation. func (mounter *Mounter) GetFSGroup(pathname string) (int64, error) { return 0, nil } +// GetSELinuxSupport returns false func (mounter *Mounter) GetSELinuxSupport(pathname string) (bool, error) { // Windows does not support SELinux. return false, nil } +// GetMode returns the filesystem mode. func (mounter *Mounter) GetMode(pathname string) (os.FileMode, error) { info, err := os.Stat(pathname) if err != nil {