Update go dependencies
This commit is contained in:
parent
14a9e9f3fa
commit
14f4a7b8e8
1349 changed files with 128369 additions and 32627 deletions
342
vendor/k8s.io/kubernetes/pkg/util/mount/mount_windows.go
generated
vendored
342
vendor/k8s.io/kubernetes/pkg/util/mount/mount_windows.go
generated
vendored
|
|
@ -26,11 +26,11 @@ import (
|
|||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"k8s.io/klog"
|
||||
"k8s.io/utils/keymutex"
|
||||
|
||||
utilfile "k8s.io/kubernetes/pkg/util/file"
|
||||
utilpath "k8s.io/utils/path"
|
||||
)
|
||||
|
||||
// Mounter provides the default implementation of mount.Interface
|
||||
|
|
@ -49,12 +49,16 @@ func New(mounterPath string) Interface {
|
|||
}
|
||||
}
|
||||
|
||||
// Mount : mounts source to target as NTFS with given options.
|
||||
// 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 {
|
||||
target = normalizeWindowsPath(target)
|
||||
|
||||
if source == "tmpfs" {
|
||||
klog.V(3).Infof("azureMount: mounting source (%q), target (%q), with options (%q)", source, target, options)
|
||||
klog.V(3).Infof("mounting source (%q), target (%q), with options (%q)", source, target, options)
|
||||
return os.MkdirAll(target, 0755)
|
||||
}
|
||||
|
||||
|
|
@ -63,9 +67,9 @@ func (mounter *Mounter) Mount(source string, target string, fstype string, optio
|
|||
return err
|
||||
}
|
||||
|
||||
klog.V(4).Infof("azureMount: mount options(%q) source:%q, target:%q, fstype:%q, begin to mount",
|
||||
klog.V(4).Infof("mount options(%q) source:%q, target:%q, fstype:%q, begin to mount",
|
||||
options, source, target, fstype)
|
||||
bindSource := ""
|
||||
bindSource := source
|
||||
|
||||
// tell it's going to mount azure disk or azure file according to options
|
||||
if bind, _, _ := isBind(options); bind {
|
||||
|
|
@ -73,31 +77,32 @@ func (mounter *Mounter) Mount(source string, target string, fstype string, optio
|
|||
bindSource = normalizeWindowsPath(source)
|
||||
} else {
|
||||
if len(options) < 2 {
|
||||
klog.Warningf("azureMount: mount options(%q) command number(%d) less than 2, source:%q, target:%q, skip mounting",
|
||||
klog.Warningf("mount options(%q) command number(%d) less than 2, source:%q, target:%q, skip mounting",
|
||||
options, len(options), source, target)
|
||||
return nil
|
||||
}
|
||||
|
||||
// currently only cifs mount is supported
|
||||
if strings.ToLower(fstype) != "cifs" {
|
||||
return fmt.Errorf("azureMount: only cifs mount is supported now, fstype: %q, mounting source (%q), target (%q), with options (%q)", fstype, source, target, options)
|
||||
return fmt.Errorf("only cifs mount is supported now, fstype: %q, mounting source (%q), target (%q), with options (%q)", fstype, source, target, options)
|
||||
}
|
||||
|
||||
bindSource = source
|
||||
// lock smb mount for the same source
|
||||
getSMBMountMutex.LockKey(source)
|
||||
defer getSMBMountMutex.UnlockKey(source)
|
||||
|
||||
// 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 := fmt.Sprintf(`$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", options[0]),
|
||||
fmt.Sprintf("smbpassword=%s", options[1]),
|
||||
fmt.Sprintf("smbremotepath=%s", source))
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("azureMount: SmbGlobalMapping failed: %v, only SMB mount is supported now, output: %q", err, string(output))
|
||||
if output, err := newSMBMapping(options[0], options[1], source); err != nil {
|
||||
if isSMBMappingExist(source) {
|
||||
klog.V(2).Infof("SMB Mapping(%s) already exists, now begin to remove and remount", source)
|
||||
if output, err := removeSMBMapping(source); err != nil {
|
||||
return fmt.Errorf("Remove-SmbGlobalMapping failed: %v, output: %q", err, output)
|
||||
}
|
||||
if output, err := newSMBMapping(options[0], options[1], source); err != nil {
|
||||
return fmt.Errorf("New-SmbGlobalMapping remount failed: %v, output: %q", err, output)
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("New-SmbGlobalMapping failed: %v, output: %q", err, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,6 +114,44 @@ func (mounter *Mounter) Mount(source string, target string, fstype string, optio
|
|||
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, password, 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
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
|
@ -132,7 +175,7 @@ func (mounter *Mounter) IsMountPointMatch(mp MountPoint, dir string) bool {
|
|||
|
||||
// IsNotMountPoint determines if a directory is a mountpoint.
|
||||
func (mounter *Mounter) IsNotMountPoint(dir string) (bool, error) {
|
||||
return IsNotMountPoint(mounter, dir)
|
||||
return isNotMountPoint(mounter, dir)
|
||||
}
|
||||
|
||||
// IsLikelyNotMountPoint determines if a directory is not a mountpoint.
|
||||
|
|
@ -235,7 +278,7 @@ func (mounter *Mounter) MakeFile(pathname string) error {
|
|||
|
||||
// ExistsPath checks whether the path exists
|
||||
func (mounter *Mounter) ExistsPath(pathname string) (bool, error) {
|
||||
return utilfile.FileExists(pathname)
|
||||
return utilpath.Exists(utilpath.CheckFollowSymlink, pathname)
|
||||
}
|
||||
|
||||
// EvalHostSymlinks returns the path name after evaluating symlinks
|
||||
|
|
@ -243,123 +286,6 @@ func (mounter *Mounter) EvalHostSymlinks(pathname string) (string, error) {
|
|||
return filepath.EvalSymlinks(pathname)
|
||||
}
|
||||
|
||||
// check whether hostPath is within volume path
|
||||
// this func will lock all intermediate subpath directories, need to close handle outside of this func after container started
|
||||
func lockAndCheckSubPath(volumePath, hostPath string) ([]uintptr, error) {
|
||||
if len(volumePath) == 0 || len(hostPath) == 0 {
|
||||
return []uintptr{}, nil
|
||||
}
|
||||
|
||||
finalSubPath, err := filepath.EvalSymlinks(hostPath)
|
||||
if err != nil {
|
||||
return []uintptr{}, fmt.Errorf("cannot read link %s: %s", hostPath, err)
|
||||
}
|
||||
finalVolumePath, err := filepath.EvalSymlinks(volumePath)
|
||||
if err != nil {
|
||||
return []uintptr{}, fmt.Errorf("cannot read link %s: %s", volumePath, err)
|
||||
}
|
||||
|
||||
return lockAndCheckSubPathWithoutSymlink(finalVolumePath, finalSubPath)
|
||||
}
|
||||
|
||||
// lock all intermediate subPath directories and check they are all within volumePath
|
||||
// volumePath & subPath should not contain any symlink, otherwise it will return error
|
||||
func lockAndCheckSubPathWithoutSymlink(volumePath, subPath string) ([]uintptr, error) {
|
||||
if len(volumePath) == 0 || len(subPath) == 0 {
|
||||
return []uintptr{}, nil
|
||||
}
|
||||
|
||||
// get relative path to volumePath
|
||||
relSubPath, err := filepath.Rel(volumePath, subPath)
|
||||
if err != nil {
|
||||
return []uintptr{}, fmt.Errorf("Rel(%s, %s) error: %v", volumePath, subPath, err)
|
||||
}
|
||||
if startsWithBackstep(relSubPath) {
|
||||
return []uintptr{}, fmt.Errorf("SubPath %q not within volume path %q", subPath, volumePath)
|
||||
}
|
||||
|
||||
if relSubPath == "." {
|
||||
// volumePath and subPath are equal
|
||||
return []uintptr{}, nil
|
||||
}
|
||||
|
||||
fileHandles := []uintptr{}
|
||||
var errorResult error
|
||||
|
||||
currentFullPath := volumePath
|
||||
dirs := strings.Split(relSubPath, string(os.PathSeparator))
|
||||
for _, dir := range dirs {
|
||||
// lock intermediate subPath directory first
|
||||
currentFullPath = filepath.Join(currentFullPath, dir)
|
||||
handle, err := lockPath(currentFullPath)
|
||||
if err != nil {
|
||||
errorResult = fmt.Errorf("cannot lock path %s: %s", currentFullPath, err)
|
||||
break
|
||||
}
|
||||
fileHandles = append(fileHandles, handle)
|
||||
|
||||
// make sure intermediate subPath directory does not contain symlink any more
|
||||
stat, err := os.Lstat(currentFullPath)
|
||||
if err != nil {
|
||||
errorResult = fmt.Errorf("Lstat(%q) error: %v", currentFullPath, err)
|
||||
break
|
||||
}
|
||||
if stat.Mode()&os.ModeSymlink != 0 {
|
||||
errorResult = fmt.Errorf("subpath %q is an unexpected symlink after EvalSymlinks", currentFullPath)
|
||||
break
|
||||
}
|
||||
|
||||
if !PathWithinBase(currentFullPath, volumePath) {
|
||||
errorResult = fmt.Errorf("SubPath %q not within volume path %q", currentFullPath, volumePath)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return fileHandles, errorResult
|
||||
}
|
||||
|
||||
// unlockPath unlock directories
|
||||
func unlockPath(fileHandles []uintptr) {
|
||||
if fileHandles != nil {
|
||||
for _, handle := range fileHandles {
|
||||
syscall.CloseHandle(syscall.Handle(handle))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// lockPath locks a directory or symlink, return handle, exec "syscall.CloseHandle(handle)" to unlock the path
|
||||
func lockPath(path string) (uintptr, error) {
|
||||
if len(path) == 0 {
|
||||
return uintptr(syscall.InvalidHandle), syscall.ERROR_FILE_NOT_FOUND
|
||||
}
|
||||
pathp, err := syscall.UTF16PtrFromString(path)
|
||||
if err != nil {
|
||||
return uintptr(syscall.InvalidHandle), err
|
||||
}
|
||||
access := uint32(syscall.GENERIC_READ)
|
||||
sharemode := uint32(syscall.FILE_SHARE_READ)
|
||||
createmode := uint32(syscall.OPEN_EXISTING)
|
||||
flags := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS | syscall.FILE_FLAG_OPEN_REPARSE_POINT)
|
||||
fd, err := syscall.CreateFile(pathp, access, sharemode, nil, createmode, flags, 0)
|
||||
return uintptr(fd), err
|
||||
}
|
||||
|
||||
// Lock all directories in subPath and check they're not symlinks.
|
||||
func (mounter *Mounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) {
|
||||
handles, err := lockAndCheckSubPath(subPath.VolumePath, subPath.Path)
|
||||
|
||||
// Unlock the directories when the container starts
|
||||
cleanupAction = func() {
|
||||
unlockPath(handles)
|
||||
}
|
||||
return subPath.Path, cleanupAction, err
|
||||
}
|
||||
|
||||
// No bind-mounts for subpaths are necessary on Windows
|
||||
func (mounter *Mounter) CleanSubPaths(podDir string, volumeName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, fstype string, options []string) error {
|
||||
// Try to mount the disk
|
||||
klog.V(4).Infof("Attempting to formatAndMount disk: %s %s %s", fstype, source, target)
|
||||
|
|
@ -460,10 +386,15 @@ func getAllParentLinks(path string) ([]string, error) {
|
|||
|
||||
// GetMountRefs : empty implementation here since there is no place to query all mount points on Windows
|
||||
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
|
||||
if _, err := os.Stat(normalizeWindowsPath(pathname)); os.IsNotExist(err) {
|
||||
windowsPath := normalizeWindowsPath(pathname)
|
||||
pathExists, pathErr := PathExists(windowsPath)
|
||||
if !pathExists {
|
||||
return []string{}, nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
} 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
|
||||
}
|
||||
|
|
@ -486,126 +417,3 @@ func (mounter *Mounter) GetMode(pathname string) (os.FileMode, error) {
|
|||
}
|
||||
return info.Mode(), nil
|
||||
}
|
||||
|
||||
// SafeMakeDir makes sure that the created directory does not escape given base directory mis-using symlinks.
|
||||
func (mounter *Mounter) SafeMakeDir(subdir string, base string, perm os.FileMode) error {
|
||||
realBase, err := filepath.EvalSymlinks(base)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error resolving symlinks in %s: %s", base, err)
|
||||
}
|
||||
|
||||
realFullPath := filepath.Join(realBase, subdir)
|
||||
return doSafeMakeDir(realFullPath, realBase, perm)
|
||||
}
|
||||
|
||||
func doSafeMakeDir(pathname string, base string, perm os.FileMode) error {
|
||||
klog.V(4).Infof("Creating directory %q within base %q", pathname, base)
|
||||
|
||||
if !PathWithinBase(pathname, base) {
|
||||
return fmt.Errorf("path %s is outside of allowed base %s", pathname, base)
|
||||
}
|
||||
|
||||
// Quick check if the directory already exists
|
||||
s, err := os.Stat(pathname)
|
||||
if err == nil {
|
||||
// Path exists
|
||||
if s.IsDir() {
|
||||
// The directory already exists. It can be outside of the parent,
|
||||
// but there is no race-proof check.
|
||||
klog.V(4).Infof("Directory %s already exists", pathname)
|
||||
return nil
|
||||
}
|
||||
return &os.PathError{Op: "mkdir", Path: pathname, Err: syscall.ENOTDIR}
|
||||
}
|
||||
|
||||
// Find all existing directories
|
||||
existingPath, toCreate, err := findExistingPrefix(base, pathname)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error opening directory %s: %s", pathname, err)
|
||||
}
|
||||
if len(toCreate) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ensure the existing directory is inside allowed base
|
||||
fullExistingPath, err := filepath.EvalSymlinks(existingPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error opening existing directory %s: %s", existingPath, err)
|
||||
}
|
||||
fullBasePath, err := filepath.EvalSymlinks(base)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot read link %s: %s", base, err)
|
||||
}
|
||||
if !PathWithinBase(fullExistingPath, fullBasePath) {
|
||||
return fmt.Errorf("path %s is outside of allowed base %s", fullExistingPath, err)
|
||||
}
|
||||
|
||||
// lock all intermediate directories from fullBasePath to fullExistingPath (top to bottom)
|
||||
fileHandles, err := lockAndCheckSubPathWithoutSymlink(fullBasePath, fullExistingPath)
|
||||
defer unlockPath(fileHandles)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
klog.V(4).Infof("%q already exists, %q to create", fullExistingPath, filepath.Join(toCreate...))
|
||||
currentPath := fullExistingPath
|
||||
// create the directories one by one, making sure nobody can change
|
||||
// created directory into symlink by lock that directory immediately
|
||||
for _, dir := range toCreate {
|
||||
currentPath = filepath.Join(currentPath, dir)
|
||||
klog.V(4).Infof("Creating %s", dir)
|
||||
if err := os.Mkdir(currentPath, perm); err != nil {
|
||||
return fmt.Errorf("cannot create directory %s: %s", currentPath, err)
|
||||
}
|
||||
handle, err := lockPath(currentPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot lock path %s: %s", currentPath, err)
|
||||
}
|
||||
defer syscall.CloseHandle(syscall.Handle(handle))
|
||||
// make sure newly created directory does not contain symlink after lock
|
||||
stat, err := os.Lstat(currentPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Lstat(%q) error: %v", currentPath, err)
|
||||
}
|
||||
if stat.Mode()&os.ModeSymlink != 0 {
|
||||
return fmt.Errorf("subpath %q is an unexpected symlink after Mkdir", currentPath)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// findExistingPrefix finds prefix of pathname that exists. In addition, it
|
||||
// returns list of remaining directories that don't exist yet.
|
||||
func findExistingPrefix(base, pathname string) (string, []string, error) {
|
||||
rel, err := filepath.Rel(base, pathname)
|
||||
if err != nil {
|
||||
return base, nil, err
|
||||
}
|
||||
|
||||
if startsWithBackstep(rel) {
|
||||
return base, nil, fmt.Errorf("pathname(%s) is not within base(%s)", pathname, base)
|
||||
}
|
||||
|
||||
if rel == "." {
|
||||
// base and pathname are equal
|
||||
return pathname, []string{}, nil
|
||||
}
|
||||
|
||||
dirs := strings.Split(rel, string(filepath.Separator))
|
||||
|
||||
parent := base
|
||||
currentPath := base
|
||||
for i, dir := range dirs {
|
||||
parent = currentPath
|
||||
currentPath = filepath.Join(parent, dir)
|
||||
if _, err := os.Lstat(currentPath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return parent, dirs[i:], nil
|
||||
}
|
||||
return base, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return pathname, []string{}, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue