...

Source file src/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_windows.go

Documentation: k8s.io/kubernetes/pkg/volume/util/hostutil

     1  //go:build windows
     2  // +build windows
     3  
     4  /*
     5  Copyright 2017 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package hostutil
    21  
    22  import (
    23  	"fmt"
    24  	"io/fs"
    25  	"os"
    26  	"path/filepath"
    27  	"strings"
    28  	"syscall"
    29  
    30  	"golang.org/x/sys/windows"
    31  	"k8s.io/klog/v2"
    32  	"k8s.io/kubernetes/pkg/util/filesystem"
    33  	"k8s.io/mount-utils"
    34  	utilpath "k8s.io/utils/path"
    35  )
    36  
    37  // HostUtil implements HostUtils for Windows platforms.
    38  type HostUtil struct{}
    39  
    40  // NewHostUtil returns a struct that implements HostUtils on Windows platforms
    41  func NewHostUtil() *HostUtil {
    42  	return &HostUtil{}
    43  }
    44  
    45  // GetDeviceNameFromMount given a mnt point, find the device
    46  func (hu *HostUtil) GetDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) {
    47  	return getDeviceNameFromMount(mounter, mountPath, pluginMountDir)
    48  }
    49  
    50  // getDeviceNameFromMount find the device(drive) name in which
    51  // the mount path reference should match the given plugin mount directory. In case no mount path reference
    52  // matches, returns the volume name taken from its given mountPath
    53  func getDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) {
    54  	refs, err := mounter.GetMountRefs(mountPath)
    55  	if err != nil {
    56  		klog.V(4).Infof("GetMountRefs failed for mount path %q: %v", mountPath, err)
    57  		return "", err
    58  	}
    59  	if len(refs) == 0 {
    60  		return "", fmt.Errorf("directory %s is not mounted", mountPath)
    61  	}
    62  	basemountPath := mount.NormalizeWindowsPath(pluginMountDir)
    63  	for _, ref := range refs {
    64  		if strings.Contains(ref, basemountPath) {
    65  			volumeID, err := filepath.Rel(mount.NormalizeWindowsPath(basemountPath), ref)
    66  			if err != nil {
    67  				klog.Errorf("Failed to get volume id from mount %s - %v", mountPath, err)
    68  				return "", err
    69  			}
    70  			return volumeID, nil
    71  		}
    72  	}
    73  
    74  	return filepath.Base(mountPath), nil
    75  }
    76  
    77  // DeviceOpened determines if the device is in use elsewhere
    78  func (hu *HostUtil) DeviceOpened(pathname string) (bool, error) {
    79  	return false, nil
    80  }
    81  
    82  // PathIsDevice determines if a path is a device.
    83  func (hu *HostUtil) PathIsDevice(pathname string) (bool, error) {
    84  	return false, nil
    85  }
    86  
    87  // MakeRShared checks that given path is on a mount with 'rshared' mount
    88  // propagation. Empty implementation here.
    89  func (hu *HostUtil) MakeRShared(path string) error {
    90  	return nil
    91  }
    92  
    93  func isSystemCannotAccessErr(err error) bool {
    94  	if fserr, ok := err.(*fs.PathError); ok {
    95  		errno, ok := fserr.Err.(syscall.Errno)
    96  		return ok && errno == windows.ERROR_CANT_ACCESS_FILE
    97  	}
    98  
    99  	return false
   100  }
   101  
   102  // GetFileType checks for sockets/block/character devices
   103  func (hu *(HostUtil)) GetFileType(pathname string) (FileType, error) {
   104  	filetype, err := getFileType(pathname)
   105  
   106  	// os.Stat will return a 1920 error (windows.ERROR_CANT_ACCESS_FILE) if we use it on a Unix Socket
   107  	// on Windows. In this case, we need to use a different method to check if it's a Unix Socket.
   108  	if err == errUnknownFileType || isSystemCannotAccessErr(err) {
   109  		if isSocket, errSocket := filesystem.IsUnixDomainSocket(pathname); errSocket == nil && isSocket {
   110  			return FileTypeSocket, nil
   111  		}
   112  	}
   113  
   114  	return filetype, err
   115  }
   116  
   117  // PathExists checks whether the path exists
   118  func (hu *HostUtil) PathExists(pathname string) (bool, error) {
   119  	return utilpath.Exists(utilpath.CheckFollowSymlink, pathname)
   120  }
   121  
   122  // EvalHostSymlinks returns the path name after evaluating symlinks
   123  func (hu *HostUtil) EvalHostSymlinks(pathname string) (string, error) {
   124  	return filepath.EvalSymlinks(pathname)
   125  }
   126  
   127  // GetOwner returns the integer ID for the user and group of the given path
   128  // Note that on windows, it always returns 0. We actually don't set Group on
   129  // windows platform, see SetVolumeOwnership implementation.
   130  func (hu *HostUtil) GetOwner(pathname string) (int64, int64, error) {
   131  	return -1, -1, nil
   132  }
   133  
   134  // GetSELinuxSupport returns a boolean indicating support for SELinux.
   135  // Windows does not support SELinux.
   136  func (hu *HostUtil) GetSELinuxSupport(pathname string) (bool, error) {
   137  	return false, nil
   138  }
   139  
   140  // GetMode returns permissions of the path.
   141  func (hu *HostUtil) GetMode(pathname string) (os.FileMode, error) {
   142  	info, err := os.Stat(pathname)
   143  	if err != nil {
   144  		return 0, err
   145  	}
   146  	return info.Mode(), nil
   147  }
   148  
   149  // GetSELinuxMountContext returns value of -o context=XYZ mount option on
   150  // given mount point.
   151  func (hu *HostUtil) GetSELinuxMountContext(pathname string) (string, error) {
   152  	return "", nil
   153  }
   154  

View as plain text