rebase: update k8s.io/mount-utils to current master

kubernetes/kubernetes#111083 has been merged and synced into
k8s.io/mount-utils. This should remove any systemd log messages while
calling NodeStageVolume and NodeGetVolumeStats.

Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
Niels de Vos
2022-07-15 11:53:35 +02:00
committed by mergify[bot]
parent 3c3cbc8005
commit 533994daff
103 changed files with 3102 additions and 496 deletions

View File

@ -32,8 +32,9 @@ type FakeMounter struct {
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
mutex sync.Mutex
UnmountFunc UnmountFunc
skipMountPointCheck bool
}
// UnmountFunc is a function callback to be executed during the Unmount() call.
@ -64,6 +65,11 @@ func NewFakeMounter(mps []MountPoint) *FakeMounter {
}
}
func (f *FakeMounter) WithSkipMountPointCheck() *FakeMounter {
f.skipMountPointCheck = true
return f
}
// ResetLog clears all the log entries in FakeMounter
func (f *FakeMounter) ResetLog() {
f.mutex.Lock()
@ -212,6 +218,18 @@ func (f *FakeMounter) IsLikelyNotMountPoint(file string) (bool, error) {
return true, nil
}
func (f *FakeMounter) canSafelySkipMountPointCheck() bool {
return f.skipMountPointCheck
}
func (f *FakeMounter) IsMountPoint(file string) (bool, error) {
notMnt, err := f.IsLikelyNotMountPoint(file)
if err != nil {
return false, err
}
return !notMnt, nil
}
// GetMountRefs finds all mount references to the path, returns a
// list of paths.
func (f *FakeMounter) GetMountRefs(pathname string) ([]string, error) {

80
vendor/k8s.io/mount-utils/mount.go generated vendored
View File

@ -21,7 +21,6 @@ package mount
import (
"fmt"
"os"
"path/filepath"
"strings"
"time"
@ -66,6 +65,18 @@ type Interface interface {
// care about such situations, this is a faster alternative to calling List()
// and scanning that output.
IsLikelyNotMountPoint(file string) (bool, error)
// canSafelySkipMountPointCheck indicates whether this mounter returns errors on
// operations for targets that are not mount points. If this returns true, no such
// errors will be returned.
canSafelySkipMountPointCheck() bool
// IsMountPoint determines if a directory is a mountpoint.
// It should return ErrNotExist when the directory does not exist.
// IsMountPoint is more expensive than IsLikelyNotMountPoint.
// IsMountPoint detects bind mounts in linux.
// IsMountPoint may enumerate 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.
IsMountPoint(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.
@ -187,6 +198,24 @@ func getMountRefsByDev(mounter Interface, mountPath string) ([]string, error) {
return refs, 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
// and depends on IsMountPoint.
//
// If an error occurs, it returns true (assuming it is not a mountpoint)
// when ErrNotExist is returned for callers similar to IsLikelyNotMountPoint.
//
// Deprecated: This function is kept to keep changes backward compatible with
// previous library version. Callers should prefer mounter.IsMountPoint.
func IsNotMountPoint(mounter Interface, file string) (bool, error) {
isMnt, err := mounter.IsMountPoint(file)
if err != nil {
return true, err
}
return !isMnt, 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) {
@ -220,56 +249,11 @@ func GetDeviceNameFromMount(mounter Interface, mountPath string) (string, int, e
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)
//
// options - 'bind' + 'remount' (no duplicate)
func MakeBindOpts(options []string) (bool, []string, []string) {
bind, bindOpts, bindRemountOpts, _ := MakeBindOptsSensitive(options, nil /* sensitiveOptions */)
return bind, bindOpts, bindRemountOpts

View File

@ -31,7 +31,7 @@ import (
func CleanupMountPoint(mountPath string, mounter Interface, extensiveMountPointCheck bool) error {
pathExists, pathErr := PathExists(mountPath)
if !pathExists && pathErr == nil {
klog.Warningf("Warning: Unmount skipped because path does not exist: %v", mountPath)
klog.Warningf("Warning: mount cleanup skipped because path does not exist: %v", mountPath)
return nil
}
corruptedMnt := IsCorruptedMnt(pathErr)
@ -44,36 +44,41 @@ func CleanupMountPoint(mountPath string, mounter Interface, extensiveMountPointC
func CleanupMountWithForce(mountPath string, mounter MounterForceUnmounter, extensiveMountPointCheck bool, umountTimeout time.Duration) error {
pathExists, pathErr := PathExists(mountPath)
if !pathExists && pathErr == nil {
klog.Warningf("Warning: Unmount skipped because path does not exist: %v", mountPath)
klog.Warningf("Warning: mount cleanup 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)
}
var notMnt bool
var err error
if !corruptedMnt {
notMnt, err = removePathIfNotMountPoint(mountPath, mounter, extensiveMountPointCheck)
// if mountPath was not a mount point - we would have attempted to remove mountPath
// and hence return errors if any.
if err != nil || notMnt {
if corruptedMnt || mounter.canSafelySkipMountPointCheck() {
klog.V(4).Infof("unmounting %q (corruptedMount: %t, mounterCanSkipMountPointChecks: %t)",
mountPath, corruptedMnt, mounter.canSafelySkipMountPointCheck())
if err := mounter.UnmountWithForce(mountPath, umountTimeout); err != nil {
return err
}
return removePath(mountPath)
}
notMnt, err := removePathIfNotMountPoint(mountPath, mounter, extensiveMountPointCheck)
// if mountPath is not a mount point, it's just been removed or there was an error
if err != nil || notMnt {
return err
}
// Unmount the mount path
klog.V(4).Infof("%q is a mountpoint, unmounting", mountPath)
if err := mounter.UnmountWithForce(mountPath, umountTimeout); err != nil {
return err
}
notMnt, err = removePathIfNotMountPoint(mountPath, mounter, extensiveMountPointCheck)
// mountPath is not a mount point we should return whatever error we saw
// if mountPath is not a mount point, it's either just been removed or there was an error
if notMnt {
return err
}
return fmt.Errorf("Failed to unmount path %v", mountPath)
// mountPath is still a mount point
return fmt.Errorf("failed to cleanup mount point %v", mountPath)
}
// doCleanupMountPoint unmounts the given path and
@ -82,31 +87,35 @@ func CleanupMountWithForce(mountPath string, mounter MounterForceUnmounter, exte
// 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
// will be skipped. The mount point check will also be skipped if the mounter supports it.
func doCleanupMountPoint(mountPath string, mounter Interface, extensiveMountPointCheck bool, corruptedMnt bool) error {
var notMnt bool
var err error
if !corruptedMnt {
notMnt, err = removePathIfNotMountPoint(mountPath, mounter, extensiveMountPointCheck)
// if mountPath was not a mount point - we would have attempted to remove mountPath
// and hence return errors if any.
if err != nil || notMnt {
if corruptedMnt || mounter.canSafelySkipMountPointCheck() {
klog.V(4).Infof("unmounting %q (corruptedMount: %t, mounterCanSkipMountPointChecks: %t)",
mountPath, corruptedMnt, mounter.canSafelySkipMountPointCheck())
if err := mounter.Unmount(mountPath); err != nil {
return err
}
return removePath(mountPath)
}
notMnt, err := removePathIfNotMountPoint(mountPath, mounter, extensiveMountPointCheck)
// if mountPath is not a mount point, it's just been removed or there was an error
if err != nil || notMnt {
return err
}
// Unmount the mount path
klog.V(4).Infof("%q is a mountpoint, unmounting", mountPath)
if err := mounter.Unmount(mountPath); err != nil {
return err
}
notMnt, err = removePathIfNotMountPoint(mountPath, mounter, extensiveMountPointCheck)
// mountPath is not a mount point we should return whatever error we saw
// if mountPath is not a mount point, it's either just been removed or there was an error
if notMnt {
return err
}
return fmt.Errorf("Failed to unmount path %v", mountPath)
// mountPath is still a mount point
return fmt.Errorf("failed to cleanup mount point %v", mountPath)
}
// removePathIfNotMountPoint verifies if given mountPath is a mount point if not it attempts
@ -135,3 +144,14 @@ func removePathIfNotMountPoint(mountPath string, mounter Interface, extensiveMou
}
return notMnt, nil
}
// removePath attempts to remove the directory. Returns nil if the directory was removed or does not exist.
func removePath(mountPath string) error {
klog.V(4).Infof("Warning: deleting path %q", mountPath)
err := os.Remove(mountPath)
if os.IsNotExist(err) {
klog.V(4).Infof("%q does not exist", mountPath)
return nil
}
return err
}

View File

@ -21,7 +21,11 @@ package mount
import (
"context"
"errors"
"fmt"
"github.com/moby/sys/mountinfo"
"io/fs"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@ -48,14 +52,18 @@ const (
fsckErrorsUncorrected = 4
// Error thrown by exec cmd.Run() when process spawned by cmd.Start() completes before cmd.Wait() is called (see - k/k issue #103753)
errNoChildProcesses = "wait: no child processes"
// Error returned by some `umount` implementations when the specified path is not a mount point
errNotMounted = "not mounted"
)
// 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
mounterPath string
withSystemd *bool
trySystemd bool
withSafeNotMountedBehavior bool
}
var _ MounterForceUnmounter = &Mounter{}
@ -65,11 +73,39 @@ var _ MounterForceUnmounter = &Mounter{}
// mounterPath allows using an alternative to `/bin/mount` for mounting.
func New(mounterPath string) Interface {
return &Mounter{
mounterPath: mounterPath,
withSystemd: detectSystemd(),
mounterPath: mounterPath,
trySystemd: true,
withSafeNotMountedBehavior: detectSafeNotMountedBehavior(),
}
}
// NewWithoutSystemd returns a Linux specific 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. Any
// detection for systemd functionality is disabled with this Mounter.
func NewWithoutSystemd(mounterPath string) Interface {
return &Mounter{
mounterPath: mounterPath,
trySystemd: false,
withSafeNotMountedBehavior: detectSafeNotMountedBehavior(),
}
}
// hasSystemd validates that the withSystemd bool is set, if it is not,
// detectSystemd will be called once for this Mounter instance.
func (mounter *Mounter) hasSystemd() bool {
if !mounter.trySystemd {
mounter.withSystemd = &mounter.trySystemd
}
if mounter.withSystemd == nil {
withSystemd := detectSystemd()
mounter.withSystemd = &withSystemd
}
return *mounter.withSystemd
}
// 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,
@ -90,11 +126,11 @@ func (mounter *Mounter) MountSensitive(source string, target string, fstype stri
mounterPath := ""
bind, bindOpts, bindRemountOpts, bindRemountOptsSensitive := MakeBindOptsSensitive(options, sensitiveOptions)
if bind {
err := mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindOpts, bindRemountOptsSensitive, nil /* mountFlags */, true)
err := mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindOpts, bindRemountOptsSensitive, nil /* mountFlags */, mounter.trySystemd)
if err != nil {
return err
}
return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindRemountOpts, bindRemountOptsSensitive, nil /* mountFlags */, true)
return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindRemountOpts, bindRemountOptsSensitive, nil /* mountFlags */, mounter.trySystemd)
}
// The list of filesystems that require containerized mounter on GCI image cluster
fsTypesNeedMounter := map[string]struct{}{
@ -106,7 +142,7 @@ func (mounter *Mounter) MountSensitive(source string, target string, fstype stri
if _, ok := fsTypesNeedMounter[fstype]; ok {
mounterPath = mounter.mounterPath
}
return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, options, sensitiveOptions, nil /* mountFlags */, true)
return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, options, sensitiveOptions, nil /* mountFlags */, mounter.trySystemd)
}
// MountSensitiveWithoutSystemd is the same as MountSensitive() but disable using systemd mount.
@ -149,7 +185,7 @@ func (mounter *Mounter) doMount(mounterPath string, mountCmd string, source stri
mountCmd = mounterPath
}
if mounter.withSystemd && systemdMountRequired {
if systemdMountRequired && mounter.hasSystemd() {
// 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
@ -223,6 +259,36 @@ func detectSystemd() bool {
return true
}
// detectSafeNotMountedBehavior returns true if the umount implementation replies "not mounted"
// when the specified path is not mounted. When not sure (permission errors, ...), it returns false.
// When possible, we will trust umount's message and avoid doing our own mount point checks.
// More info: https://github.com/util-linux/util-linux/blob/v2.2/mount/umount.c#L179
func detectSafeNotMountedBehavior() bool {
return detectSafeNotMountedBehaviorWithExec(utilexec.New())
}
// detectSafeNotMountedBehaviorWithExec is for testing with FakeExec.
func detectSafeNotMountedBehaviorWithExec(exec utilexec.Interface) bool {
// create a temp dir and try to umount it
path, err := ioutil.TempDir("", "kubelet-detect-safe-umount")
if err != nil {
klog.V(4).Infof("Cannot create temp dir to detect safe 'not mounted' behavior: %v", err)
return false
}
defer os.RemoveAll(path)
cmd := exec.Command("umount", path)
output, err := cmd.CombinedOutput()
if err != nil {
if strings.Contains(string(output), errNotMounted) {
klog.V(4).Infof("Detected umount with safe 'not mounted' behavior")
return true
}
klog.V(4).Infof("'umount %s' failed with: %v, output: %s", path, err, string(output))
}
klog.V(4).Infof("Detected umount with unsafe 'not mounted' behavior")
return false
}
// 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) {
@ -290,6 +356,7 @@ func AddSystemdScopeSensitive(systemdRunPath, mountName, command string, args []
}
// Unmount unmounts the target.
// If the mounter has safe "not mounted" behavior, no error will be returned when the target is not a mount point.
func (mounter *Mounter) Unmount(target string) error {
klog.V(4).Infof("Unmounting %s", target)
command := exec.Command("umount", target)
@ -303,6 +370,10 @@ func (mounter *Mounter) Unmount(target string) error {
// Rewrite err with the actual exit error of the process.
err = &exec.ExitError{ProcessState: command.ProcessState}
}
if mounter.withSafeNotMountedBehavior && strings.Contains(string(output), errNotMounted) {
klog.V(4).Infof("ignoring 'not mounted' error for %s", target)
return nil
}
return fmt.Errorf("unmount failed: %v\nUnmounting arguments: %s\nOutput: %s", err, target, string(output))
}
return nil
@ -351,6 +422,11 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
return true, nil
}
// canSafelySkipMountPointCheck relies on the detected behavior of umount when given a target that is not a mount point.
func (mounter *Mounter) canSafelySkipMountPointCheck() bool {
return mounter.withSafeNotMountedBehavior
}
// GetMountRefs finds all mount references to pathname, returns a
// list of paths. Path could be a mountpoint or a normal
// directory (for bind mount).
@ -637,6 +713,63 @@ func SearchMountPoints(hostSource, mountInfoPath string) ([]string, error) {
return refs, nil
}
// IsMountPoint determines if a file is a mountpoint.
// It first detects bind & any other mountpoints using
// MountedFast function. If the MountedFast function returns
// sure as true and err as nil, then a mountpoint is detected
// successfully. When an error is returned by MountedFast, the
// following is true:
// 1. All errors are returned with IsMountPoint as false
// except os.IsPermission.
// 2. When os.IsPermission is returned by MountedFast, List()
// is called to confirm if the given file is a mountpoint are not.
//
// os.ErrNotExist should always be returned if a file does not exist
// as callers have in past relied on this error and not fallback.
//
// When MountedFast returns sure as false and err as nil (eg: in
// case of bindmounts on kernel version 5.10- ); mounter.List()
// endpoint is called to enumerate all the mountpoints and check if
// it is mountpoint match or not.
func (mounter *Mounter) IsMountPoint(file string) (bool, error) {
isMnt, sure, isMntErr := mountinfo.MountedFast(file)
if sure && isMntErr == nil {
return isMnt, nil
}
if isMntErr != nil {
if errors.Is(isMntErr, fs.ErrNotExist) {
return false, fs.ErrNotExist
}
// We were not allowed to do the simple stat() check, e.g. on NFS with
// root_squash. Fall back to /proc/mounts check below when
// fs.ErrPermission is returned.
if !errors.Is(isMntErr, fs.ErrPermission) {
return false, isMntErr
}
}
// 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 {
if errors.Is(isMntErr, fs.ErrNotExist) {
return false, fs.ErrNotExist
}
return false, err
}
// check all mountpoints since MountedFast is not sure.
// is not reliable for some mountpoint types.
mountPoints, mountPointsErr := mounter.List()
if mountPointsErr != nil {
return false, mountPointsErr
}
for _, mp := range mountPoints {
if isMountPointMatch(mp, resolvedFile) {
return true, nil
}
}
return false, nil
}
// tryUnmount calls plain "umount" and waits for unmountTimeout for it to finish.
func tryUnmount(path string, unmountTimeout time.Duration) error {
klog.V(4).Infof("Unmounting %s", path)

View File

@ -74,6 +74,17 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
return true, errUnsupported
}
// canSafelySkipMountPointCheck always returns false on unsupported platforms
func (mounter *Mounter) canSafelySkipMountPointCheck() bool {
return false
}
// IsMountPoint determines if a directory is a mountpoint.
// It always returns an error on unsupported platforms.
func (mounter *Mounter) IsMountPoint(file string) (bool, error) {
return false, errUnsupported
}
// GetMountRefs always returns an error on unsupported platforms
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
return nil, errUnsupported
@ -86,3 +97,9 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target
func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) {
return true, errUnsupported
}
// IsMountPoint determines if a directory is a mountpoint.
// It always returns an error on unsupported platforms.
func (mounter *SafeFormatAndMount) IsMountPoint(file string) (bool, error) {
return false, errUnsupported
}

View File

@ -244,6 +244,20 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
return true, nil
}
// canSafelySkipMountPointCheck always returns false on Windows
func (mounter *Mounter) canSafelySkipMountPointCheck() bool {
return false
}
// IsMountPoint: determines if a directory is a mountpoint.
func (mounter *Mounter) IsMountPoint(file string) (bool, error) {
isNotMnt, err := mounter.IsLikelyNotMountPoint(file)
if err != nil {
return false, err
}
return !isNotMnt, 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)

View File

@ -39,3 +39,8 @@ func NewResizeFs(exec utilexec.Interface) *ResizeFs {
func (resizefs *ResizeFs) Resize(devicePath string, deviceMountPath string) (bool, error) {
return false, fmt.Errorf("Resize is not supported for this build")
}
// NeedResize check whether mounted volume needs resize
func (resizefs *ResizeFs) NeedResize(devicePath string, deviceMountPath string) (bool, error) {
return false, fmt.Errorf("NeedResize is not supported for this build")
}

10
vendor/k8s.io/utils/exec/exec.go generated vendored
View File

@ -19,6 +19,7 @@ package exec
import (
"context"
"io"
"io/fs"
osexec "os/exec"
"syscall"
"time"
@ -98,17 +99,18 @@ func New() Interface {
// Command is part of the Interface interface.
func (executor *executor) Command(cmd string, args ...string) Cmd {
return (*cmdWrapper)(osexec.Command(cmd, args...))
return (*cmdWrapper)(maskErrDotCmd(osexec.Command(cmd, args...)))
}
// CommandContext is part of the Interface interface.
func (executor *executor) CommandContext(ctx context.Context, cmd string, args ...string) Cmd {
return (*cmdWrapper)(osexec.CommandContext(ctx, cmd, args...))
return (*cmdWrapper)(maskErrDotCmd(osexec.CommandContext(ctx, cmd, args...)))
}
// LookPath is part of the Interface interface
func (executor *executor) LookPath(file string) (string, error) {
return osexec.LookPath(file)
path, err := osexec.LookPath(file)
return path, handleError(maskErrDot(err))
}
// Wraps exec.Cmd so we can capture errors.
@ -198,6 +200,8 @@ func handleError(err error) error {
switch e := err.(type) {
case *osexec.ExitError:
return &ExitErrorWrapper{e}
case *fs.PathError:
return ErrExecutableNotFound
case *osexec.Error:
if e.Err == osexec.ErrNotFound {
return ErrExecutableNotFound

32
vendor/k8s.io/utils/exec/fixup_go118.go generated vendored Normal file
View File

@ -0,0 +1,32 @@
//go:build !go1.19
// +build !go1.19
/*
Copyright 2022 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 exec
import (
osexec "os/exec"
)
func maskErrDotCmd(cmd *osexec.Cmd) *osexec.Cmd {
return cmd
}
func maskErrDot(err error) error {
return err
}

40
vendor/k8s.io/utils/exec/fixup_go119.go generated vendored Normal file
View File

@ -0,0 +1,40 @@
//go:build go1.19
// +build go1.19
/*
Copyright 2022 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 exec
import (
"errors"
osexec "os/exec"
)
// maskErrDotCmd reverts the behavior of osexec.Cmd to what it was before go1.19
// specifically set the Err field to nil (LookPath returns a new error when the file
// is resolved to the current directory.
func maskErrDotCmd(cmd *osexec.Cmd) *osexec.Cmd {
cmd.Err = maskErrDot(cmd.Err)
return cmd
}
func maskErrDot(err error) error {
if err != nil && errors.Is(err, osexec.ErrDot) {
return nil
}
return err
}

View File

@ -1,3 +1,4 @@
//go:build linux
// +build linux
/*

View File

@ -1,3 +1,4 @@
//go:build !linux
// +build !linux
/*

View File

@ -52,6 +52,8 @@ func Int(i int) *int {
return &i
}
// IntPtr is a function variable referring to Int.
// Deprecated: Use Int instead.
var IntPtr = Int // for back-compat
// IntDeref dereferences the int ptr and returns it if not nil, or else
@ -63,6 +65,8 @@ func IntDeref(ptr *int, def int) int {
return def
}
// IntPtrDerefOr is a function variable referring to IntDeref.
// Deprecated: Use IntDeref instead.
var IntPtrDerefOr = IntDeref // for back-compat
// Int32 returns a pointer to an int32.
@ -70,6 +74,8 @@ func Int32(i int32) *int32 {
return &i
}
// Int32Ptr is a function variable referring to Int32.
// Deprecated: Use Int32 instead.
var Int32Ptr = Int32 // for back-compat
// Int32Deref dereferences the int32 ptr and returns it if not nil, or else
@ -81,6 +87,8 @@ func Int32Deref(ptr *int32, def int32) int32 {
return def
}
// Int32PtrDerefOr is a function variable referring to Int32Deref.
// Deprecated: Use Int32Deref instead.
var Int32PtrDerefOr = Int32Deref // for back-compat
// Int32Equal returns true if both arguments are nil or both arguments
@ -100,6 +108,8 @@ func Int64(i int64) *int64 {
return &i
}
// Int64Ptr is a function variable referring to Int64.
// Deprecated: Use Int64 instead.
var Int64Ptr = Int64 // for back-compat
// Int64Deref dereferences the int64 ptr and returns it if not nil, or else
@ -111,6 +121,8 @@ func Int64Deref(ptr *int64, def int64) int64 {
return def
}
// Int64PtrDerefOr is a function variable referring to Int64Deref.
// Deprecated: Use Int64Deref instead.
var Int64PtrDerefOr = Int64Deref // for back-compat
// Int64Equal returns true if both arguments are nil or both arguments
@ -130,6 +142,8 @@ func Bool(b bool) *bool {
return &b
}
// BoolPtr is a function variable referring to Bool.
// Deprecated: Use Bool instead.
var BoolPtr = Bool // for back-compat
// BoolDeref dereferences the bool ptr and returns it if not nil, or else
@ -141,6 +155,8 @@ func BoolDeref(ptr *bool, def bool) bool {
return def
}
// BoolPtrDerefOr is a function variable referring to BoolDeref.
// Deprecated: Use BoolDeref instead.
var BoolPtrDerefOr = BoolDeref // for back-compat
// BoolEqual returns true if both arguments are nil or both arguments
@ -160,6 +176,8 @@ func String(s string) *string {
return &s
}
// StringPtr is a function variable referring to String.
// Deprecated: Use String instead.
var StringPtr = String // for back-compat
// StringDeref dereferences the string ptr and returns it if not nil, or else
@ -171,6 +189,8 @@ func StringDeref(ptr *string, def string) string {
return def
}
// StringPtrDerefOr is a function variable referring to StringDeref.
// Deprecated: Use StringDeref instead.
var StringPtrDerefOr = StringDeref // for back-compat
// StringEqual returns true if both arguments are nil or both arguments
@ -190,6 +210,8 @@ func Float32(i float32) *float32 {
return &i
}
// Float32Ptr is a function variable referring to Float32.
// Deprecated: Use Float32 instead.
var Float32Ptr = Float32
// Float32Deref dereferences the float32 ptr and returns it if not nil, or else
@ -201,6 +223,8 @@ func Float32Deref(ptr *float32, def float32) float32 {
return def
}
// Float32PtrDerefOr is a function variable referring to Float32Deref.
// Deprecated: Use Float32Deref instead.
var Float32PtrDerefOr = Float32Deref // for back-compat
// Float32Equal returns true if both arguments are nil or both arguments
@ -220,6 +244,8 @@ func Float64(i float64) *float64 {
return &i
}
// Float64Ptr is a function variable referring to Float64.
// Deprecated: Use Float64 instead.
var Float64Ptr = Float64
// Float64Deref dereferences the float64 ptr and returns it if not nil, or else
@ -231,6 +257,8 @@ func Float64Deref(ptr *float64, def float64) float64 {
return def
}
// Float64PtrDerefOr is a function variable referring to Float64Deref.
// Deprecated: Use Float64Deref instead.
var Float64PtrDerefOr = Float64Deref // for back-compat
// Float64Equal returns true if both arguments are nil or both arguments