k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/volume/util/hostutil/hostutil_windows.go (about) 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 }