From b1a3b027415815d4840ec52220a325411a69a9ed Mon Sep 17 00:00:00 2001 From: Madhu Rajanna Date: Fri, 10 Dec 2021 15:49:52 +0530 Subject: [PATCH] cleanup: remove k8s.io/utils from vendor as part of running `go mod tidy` the unused k8s.io/utils is removed from the vendor directory. Signed-off-by: Madhu Rajanna --- vendor/k8s.io/utils/mount/OWNERS | 15 - vendor/k8s.io/utils/mount/README.md | 11 - vendor/k8s.io/utils/mount/doc.go | 18 - vendor/k8s.io/utils/mount/fake_mounter.go | 216 ------- vendor/k8s.io/utils/mount/mount.go | 370 ------------ .../k8s.io/utils/mount/mount_helper_common.go | 103 ---- .../k8s.io/utils/mount/mount_helper_unix.go | 158 ----- .../utils/mount/mount_helper_windows.go | 101 ---- vendor/k8s.io/utils/mount/mount_linux.go | 551 ------------------ .../k8s.io/utils/mount/mount_unsupported.go | 77 --- vendor/k8s.io/utils/mount/mount_windows.go | 313 ---------- vendor/modules.txt | 1 - 12 files changed, 1934 deletions(-) delete mode 100644 vendor/k8s.io/utils/mount/OWNERS delete mode 100644 vendor/k8s.io/utils/mount/README.md delete mode 100644 vendor/k8s.io/utils/mount/doc.go delete mode 100644 vendor/k8s.io/utils/mount/fake_mounter.go delete mode 100644 vendor/k8s.io/utils/mount/mount.go delete mode 100644 vendor/k8s.io/utils/mount/mount_helper_common.go delete mode 100644 vendor/k8s.io/utils/mount/mount_helper_unix.go delete mode 100644 vendor/k8s.io/utils/mount/mount_helper_windows.go delete mode 100644 vendor/k8s.io/utils/mount/mount_linux.go delete mode 100644 vendor/k8s.io/utils/mount/mount_unsupported.go delete mode 100644 vendor/k8s.io/utils/mount/mount_windows.go diff --git a/vendor/k8s.io/utils/mount/OWNERS b/vendor/k8s.io/utils/mount/OWNERS deleted file mode 100644 index aacc6685b..000000000 --- a/vendor/k8s.io/utils/mount/OWNERS +++ /dev/null @@ -1,15 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -reviewers: - - jingxu97 - - saad-ali - - jsafrane - - msau42 - - andyzhangx - - gnufied -approvers: - - andyzhangx - - jingxu97 - - saad-ali - - jsafrane - diff --git a/vendor/k8s.io/utils/mount/README.md b/vendor/k8s.io/utils/mount/README.md deleted file mode 100644 index e66b5c27a..000000000 --- a/vendor/k8s.io/utils/mount/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# WARNING ! Please read before using mount functionality -# THIS REPOSITORY is moved : Please use https://github.com/kubernetes/mount-utils for all your work - -This package has been moved to new location. Please use the new repo for bug fixes and enhancements. -All existing dependencies on this repo are being removed. Eventually this repo will be deprecated. -If you are using this repo or planning to use, you must use the new repo mentioned here for this functionality. - -New repo : https://github.com/kubernetes/mount-utils -New go module: k8s.io/mount-utils -For Kubernetes/Kubernetes project the code is available under staging directory. - diff --git a/vendor/k8s.io/utils/mount/doc.go b/vendor/k8s.io/utils/mount/doc.go deleted file mode 100644 index c81b426ce..000000000 --- a/vendor/k8s.io/utils/mount/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -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 defines an interface to mounting filesystems. -package mount // import "k8s.io/utils/mount" diff --git a/vendor/k8s.io/utils/mount/fake_mounter.go b/vendor/k8s.io/utils/mount/fake_mounter.go deleted file mode 100644 index f48c2badb..000000000 --- a/vendor/k8s.io/utils/mount/fake_mounter.go +++ /dev/null @@ -1,216 +0,0 @@ -/* -Copyright 2015 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 ( - "os" - "path/filepath" - "sync" - - "k8s.io/klog/v2" -) - -// FakeMounter implements mount.Interface for tests. -type FakeMounter struct { - MountPoints []MountPoint - log []FakeAction - // Error to return for a path when calling IsLikelyNotMountPoint - MountCheckErrors map[string]error - // Some tests run things in parallel, make sure the mounter does not produce - // any golang's DATA RACE warnings. - mutex sync.Mutex - UnmountFunc UnmountFunc -} - -// UnmountFunc is a function callback to be executed during the Unmount() call. -type UnmountFunc func(path string) error - -var _ Interface = &FakeMounter{} - -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 { - Action string // "mount" or "unmount" - Target string // applies to both mount and unmount actions - Source string // applies only to "mount" actions - FSType string // applies only to "mount" actions -} - -// NewFakeMounter returns a FakeMounter struct that implements Interface and is -// suitable for testing purposes. -func NewFakeMounter(mps []MountPoint) *FakeMounter { - return &FakeMounter{ - MountPoints: mps, - } -} - -// ResetLog clears all the log entries in FakeMounter -func (f *FakeMounter) ResetLog() { - f.mutex.Lock() - defer f.mutex.Unlock() - - f.log = []FakeAction{} -} - -// GetLog returns the slice of FakeActions taken by the mounter -func (f *FakeMounter) GetLog() []FakeAction { - f.mutex.Lock() - defer f.mutex.Unlock() - - return f.log -} - -// 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 { - return f.MountSensitive(source, target, fstype, options, nil /* sensitiveOptions */) -} - -// Mount records the mount event and updates the in-memory mount points for FakeMounter -// sensitiveOptions to be passed in a separate parameter from the normal -// mount options and ensures the sensitiveOptions are never logged. This -// method should be used by callers that pass sensitive material (like -// passwords) as mount options. -func (f *FakeMounter) MountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error { - f.mutex.Lock() - defer f.mutex.Unlock() - - opts := []string{} - - for _, option := range options { - // find 'bind' option - if option == "bind" { - // This is a bind-mount. In order to mimic linux behaviour, we must - // use the original device of the bind-mount as the real source. - // E.g. when mounted /dev/sda like this: - // $ mount /dev/sda /mnt/test - // $ mount -o bind /mnt/test /mnt/bound - // then /proc/mount contains: - // /dev/sda /mnt/test - // /dev/sda /mnt/bound - // (and not /mnt/test /mnt/bound) - // I.e. we must use /dev/sda as source instead of /mnt/test in the - // bind mount. - for _, mnt := range f.MountPoints { - if source == mnt.Path { - source = mnt.Device - break - } - } - } - // reuse MountPoint.Opts field to mark mount as readonly - opts = append(opts, option) - } - - // If target is a symlink, get its absolute path - absTarget, err := filepath.EvalSymlinks(target) - if err != nil { - absTarget = target - } - f.MountPoints = append(f.MountPoints, MountPoint{Device: source, Path: absTarget, Type: fstype, Opts: append(opts, sensitiveOptions...)}) - klog.V(5).Infof("Fake mounter: mounted %s to %s", source, absTarget) - f.log = append(f.log, FakeAction{Action: FakeActionMount, Target: absTarget, Source: source, FSType: fstype}) - 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() - - // If target is a symlink, get its absolute path - absTarget, err := filepath.EvalSymlinks(target) - if err != nil { - absTarget = target - } - - newMountpoints := []MountPoint{} - for _, mp := range f.MountPoints { - if mp.Path == absTarget { - if f.UnmountFunc != nil { - err := f.UnmountFunc(absTarget) - if err != nil { - return err - } - } - klog.V(5).Infof("Fake mounter: unmounted %s from %s", mp.Device, absTarget) - // Don't copy it to newMountpoints - continue - } - newMountpoints = append(newMountpoints, MountPoint{Device: mp.Device, Path: mp.Path, Type: mp.Type}) - } - f.MountPoints = newMountpoints - f.log = append(f.log, FakeAction{Action: FakeActionUnmount, Target: absTarget}) - delete(f.MountCheckErrors, target) - return nil -} - -// List returns all the in-memory mountpoints for FakeMounter -func (f *FakeMounter) List() ([]MountPoint, error) { - f.mutex.Lock() - defer f.mutex.Unlock() - - return f.MountPoints, nil -} - -// 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() - - err := f.MountCheckErrors[file] - if err != nil { - return false, err - } - - _, err = os.Stat(file) - if err != nil { - return true, err - } - - // If file is a symlink, get its absolute path - absFile, err := filepath.EvalSymlinks(file) - if err != nil { - absFile = file - } - - for _, mp := range f.MountPoints { - if mp.Path == absFile { - klog.V(5).Infof("isLikelyNotMountPoint for %s: mounted %s, false", file, mp.Path) - return false, nil - } - } - klog.V(5).Infof("isLikelyNotMountPoint for %s: true", file) - 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 { - // Ignore error in FakeMounter, because we actually didn't create files. - realpath = pathname - } - return getMountRefsByDev(f, realpath) -} diff --git a/vendor/k8s.io/utils/mount/mount.go b/vendor/k8s.io/utils/mount/mount.go deleted file mode 100644 index 14997a75c..000000000 --- a/vendor/k8s.io/utils/mount/mount.go +++ /dev/null @@ -1,370 +0,0 @@ -/* -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. -*/ - -// 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 ( - "fmt" - "os" - "path/filepath" - "strings" - - utilexec "k8s.io/utils/exec" -) - -const ( - // Default mount command if mounter path is not specified. - defaultMountCommand = "mount" - // Log message where sensitive mount options were removed - sensitiveOptionsRemoved = "" -) - -// 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. - // options MUST not contain sensitive material (like passwords). - Mount(source string, target string, fstype string, options []string) error - // MountSensitive is the same as Mount() but this method allows - // sensitiveOptions to be passed in a separate parameter from the normal - // mount options and ensures the sensitiveOptions are never logged. This - // method should be used by callers that pass sensitive material (like - // passwords) as mount options. - MountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []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 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) - // IsLikelyNotMountPoint uses heuristics to determine if a directory - // 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. For callers that do not - // care about such situations, this is a faster alternative to calling List() - // and scanning that output. - IsLikelyNotMountPoint(file string) (bool, error) - // GetMountRefs finds all mount references to pathname, returning a slice of - // paths. Pathname can be a mountpoint path or a normal directory - // (for bind mount). On Linux, pathname is excluded from the slice. - // For example, if /dev/sdc was mounted at /path/a and /path/b, - // GetMountRefs("/path/a") would return ["/path/b"] - // GetMountRefs("/path/b") would return ["/path/a"] - // On Windows there is no way to query all mount points; as long as pathname is - // a valid mount, it will be returned. - GetMountRefs(pathname string) ([]string, error) -} - -// Compile-time check to ensure all Mounter implementations satisfy -// the mount interface. -var _ Interface = &Mounter{} - -// MountPoint represents a single line in /proc/mounts or /etc/fstab. -type MountPoint struct { // nolint: golint - Device string - Path string - Type string - Opts []string // Opts may contain sensitive mount options (like passwords) and MUST be treated as such (e.g. not logged). - Freq int - Pass int -} - -type MountErrorType string // nolint: golint - -const ( - FilesystemMismatch MountErrorType = "FilesystemMismatch" - HasFilesystemErrors MountErrorType = "HasFilesystemErrors" - UnformattedReadOnly MountErrorType = "UnformattedReadOnly" - FormatFailed MountErrorType = "FormatFailed" - GetDiskFormatFailed MountErrorType = "GetDiskFormatFailed" - UnknownMountError MountErrorType = "UnknownMountError" -) - -type MountError struct { // nolint: golint - Type MountErrorType - Message string -} - -func (mountError MountError) String() string { - return mountError.Message -} - -func (mountError MountError) Error() string { - return mountError.Message -} - -func NewMountError(mountErrorValue MountErrorType, format string, args ...interface{}) error { - mountError := MountError{ - Type: mountErrorValue, - Message: fmt.Sprintf(format, args...), - } - return mountError -} - -// SafeFormatAndMount probes a device to see if it is formatted. -// Namely it checks to see if a file system is present. If so it -// mounts it otherwise the device is formatted first then mounted. -type SafeFormatAndMount struct { - Interface - Exec utilexec.Interface -} - -// FormatAndMount formats the given disk, if needed, and mounts it. -// That is if the disk is not formatted and it is not being mounted as -// read-only it will format it first then mount it. Otherwise, if the -// disk is already formatted or it is being mounted as read-only, it -// will be mounted without formatting. -// options MUST not contain sensitive material (like passwords). -func (mounter *SafeFormatAndMount) FormatAndMount(source string, target string, fstype string, options []string) error { - return mounter.FormatAndMountSensitive(source, target, fstype, options, nil /* sensitiveOptions */) -} - -// FormatAndMountSensitive is the same as FormatAndMount but this method allows -// sensitiveOptions to be passed in a separate parameter from the normal mount -// options and ensures the sensitiveOptions are never logged. This method should -// be used by callers that pass sensitive material (like passwords) as mount -// options. -func (mounter *SafeFormatAndMount) FormatAndMountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error { - return mounter.formatAndMountSensitive(source, target, fstype, options, sensitiveOptions) -} - -// getMountRefsByDev finds all references to the device provided -// by mountPath; returns a list of paths. -// Note that mountPath should be path after the evaluation of any symblolic links. -func getMountRefsByDev(mounter Interface, mountPath string) ([]string, error) { - mps, err := mounter.List() - if err != nil { - return nil, err - } - - // Finding the device mounted to mountPath. - diskDev := "" - for i := range mps { - if mountPath == mps[i].Path { - diskDev = mps[i].Device - break - } - } - - // Find all references to the device. - var refs []string - for i := range mps { - if mps[i].Device == diskDev || mps[i].Device == mountPath { - if mps[i].Path != mountPath { - refs = append(refs, mps[i].Path) - } - } - } - return refs, nil -} - -// 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 { - return "", 0, err - } - - // Find the device name. - // 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) - if err != nil { - slTarget = mountPath - } - for i := range mps { - if mps[i].Path == slTarget { - device = mps[i].Device - break - } - } - - // Find all references to the device. - refCount := 0 - for i := range mps { - if mps[i].Device == device { - refCount++ - } - } - return device, refCount, nil -} - -// 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) - if notMntErr != nil && os.IsPermission(notMntErr) { - // We were not allowed to do the simple stat() check, e.g. on NFS with - // root_squash. Fall back to /proc/mounts check below. - notMnt = true - notMntErr = nil - } - if notMntErr != nil { - return notMnt, notMntErr - } - // 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. - resolvedFile, err := filepath.EvalSymlinks(file) - if err != nil { - return true, err - } - - // check all mountpoints since IsLikelyNotMountPoint - // is not reliable for some mountpoint types. - mountPoints, mountPointsErr := mounter.List() - if mountPointsErr != nil { - return notMnt, mountPointsErr - } - for _, mp := range mountPoints { - if isMountPointMatch(mp, resolvedFile) { - notMnt = false - break - } - } - return notMnt, nil -} - -// MakeBindOpts 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 MakeBindOpts(options []string) (bool, []string, []string) { - bind, bindOpts, bindRemountOpts, _ := MakeBindOptsSensitive(options, nil /* sensitiveOptions */) - return bind, bindOpts, bindRemountOpts -} - -// MakeBindOptsSensitive is the same as MakeBindOpts but this method allows -// sensitiveOptions to be passed in a separate parameter from the normal mount -// options and ensures the sensitiveOptions are never logged. This method should -// be used by callers that pass sensitive material (like passwords) as mount -// options. -func MakeBindOptsSensitive(options []string, sensitiveOptions []string) (bool, []string, []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. - // - // As a consequence, all read only bind mounts will no longer change the underlying - // volume mount to be read only. - bindRemountOpts := []string{"bind", "remount"} - bindRemountSensitiveOpts := []string{} - bind := false - bindOpts := []string{"bind"} - - // _netdev is a userspace mount option and does not automatically get added when - // bind mount is created and hence we must carry it over. - if checkForNetDev(options, sensitiveOptions) { - bindOpts = append(bindOpts, "_netdev") - } - - for _, option := range options { - switch option { - case "bind": - bind = true - break - case "remount": - break - default: - bindRemountOpts = append(bindRemountOpts, option) - } - } - - for _, sensitiveOption := range sensitiveOptions { - switch sensitiveOption { - case "bind": - bind = true - break - case "remount": - break - default: - bindRemountSensitiveOpts = append(bindRemountSensitiveOpts, sensitiveOption) - } - } - - return bind, bindOpts, bindRemountOpts, bindRemountSensitiveOpts -} - -func checkForNetDev(options []string, sensitiveOptions []string) bool { - for _, option := range options { - if option == "_netdev" { - return true - } - } - for _, sensitiveOption := range sensitiveOptions { - if sensitiveOption == "_netdev" { - return true - } - } - return false -} - -// PathWithinBase checks if give path is within given base directory. -func PathWithinBase(fullPath, basePath string) bool { - rel, err := filepath.Rel(basePath, fullPath) - if err != nil { - return false - } - if StartsWithBackstep(rel) { - // Needed to escape the base path. - return false - } - return true -} - -// 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), "../") -} - -// sanitizedOptionsForLogging will return a comma separated string containing -// options and sensitiveOptions. Each entry in sensitiveOptions will be -// replaced with the string sensitiveOptionsRemoved -// e.g. o1,o2,, -func sanitizedOptionsForLogging(options []string, sensitiveOptions []string) string { - separator := "" - if len(options) > 0 && len(sensitiveOptions) > 0 { - separator = "," - } - - sensitiveOptionsStart := "" - sensitiveOptionsEnd := "" - if len(sensitiveOptions) > 0 { - sensitiveOptionsStart = strings.Repeat(sensitiveOptionsRemoved+",", len(sensitiveOptions)-1) - sensitiveOptionsEnd = sensitiveOptionsRemoved - } - - return strings.Join(options, ",") + - separator + - sensitiveOptionsStart + - sensitiveOptionsEnd -} diff --git a/vendor/k8s.io/utils/mount/mount_helper_common.go b/vendor/k8s.io/utils/mount/mount_helper_common.go deleted file mode 100644 index 1d40549b5..000000000 --- a/vendor/k8s.io/utils/mount/mount_helper_common.go +++ /dev/null @@ -1,103 +0,0 @@ -/* -Copyright 2018 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 ( - "fmt" - "os" - - "k8s.io/klog/v2" -) - -// 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 { - pathExists, pathErr := PathExists(mountPath) - if !pathExists { - klog.Warningf("Warning: Unmount skipped because path does not exist: %v", mountPath) - return nil - } - corruptedMnt := IsCorruptedMnt(pathErr) - if pathErr != nil && !corruptedMnt { - return fmt.Errorf("Error checking path: %v", pathErr) - } - return doCleanupMountPoint(mountPath, mounter, extensiveMountPointCheck, corruptedMnt) -} - -// doCleanupMountPoint 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. -// if corruptedMnt is true, it means that the mountPath is a corrupted mountpoint, and the mount point check -// will be skipped -func doCleanupMountPoint(mountPath string, mounter Interface, extensiveMountPointCheck bool, corruptedMnt bool) error { - var notMnt bool - var err error - if !corruptedMnt { - if extensiveMountPointCheck { - notMnt, err = IsNotMountPoint(mounter, mountPath) - } else { - notMnt, err = mounter.IsLikelyNotMountPoint(mountPath) - } - - if err != nil { - return err - } - - if notMnt { - klog.Warningf("Warning: %q is not a mountpoint, deleting", mountPath) - return os.Remove(mountPath) - } - } - - // Unmount the mount path - klog.V(4).Infof("%q is a mountpoint, unmounting", mountPath) - if err := mounter.Unmount(mountPath); err != nil { - return err - } - - if extensiveMountPointCheck { - notMnt, err = IsNotMountPoint(mounter, mountPath) - } else { - notMnt, err = mounter.IsLikelyNotMountPoint(mountPath) - } - if err != nil { - return err - } - if notMnt { - klog.V(4).Infof("%q is unmounted, deleting the directory", mountPath) - return os.Remove(mountPath) - } - return fmt.Errorf("Failed to unmount path %v", mountPath) -} - -// 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 { - return true, nil - } else if os.IsNotExist(err) { - return false, nil - } else if IsCorruptedMnt(err) { - return true, err - } - return false, err -} diff --git a/vendor/k8s.io/utils/mount/mount_helper_unix.go b/vendor/k8s.io/utils/mount/mount_helper_unix.go deleted file mode 100644 index 11b70ebc2..000000000 --- a/vendor/k8s.io/utils/mount/mount_helper_unix.go +++ /dev/null @@ -1,158 +0,0 @@ -// +build !windows - -/* -Copyright 2019 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 ( - "fmt" - "os" - "strconv" - "strings" - "syscall" - - utilio "k8s.io/utils/io" -) - -const ( - // At least number of fields per line in /proc//mountinfo. - expectedAtLeastNumFieldsPerMountInfo = 10 - // How many times to retry for a consistent read of /proc/mounts. - maxListTries = 3 -) - -// IsCorruptedMnt return true if err is about corrupted mount point -func IsCorruptedMnt(err error) bool { - if err == nil { - return false - } - var underlyingError error - switch pe := err.(type) { - case nil: - return false - case *os.PathError: - underlyingError = pe.Err - case *os.LinkError: - underlyingError = pe.Err - case *os.SyscallError: - underlyingError = pe.Err - } - - return underlyingError == syscall.ENOTCONN || underlyingError == syscall.ESTALE || underlyingError == syscall.EIO || underlyingError == syscall.EACCES -} - -// MountInfo represents a single line in /proc//mountinfo. -type MountInfo struct { // nolint: golint - // Unique ID for the mount (maybe reused after umount). - ID int - // The ID of the parent mount (or of self for the root of this mount namespace's mount tree). - ParentID int - // Major indicates one half of the device ID which identifies the device class - // (parsed from `st_dev` for files on this filesystem). - Major int - // Minor indicates one half of the device ID which identifies a specific - // instance of device (parsed from `st_dev` for files on this filesystem). - Minor int - // The pathname of the directory in the filesystem which forms the root of this mount. - Root string - // Mount source, filesystem-specific information. e.g. device, tmpfs name. - Source string - // Mount point, the pathname of the mount point. - MountPoint string - // Optional fieds, zero or more fields of the form "tag[:value]". - OptionalFields []string - // The filesystem type in the form "type[.subtype]". - FsType string - // Per-mount options. - MountOptions []string - // Per-superblock options. - SuperOptions []string -} - -// ParseMountInfo parses /proc/xxx/mountinfo. -func ParseMountInfo(filename string) ([]MountInfo, error) { - content, err := utilio.ConsistentRead(filename, maxListTries) - if err != nil { - return []MountInfo{}, err - } - contentStr := string(content) - infos := []MountInfo{} - - for _, line := range strings.Split(contentStr, "\n") { - if line == "" { - // the last split() item is empty string following the last \n - continue - } - // See `man proc` for authoritative description of format of the file. - fields := strings.Fields(line) - if len(fields) < expectedAtLeastNumFieldsPerMountInfo { - return nil, fmt.Errorf("wrong number of fields in (expected at least %d, got %d): %s", expectedAtLeastNumFieldsPerMountInfo, len(fields), line) - } - id, err := strconv.Atoi(fields[0]) - if err != nil { - return nil, err - } - parentID, err := strconv.Atoi(fields[1]) - if err != nil { - return nil, err - } - mm := strings.Split(fields[2], ":") - if len(mm) != 2 { - return nil, fmt.Errorf("parsing '%s' failed: unexpected minor:major pair %s", line, mm) - } - major, err := strconv.Atoi(mm[0]) - if err != nil { - return nil, fmt.Errorf("parsing '%s' failed: unable to parse major device id, err:%v", mm[0], err) - } - minor, err := strconv.Atoi(mm[1]) - if err != nil { - return nil, fmt.Errorf("parsing '%s' failed: unable to parse minor device id, err:%v", mm[1], err) - } - - info := MountInfo{ - ID: id, - ParentID: parentID, - Major: major, - Minor: minor, - Root: fields[3], - MountPoint: fields[4], - MountOptions: strings.Split(fields[5], ","), - } - // All fields until "-" are "optional fields". - i := 6 - for ; i < len(fields) && fields[i] != "-"; i++ { - info.OptionalFields = append(info.OptionalFields, fields[i]) - } - // Parse the rest 3 fields. - i++ - if len(fields)-i < 3 { - return nil, fmt.Errorf("expect 3 fields in %s, got %d", line, len(fields)-i) - } - info.FsType = fields[i] - info.Source = fields[i+1] - info.SuperOptions = strings.Split(fields[i+2], ",") - infos = append(infos, info) - } - return infos, nil -} - -// isMountPointMatch returns true if the path in mp is the same as dir. -// Handles case where mountpoint dir has been renamed due to stale NFS mount. -func isMountPointMatch(mp MountPoint, dir string) bool { - deletedDir := fmt.Sprintf("%s\\040(deleted)", dir) - return ((mp.Path == dir) || (mp.Path == deletedDir)) -} diff --git a/vendor/k8s.io/utils/mount/mount_helper_windows.go b/vendor/k8s.io/utils/mount/mount_helper_windows.go deleted file mode 100644 index b308ce76d..000000000 --- a/vendor/k8s.io/utils/mount/mount_helper_windows.go +++ /dev/null @@ -1,101 +0,0 @@ -// +build windows - -/* -Copyright 2019 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 ( - "fmt" - "os" - "strconv" - "strings" - "syscall" - - "k8s.io/klog/v2" -) - -// following failure codes are from https://docs.microsoft.com/en-us/windows/desktop/debug/system-error-codes--1300-1699- -// ERROR_BAD_NETPATH = 53 -// ERROR_NETWORK_BUSY = 54 -// ERROR_UNEXP_NET_ERR = 59 -// ERROR_NETNAME_DELETED = 64 -// ERROR_NETWORK_ACCESS_DENIED = 65 -// ERROR_BAD_DEV_TYPE = 66 -// ERROR_BAD_NET_NAME = 67 -// ERROR_SESSION_CREDENTIAL_CONFLICT = 1219 -// ERROR_LOGON_FAILURE = 1326 -var errorNoList = [...]int{53, 54, 59, 64, 65, 66, 67, 1219, 1326} - -// IsCorruptedMnt return true if err is about corrupted mount point -func IsCorruptedMnt(err error) bool { - if err == nil { - return false - } - - var underlyingError error - switch pe := err.(type) { - case nil: - return false - case *os.PathError: - underlyingError = pe.Err - case *os.LinkError: - underlyingError = pe.Err - case *os.SyscallError: - underlyingError = pe.Err - } - - if ee, ok := underlyingError.(syscall.Errno); ok { - for _, errno := range errorNoList { - if int(ee) == errno { - klog.Warningf("IsCorruptedMnt failed with error: %v, error code: %v", err, errno) - return true - } - } - } - - return false -} - -// NormalizeWindowsPath makes sure the given path is a valid path on Windows -// systems by making sure all instances of `/` are replaced with `\\`, and the -// path beings with `c:` -func NormalizeWindowsPath(path string) string { - normalizedPath := strings.Replace(path, "/", "\\", -1) - if strings.HasPrefix(normalizedPath, "\\") { - normalizedPath = "c:" + normalizedPath - } - return normalizedPath -} - -// ValidateDiskNumber : disk number should be a number in [0, 99] -func ValidateDiskNumber(disk string) error { - diskNum, err := strconv.Atoi(disk) - if err != nil { - return fmt.Errorf("wrong disk number format: %q, err:%v", disk, err) - } - - if diskNum < 0 || diskNum > 99 { - return fmt.Errorf("disk number out of range: %q", disk) - } - - return nil -} - -// isMountPointMatch determines if the mountpoint matches the dir -func isMountPointMatch(mp MountPoint, dir string) bool { - return mp.Path == dir -} diff --git a/vendor/k8s.io/utils/mount/mount_linux.go b/vendor/k8s.io/utils/mount/mount_linux.go deleted file mode 100644 index b7a443fdf..000000000 --- a/vendor/k8s.io/utils/mount/mount_linux.go +++ /dev/null @@ -1,551 +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 ( - "fmt" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" - "syscall" - - "k8s.io/klog/v2" - utilexec "k8s.io/utils/exec" - utilio "k8s.io/utils/io" -) - -const ( - // Number of fields per line in /proc/mounts as per the fstab man page. - expectedNumFieldsPerLine = 6 - // Location of the mount file to use - procMountsPath = "/proc/mounts" - // Location of the mountinfo file - procMountInfoPath = "/proc/self/mountinfo" - // 'fsck' found errors and corrected them - fsckErrorsCorrected = 1 - // 'fsck' found errors but exited without correcting them - fsckErrorsUncorrected = 4 -) - -// Mounter provides the default implementation of mount.Interface -// for the linux platform. This implementation assumes that the -// kubelet is running in the host's root mount namespace. -type Mounter struct { - mounterPath string - withSystemd bool -} - -// New returns a mount.Interface for the current system. -// It provides options to override the default mounter behavior. -// mounterPath allows using an alternative to `/bin/mount` for mounting. -func New(mounterPath string) Interface { - return &Mounter{ - mounterPath: mounterPath, - withSystemd: detectSystemd(), - } -} - -// Mount mounts source to target as fstype with given options. 'source' and 'fstype' must -// be an empty string in case it's not required, e.g. for remount, or for auto filesystem -// type, where kernel handles fstype for you. The mount 'options' is a list of options, -// currently come from mount(8), e.g. "ro", "remount", "bind", etc. If no more option is -// required, call Mount with an empty string list or nil. -func (mounter *Mounter) Mount(source string, target string, fstype string, options []string) error { - return mounter.MountSensitive(source, target, fstype, options, nil) -} - -// MountSensitive is the same as Mount() but this method allows -// sensitiveOptions to be passed in a separate parameter from the normal -// mount options and ensures the sensitiveOptions are never logged. This -// method should be used by callers that pass sensitive material (like -// passwords) as mount options. -func (mounter *Mounter) MountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error { - // 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, bindRemountOptsSensitive := MakeBindOptsSensitive(options, sensitiveOptions) - if bind { - err := mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindOpts, bindRemountOptsSensitive) - if err != nil { - return err - } - return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindRemountOpts, bindRemountOptsSensitive) - } - // The list of filesystems that require containerized mounter on GCI image cluster - fsTypesNeedMounter := map[string]struct{}{ - "nfs": {}, - "glusterfs": {}, - "ceph": {}, - "cifs": {}, - } - if _, ok := fsTypesNeedMounter[fstype]; ok { - mounterPath = mounter.mounterPath - } - return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, options, sensitiveOptions) -} - -// doMount runs the mount command. mounterPath is the path to mounter binary if containerized mounter is used. -// sensitiveOptions is an extension of options except they will not be logged (because they may contain sensitive material) -func (mounter *Mounter) doMount(mounterPath string, mountCmd string, source string, target string, fstype string, options []string, sensitiveOptions []string) error { - mountArgs, mountArgsLogStr := MakeMountArgsSensitive(source, target, fstype, options, sensitiveOptions) - if len(mounterPath) > 0 { - mountArgs = append([]string{mountCmd}, mountArgs...) - mountArgsLogStr = mountCmd + " " + mountArgsLogStr - mountCmd = mounterPath - } - - 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 - // these fuse daemons. - // - // Complete command line (when mounterPath is not used): - // systemd-run --description=... --scope -- mount -t - // - // Expected flow: - // * systemd-run creates a transient scope (=~ cgroup) and executes its - // argument (/bin/mount) there. - // * mount does its job, forks a fuse daemon if necessary and finishes. - // (systemd-run --scope finishes at this point, returning mount's exit - // code and stdout/stderr - thats one of --scope benefits). - // * systemd keeps the fuse daemon running in the scope (i.e. in its own - // cgroup) until the fuse daemon dies (another --scope benefit). - // Kubelet service can be restarted and the fuse daemon survives. - // * When the fuse daemon dies (e.g. during unmount) systemd removes the - // scope automatically. - // - // systemd-mount is not used because it's too new for older distros - // (CentOS 7, Debian Jessie). - mountCmd, mountArgs, mountArgsLogStr = AddSystemdScopeSensitive("systemd-run", target, mountCmd, mountArgs, mountArgsLogStr) - } else { - // No systemd-run on the host (or we failed to check it), assume kubelet - // does not run as a systemd service. - // No code here, mountCmd and mountArgs are already populated. - } - - // Logging with sensitive mount options removed. - klog.V(4).Infof("Mounting cmd (%s) with arguments (%s)", mountCmd, mountArgsLogStr) - command := exec.Command(mountCmd, mountArgs...) - output, err := command.CombinedOutput() - if err != nil { - klog.Errorf("Mount failed: %v\nMounting command: %s\nMounting arguments: %s\nOutput: %s\n", err, mountCmd, mountArgsLogStr, string(output)) - return fmt.Errorf("mount failed: %v\nMounting command: %s\nMounting arguments: %s\nOutput: %s", - err, mountCmd, mountArgsLogStr, string(output)) - } - return err -} - -// detectSystemd returns true if OS runs with systemd as init. When not sure -// (permission errors, ...), it returns false. -// There may be different ways how to detect systemd, this one makes sure that -// systemd-runs (needed by Mount()) works. -func detectSystemd() bool { - if _, err := exec.LookPath("systemd-run"); err != nil { - klog.V(2).Infof("Detected OS without systemd") - return false - } - // Try to run systemd-run --scope /bin/true, that should be enough - // to make sure that systemd is really running and not just installed, - // which happens when running in a container with a systemd-based image - // but with different pid 1. - cmd := exec.Command("systemd-run", "--description=Kubernetes systemd probe", "--scope", "true") - output, err := cmd.CombinedOutput() - if err != nil { - klog.V(2).Infof("Cannot run systemd-run, assuming non-systemd OS") - klog.V(4).Infof("systemd-run failed with: %v", err) - klog.V(4).Infof("systemd-run output: %s", string(output)) - return false - } - klog.V(2).Infof("Detected OS with systemd") - return true -} - -// MakeMountArgs makes the arguments to the mount(8) command. -// options MUST not contain sensitive material (like passwords). -func MakeMountArgs(source, target, fstype string, options []string) (mountArgs []string) { - mountArgs, _ = MakeMountArgsSensitive(source, target, fstype, options, nil /* sensitiveOptions */) - return mountArgs -} - -// MakeMountArgsSensitive makes the arguments to the mount(8) command. -// sensitiveOptions is an extension of options except they will not be logged (because they may contain sensitive material) -func MakeMountArgsSensitive(source, target, fstype string, options []string, sensitiveOptions []string) (mountArgs []string, mountArgsLogStr string) { - // Build mount command as follows: - // mount [-t $fstype] [-o $options] [$source] $target - mountArgs = []string{} - mountArgsLogStr = "" - if len(fstype) > 0 { - mountArgs = append(mountArgs, "-t", fstype) - mountArgsLogStr += strings.Join(mountArgs, " ") - } - if len(options) > 0 || len(sensitiveOptions) > 0 { - combinedOptions := []string{} - combinedOptions = append(combinedOptions, options...) - combinedOptions = append(combinedOptions, sensitiveOptions...) - mountArgs = append(mountArgs, "-o", strings.Join(combinedOptions, ",")) - // exclude sensitiveOptions from log string - mountArgsLogStr += " -o " + sanitizedOptionsForLogging(options, sensitiveOptions) - } - if len(source) > 0 { - mountArgs = append(mountArgs, source) - mountArgsLogStr += " " + source - } - mountArgs = append(mountArgs, target) - mountArgsLogStr += " " + target - - return mountArgs, mountArgsLogStr -} - -// AddSystemdScope adds "system-run --scope" to given command line -// If args contains sensitive material, use AddSystemdScopeSensitive to construct -// a safe to log string. -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...) -} - -// AddSystemdScopeSensitive adds "system-run --scope" to given command line -// It also accepts takes a sanitized string containing mount arguments, mountArgsLogStr, -// and returns the string appended to the systemd command for logging. -func AddSystemdScopeSensitive(systemdRunPath, mountName, command string, args []string, mountArgsLogStr string) (string, []string, string) { - descriptionArg := fmt.Sprintf("--description=Kubernetes transient mount for %s", mountName) - systemdRunArgs := []string{descriptionArg, "--scope", "--", command} - return systemdRunPath, append(systemdRunArgs, args...), strings.Join(systemdRunArgs, " ") + " " + mountArgsLogStr -} - -// Unmount unmounts the target. -func (mounter *Mounter) Unmount(target string) error { - klog.V(4).Infof("Unmounting %s", target) - command := exec.Command("umount", target) - output, err := command.CombinedOutput() - if err != nil { - 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) { - return ListProcMounts(procMountsPath) -} - -// 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. -// It also can not distinguish between mountpoints and symbolic links. -// mkdir /tmp/a /tmp/b; mount --bind /tmp/a /tmp/b; IsLikelyNotMountPoint("/tmp/b") -// will return true. When in fact /tmp/b is a mount point. If this situation -// is of interest to you, don't use this function... -func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) { - stat, err := os.Stat(file) - if err != nil { - return true, err - } - rootStat, err := os.Stat(filepath.Dir(strings.TrimSuffix(file, "/"))) - if err != nil { - return true, err - } - // If the directory has a different device as parent, then it is a mountpoint. - if stat.Sys().(*syscall.Stat_t).Dev != rootStat.Sys().(*syscall.Stat_t).Dev { - return false, nil - } - - return true, nil -} - -// GetMountRefs finds all mount references to pathname, returns a -// list of paths. Path could be a mountpoint or a normal -// directory (for bind mount). -func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) { - pathExists, pathErr := PathExists(pathname) - if !pathExists { - return []string{}, nil - } else if IsCorruptedMnt(pathErr) { - klog.Warningf("GetMountRefs found corrupted mount at %s, treating as unmounted path", pathname) - return []string{}, nil - } else if pathErr != nil { - return nil, fmt.Errorf("error checking path %s: %v", pathname, pathErr) - } - realpath, err := filepath.EvalSymlinks(pathname) - if err != nil { - return nil, err - } - return SearchMountPoints(realpath, procMountInfoPath) -} - -// checkAndRepairFileSystem checks and repairs filesystems using command fsck. -func (mounter *SafeFormatAndMount) checkAndRepairFilesystem(source string) error { - klog.V(4).Infof("Checking for issues with fsck on disk: %s", source) - args := []string{"-a", source} - out, err := mounter.Exec.Command("fsck", args...).CombinedOutput() - if err != nil { - ee, isExitError := err.(utilexec.ExitError) - switch { - case err == utilexec.ErrExecutableNotFound: - klog.Warningf("'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) - case isExitError && ee.ExitStatus() == fsckErrorsUncorrected: - return NewMountError(HasFilesystemErrors, "'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)) - } - } - return nil -} - -// formatAndMount uses unix utils to format and mount the given disk -func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error { - readOnly := false - for _, option := range options { - if option == "ro" { - readOnly = true - break - } - } - if !readOnly { - // Check sensitiveOptions for ro - for _, option := range sensitiveOptions { - if option == "ro" { - readOnly = true - break - } - } - } - - options = append(options, "defaults") - mountErrorValue := UnknownMountError - - // Check if the disk is already formatted - existingFormat, err := mounter.GetDiskFormat(source) - if err != nil { - return NewMountError(GetDiskFormatFailed, "failed to get disk format of disk %s: %v", source, err) - } - - // Use 'ext4' as the default - if len(fstype) == 0 { - fstype = "ext4" - } - - if existingFormat == "" { - // Do not attempt to format the disk if mounting as readonly, return an error to reflect this. - if readOnly { - return NewMountError(UnformattedReadOnly, "cannot mount unformatted disk %s as we are manipulating it in read-only mode", source) - } - - // Disk is unformatted so format it. - args := []string{source} - if fstype == "ext4" || fstype == "ext3" { - args = []string{ - "-F", // Force flag - "-m0", // Zero blocks reserved for super-user - source, - } - } - - klog.Infof("Disk %q appears to be unformatted, attempting to format as type: %q with options: %v", source, fstype, args) - output, err := mounter.Exec.Command("mkfs."+fstype, args...).CombinedOutput() - if err != nil { - // Do not log sensitiveOptions only options - sensitiveOptionsLog := sanitizedOptionsForLogging(options, sensitiveOptions) - detailedErr := fmt.Sprintf("format of disk %q failed: type:(%q) target:(%q) options:(%q) errcode:(%v) output:(%v) ", source, fstype, target, sensitiveOptionsLog, err, string(output)) - klog.Error(detailedErr) - return NewMountError(FormatFailed, detailedErr) - } - - klog.Infof("Disk successfully formatted (mkfs): %s - %s %s", fstype, source, target) - } else { - if fstype != existingFormat { - // Verify that the disk is formatted with filesystem type we are expecting - mountErrorValue = FilesystemMismatch - klog.Warningf("Configured to mount disk %s as %s but current format is %s, things might break", source, existingFormat, fstype) - } - - if !readOnly { - // Run check tools on the disk to fix repairable issues, only do this for formatted volumes requested as rw. - err := mounter.checkAndRepairFilesystem(source) - if err != nil { - return err - } - } - } - - // Mount the disk - klog.V(4).Infof("Attempting to mount disk %s in %s format at %s", source, fstype, target) - if err := mounter.MountSensitive(source, target, fstype, options, sensitiveOptions); err != nil { - return NewMountError(mountErrorValue, err.Error()) - } - - return nil -} - -// GetDiskFormat uses 'blkid' to see if the given disk is unformatted -func (mounter *SafeFormatAndMount) GetDiskFormat(disk string) (string, error) { - args := []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", disk} - klog.V(4).Infof("Attempting to determine if disk %q is formatted using blkid with args: (%v)", disk, args) - dataOut, err := mounter.Exec.Command("blkid", args...).CombinedOutput() - output := string(dataOut) - klog.V(4).Infof("Output: %q, err: %v", output, err) - - if err != nil { - if exit, ok := err.(utilexec.ExitError); ok { - if exit.ExitStatus() == 2 { - // Disk device is unformatted. - // For `blkid`, if the specified token (TYPE/PTTYPE, etc) was - // not found, or no (specified) devices could be identified, an - // exit code of 2 is returned. - return "", nil - } - } - klog.Errorf("Could not determine if disk %q is formatted (%v)", disk, err) - return "", err - } - - var fstype, pttype string - - lines := strings.Split(output, "\n") - for _, l := range lines { - if len(l) <= 0 { - // Ignore empty line. - continue - } - cs := strings.Split(l, "=") - if len(cs) != 2 { - return "", fmt.Errorf("blkid returns invalid output: %s", output) - } - // TYPE is filesystem type, and PTTYPE is partition table type, according - // to https://www.kernel.org/pub/linux/utils/util-linux/v2.21/libblkid-docs/. - if cs[0] == "TYPE" { - fstype = cs[1] - } else if cs[0] == "PTTYPE" { - pttype = cs[1] - } - } - - if len(pttype) > 0 { - klog.V(4).Infof("Disk %s detected partition table type: %s", disk, pttype) - // Returns a special non-empty string as filesystem type, then kubelet - // will not format it. - return "unknown data, probably partitions", nil - } - - return fstype, nil -} - -// ListProcMounts is shared with NsEnterMounter -func ListProcMounts(mountFilePath string) ([]MountPoint, error) { - content, err := utilio.ConsistentRead(mountFilePath, maxListTries) - if err != nil { - return nil, err - } - return parseProcMounts(content) -} - -func parseProcMounts(content []byte) ([]MountPoint, error) { - out := []MountPoint{} - lines := strings.Split(string(content), "\n") - for _, line := range lines { - if line == "" { - // the last split() item is empty string following the last \n - continue - } - fields := strings.Fields(line) - if len(fields) != expectedNumFieldsPerLine { - // Do not log line in case it contains sensitive Mount options - return nil, fmt.Errorf("wrong number of fields (expected %d, got %d)", expectedNumFieldsPerLine, len(fields)) - } - - mp := MountPoint{ - Device: fields[0], - Path: fields[1], - Type: fields[2], - Opts: strings.Split(fields[3], ","), - } - - freq, err := strconv.Atoi(fields[4]) - if err != nil { - return nil, err - } - mp.Freq = freq - - pass, err := strconv.Atoi(fields[5]) - if err != nil { - return nil, err - } - mp.Pass = pass - - out = append(out, mp) - } - return out, nil -} - -// SearchMountPoints finds all mount references to the source, returns a list of -// mountpoints. -// The source can be a mount point or a normal directory (bind mount). We -// didn't support device because there is no use case by now. -// 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) { - mis, err := ParseMountInfo(mountInfoPath) - if err != nil { - return nil, err - } - - mountID := 0 - rootPath := "" - major := -1 - minor := -1 - - // Finding the underlying root path and major:minor if possible. - // We need search in backward order because it's possible for later mounts - // to overlap earlier mounts. - for i := len(mis) - 1; i >= 0; i-- { - if hostSource == mis[i].MountPoint || PathWithinBase(hostSource, mis[i].MountPoint) { - // If it's a mount point or path under a mount point. - mountID = mis[i].ID - rootPath = filepath.Join(mis[i].Root, strings.TrimPrefix(hostSource, mis[i].MountPoint)) - major = mis[i].Major - minor = mis[i].Minor - break - } - } - - if rootPath == "" || major == -1 || minor == -1 { - return nil, fmt.Errorf("failed to get root path and major:minor for %s", hostSource) - } - - var refs []string - for i := range mis { - if mis[i].ID == mountID { - // Ignore mount entry for mount source itself. - continue - } - if mis[i].Root == rootPath && mis[i].Major == major && mis[i].Minor == minor { - refs = append(refs, mis[i].MountPoint) - } - } - - return refs, nil -} diff --git a/vendor/k8s.io/utils/mount/mount_unsupported.go b/vendor/k8s.io/utils/mount/mount_unsupported.go deleted file mode 100644 index 985edbe3d..000000000 --- a/vendor/k8s.io/utils/mount/mount_unsupported.go +++ /dev/null @@ -1,77 +0,0 @@ -// +build !linux,!windows - -/* -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" -) - -// Mounter implements mount.Interface for unsupported platforms -type Mounter struct { - mounterPath string -} - -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. -// mounterPath allows using an alternative to `/bin/mount` for mounting. -func New(mounterPath string) Interface { - return &Mounter{ - mounterPath: mounterPath, - } -} - -// Mount always returns an error on unsupported platforms -func (mounter *Mounter) Mount(source string, target string, fstype string, options []string) error { - return errUnsupported -} - -// Mount always returns an error on unsupported platforms -func (mounter *Mounter) MountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error { - return errUnsupported -} - -// Unmount always returns an error on unsupported platforms -func (mounter *Mounter) Unmount(target string) error { - return errUnsupported -} - -// List always returns an error on unsupported platforms -func (mounter *Mounter) List() ([]MountPoint, error) { - return []MountPoint{}, errUnsupported -} - -// IsLikelyNotMountPoint always returns an error on unsupported platforms -func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) { - return true, errUnsupported -} - -// GetMountRefs always returns an error on unsupported platforms -func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) { - return nil, errUnsupported -} - -func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error { - return mounter.Interface.Mount(source, target, fstype, options) -} - -func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) { - return true, errUnsupported -} diff --git a/vendor/k8s.io/utils/mount/mount_windows.go b/vendor/k8s.io/utils/mount/mount_windows.go deleted file mode 100644 index 4ec70fbd1..000000000 --- a/vendor/k8s.io/utils/mount/mount_windows.go +++ /dev/null @@ -1,313 +0,0 @@ -// +build windows - -/* -Copyright 2017 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 ( - "fmt" - "os" - "os/exec" - "path/filepath" - "strings" - - "k8s.io/klog/v2" - "k8s.io/utils/keymutex" -) - -const ( - accessDenied string = "access is denied" -) - -// Mounter provides the default implementation of mount.Interface -// for the windows platform. This implementation assumes that the -// kubelet is running in the host's root mount namespace. -type Mounter struct { - mounterPath string -} - -// New returns a mount.Interface for the current system. -// It provides options to override the default mounter behavior. -// mounterPath allows using an alternative to `/bin/mount` for mounting. -func New(mounterPath string) Interface { - return &Mounter{ - mounterPath: mounterPath, - } -} - -// acquire lock for smb mount -var getSMBMountMutex = keymutex.NewHashed(0) - -// Mount : mounts source to target with given options. -// currently only supports cifs(smb), bind mount(for disk) -func (mounter *Mounter) Mount(source string, target string, fstype string, options []string) error { - return mounter.MountSensitive(source, target, fstype, options, nil /* sensitiveOptions */) -} - -// MountSensitive is the same as Mount() but this method allows -// sensitiveOptions to be passed in a separate parameter from the normal -// mount options and ensures the sensitiveOptions are never logged. This -// method should be used by callers that pass sensitive material (like -// passwords) as mount options. -func (mounter *Mounter) MountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error { - target = NormalizeWindowsPath(target) - sanitizedOptionsForLogging := sanitizedOptionsForLogging(options, sensitiveOptions) - - if source == "tmpfs" { - klog.V(3).Infof("mounting source (%q), target (%q), with options (%q)", source, target, sanitizedOptionsForLogging) - return os.MkdirAll(target, 0755) - } - - parentDir := filepath.Dir(target) - if err := os.MkdirAll(parentDir, 0755); err != nil { - return err - } - - klog.V(4).Infof("mount options(%q) source:%q, target:%q, fstype:%q, begin to mount", - sanitizedOptionsForLogging, source, target, fstype) - bindSource := source - - if bind, _, _, _ := MakeBindOptsSensitive(options, sensitiveOptions); bind { - bindSource = NormalizeWindowsPath(source) - } else { - allOptions := []string{} - allOptions = append(allOptions, options...) - allOptions = append(allOptions, sensitiveOptions...) - if len(allOptions) < 2 { - return fmt.Errorf("mount options(%q) should have at least 2 options, current number:%d, source:%q, target:%q", - sanitizedOptionsForLogging, len(allOptions), source, target) - } - - // currently only cifs mount is supported - if strings.ToLower(fstype) != "cifs" { - return fmt.Errorf("only cifs mount is supported now, fstype: %q, mounting source (%q), target (%q), with options (%q)", fstype, source, target, sanitizedOptionsForLogging) - } - - // lock smb mount for the same source - getSMBMountMutex.LockKey(source) - defer getSMBMountMutex.UnlockKey(source) - - username := allOptions[0] - password := allOptions[1] - if output, err := newSMBMapping(username, password, source); err != nil { - klog.Warningf("SMB Mapping(%s) returned with error(%v), output(%s)", source, err, string(output)) - if isSMBMappingExist(source) { - valid, err := isValidPath(source) - if !valid { - if err == nil || isAccessDeniedError(err) { - klog.V(2).Infof("SMB Mapping(%s) already exists while it's not valid, return error: %v, now begin to remove and remount", source, err) - if output, err = removeSMBMapping(source); err != nil { - return fmt.Errorf("Remove-SmbGlobalMapping failed: %v, output: %q", err, output) - } - if output, err := newSMBMapping(username, password, source); err != nil { - return fmt.Errorf("New-SmbGlobalMapping(%s) failed: %v, output: %q", source, err, output) - } - } - } else { - klog.V(2).Infof("SMB Mapping(%s) already exists and is still valid, skip error(%v)", source, err) - } - } else { - return fmt.Errorf("New-SmbGlobalMapping(%s) failed: %v, output: %q", source, err, output) - } - } - } - - output, err := exec.Command("cmd", "/c", "mklink", "/D", target, bindSource).CombinedOutput() - if err != nil { - klog.Errorf("mklink failed: %v, source(%q) target(%q) output: %q", err, bindSource, target, string(output)) - return err - } - klog.V(2).Infof("mklink source(%q) on target(%q) successfully, output: %q", bindSource, target, string(output)) - - return nil -} - -// do the SMB mount with username, password, remotepath -// return (output, error) -func newSMBMapping(username, password, remotepath string) (string, error) { - if username == "" || password == "" || remotepath == "" { - return "", fmt.Errorf("invalid parameter(username: %s, password: %s, remoteapth: %s)", username, sensitiveOptionsRemoved, remotepath) - } - - // use PowerShell Environment Variables to store user input string to prevent command line injection - // https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_environment_variables?view=powershell-5.1 - cmdLine := `$PWord = ConvertTo-SecureString -String $Env:smbpassword -AsPlainText -Force` + - `;$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Env:smbuser, $PWord` + - `;New-SmbGlobalMapping -RemotePath $Env:smbremotepath -Credential $Credential` - cmd := exec.Command("powershell", "/c", cmdLine) - cmd.Env = append(os.Environ(), - fmt.Sprintf("smbuser=%s", username), - fmt.Sprintf("smbpassword=%s", password), - fmt.Sprintf("smbremotepath=%s", remotepath)) - - output, err := cmd.CombinedOutput() - return string(output), err -} - -// check whether remotepath is already mounted -func isSMBMappingExist(remotepath string) bool { - cmd := exec.Command("powershell", "/c", `Get-SmbGlobalMapping -RemotePath $Env:smbremotepath`) - cmd.Env = append(os.Environ(), fmt.Sprintf("smbremotepath=%s", remotepath)) - _, err := cmd.CombinedOutput() - return err == nil -} - -// check whether remotepath is valid -// return (true, nil) if remotepath is valid -func isValidPath(remotepath string) (bool, error) { - cmd := exec.Command("powershell", "/c", `Test-Path $Env:remoteapth`) - cmd.Env = append(os.Environ(), fmt.Sprintf("remoteapth=%s", remotepath)) - output, err := cmd.CombinedOutput() - if err != nil { - return false, fmt.Errorf("returned output: %s, error: %v", string(output), err) - } - - return strings.HasPrefix(strings.ToLower(string(output)), "true"), nil -} - -func isAccessDeniedError(err error) bool { - return err != nil && strings.Contains(strings.ToLower(err.Error()), accessDenied) -} - -// remove SMB mapping -func removeSMBMapping(remotepath string) (string, error) { - cmd := exec.Command("powershell", "/c", `Remove-SmbGlobalMapping -RemotePath $Env:smbremotepath -Force`) - cmd.Env = append(os.Environ(), fmt.Sprintf("smbremotepath=%s", remotepath)) - output, err := cmd.CombinedOutput() - return string(output), err -} - -// Unmount unmounts the target. -func (mounter *Mounter) Unmount(target string) error { - klog.V(4).Infof("azureMount: Unmount target (%q)", target) - target = NormalizeWindowsPath(target) - if output, err := exec.Command("cmd", "/c", "rmdir", target).CombinedOutput(); err != nil { - klog.Errorf("rmdir failed: %v, output: %q", err, string(output)) - return err - } - return nil -} - -// List returns a list of all mounted filesystems. todo -func (mounter *Mounter) List() ([]MountPoint, error) { - return []MountPoint{}, nil -} - -// IsLikelyNotMountPoint determines if a directory is not a mountpoint. -func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) { - stat, err := os.Lstat(file) - if err != nil { - return true, err - } - - if stat.Mode()&os.ModeSymlink != 0 { - return false, err - } - return true, nil -} - -// GetMountRefs : empty implementation here since there is no place to query all mount points on Windows -func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) { - windowsPath := NormalizeWindowsPath(pathname) - pathExists, pathErr := PathExists(windowsPath) - if !pathExists { - return []string{}, nil - } else if IsCorruptedMnt(pathErr) { - klog.Warningf("GetMountRefs found corrupted mount at %s, treating as unmounted path", windowsPath) - return []string{}, nil - } else if pathErr != nil { - return nil, fmt.Errorf("error checking path %s: %v", windowsPath, pathErr) - } - return []string{pathname}, nil -} - -func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error { - // Try to mount the disk - klog.V(4).Infof("Attempting to formatAndMount disk: %s %s %s", fstype, source, target) - - if err := ValidateDiskNumber(source); err != nil { - klog.Errorf("diskMount: formatAndMount failed, err: %v", err) - return err - } - - if len(fstype) == 0 { - // Use 'NTFS' as the default - fstype = "NTFS" - } - - // format disk if it is unformatted(raw) - cmd := fmt.Sprintf("Get-Disk -Number %s | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle MBR -PassThru"+ - " | New-Partition -UseMaximumSize | Format-Volume -FileSystem %s -Confirm:$false", source, fstype) - if output, err := mounter.Exec.Command("powershell", "/c", cmd).CombinedOutput(); err != nil { - return fmt.Errorf("diskMount: format disk failed, error: %v, output: %q", err, string(output)) - } - klog.V(4).Infof("diskMount: Disk successfully formatted, disk: %q, fstype: %q", source, fstype) - - volumeIds, err := listVolumesOnDisk(source) - if err != nil { - return err - } - driverPath := volumeIds[0] - target = NormalizeWindowsPath(target) - output, err := mounter.Exec.Command("cmd", "/c", "mklink", "/D", target, driverPath).CombinedOutput() - if err != nil { - klog.Errorf("mklink(%s, %s) failed: %v, output: %q", target, driverPath, err, string(output)) - return err - } - klog.V(2).Infof("formatAndMount disk(%s) fstype(%s) on(%s) with output(%s) successfully", driverPath, fstype, target, string(output)) - return nil -} - -// ListVolumesOnDisk - returns back list of volumes(volumeIDs) in the disk (requested in diskID). -func listVolumesOnDisk(diskID string) (volumeIDs []string, err error) { - cmd := fmt.Sprintf("(Get-Disk -DeviceId %s | Get-Partition | Get-Volume).UniqueId", diskID) - output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() - klog.V(4).Infof("listVolumesOnDisk id from %s: %s", diskID, string(output)) - if err != nil { - return []string{}, fmt.Errorf("error list volumes on disk. cmd: %s, output: %s, error: %v", cmd, string(output), err) - } - - volumeIds := strings.Split(strings.TrimSpace(string(output)), "\r\n") - return volumeIds, nil -} - -// getAllParentLinks walks all symbolic links and return all the parent targets recursively -func getAllParentLinks(path string) ([]string, error) { - const maxIter = 255 - links := []string{} - for { - links = append(links, path) - if len(links) > maxIter { - return links, fmt.Errorf("unexpected length of parent links: %v", links) - } - - fi, err := os.Lstat(path) - if err != nil { - return links, fmt.Errorf("Lstat: %v", err) - } - if fi.Mode()&os.ModeSymlink == 0 { - break - } - - path, err = os.Readlink(path) - if err != nil { - return links, fmt.Errorf("Readlink error: %v", err) - } - } - - return links, nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index ba28aa167..73f82105f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1191,7 +1191,6 @@ k8s.io/utils/internal/third_party/forked/golang/net k8s.io/utils/io k8s.io/utils/keymutex k8s.io/utils/lru -k8s.io/utils/mount k8s.io/utils/net k8s.io/utils/nsenter k8s.io/utils/path