k8s.io/kubernetes@v1.29.3/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" 27 "path/filepath" 28 "strings" 29 "syscall" 30 31 "golang.org/x/sys/windows" 32 "k8s.io/klog/v2" 33 "k8s.io/kubernetes/pkg/util/filesystem" 34 "k8s.io/mount-utils" 35 utilpath "k8s.io/utils/path" 36 ) 37 38 // HostUtil implements HostUtils for Windows platforms. 39 type HostUtil struct{} 40 41 // NewHostUtil returns a struct that implements HostUtils on Windows platforms 42 func NewHostUtil() *HostUtil { 43 return &HostUtil{} 44 } 45 46 // GetDeviceNameFromMount given a mnt point, find the device 47 func (hu *HostUtil) GetDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) { 48 return getDeviceNameFromMount(mounter, mountPath, pluginMountDir) 49 } 50 51 // getDeviceNameFromMount find the device(drive) name in which 52 // the mount path reference should match the given plugin mount directory. In case no mount path reference 53 // matches, returns the volume name taken from its given mountPath 54 func getDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) { 55 refs, err := mounter.GetMountRefs(mountPath) 56 if err != nil { 57 klog.V(4).Infof("GetMountRefs failed for mount path %q: %v", mountPath, err) 58 return "", err 59 } 60 if len(refs) == 0 { 61 return "", fmt.Errorf("directory %s is not mounted", mountPath) 62 } 63 basemountPath := mount.NormalizeWindowsPath(pluginMountDir) 64 for _, ref := range refs { 65 if strings.Contains(ref, basemountPath) { 66 volumeID, err := filepath.Rel(mount.NormalizeWindowsPath(basemountPath), ref) 67 if err != nil { 68 klog.Errorf("Failed to get volume id from mount %s - %v", mountPath, err) 69 return "", err 70 } 71 return volumeID, nil 72 } 73 } 74 75 return path.Base(mountPath), nil 76 } 77 78 // DeviceOpened determines if the device is in use elsewhere 79 func (hu *HostUtil) DeviceOpened(pathname string) (bool, error) { 80 return false, nil 81 } 82 83 // PathIsDevice determines if a path is a device. 84 func (hu *HostUtil) PathIsDevice(pathname string) (bool, error) { 85 return false, nil 86 } 87 88 // MakeRShared checks that given path is on a mount with 'rshared' mount 89 // propagation. Empty implementation here. 90 func (hu *HostUtil) MakeRShared(path string) error { 91 return nil 92 } 93 94 func isSystemCannotAccessErr(err error) bool { 95 if fserr, ok := err.(*fs.PathError); ok { 96 errno, ok := fserr.Err.(syscall.Errno) 97 return ok && errno == windows.ERROR_CANT_ACCESS_FILE 98 } 99 100 return false 101 } 102 103 // GetFileType checks for sockets/block/character devices 104 func (hu *(HostUtil)) GetFileType(pathname string) (FileType, error) { 105 filetype, err := getFileType(pathname) 106 107 // os.Stat will return a 1920 error (windows.ERROR_CANT_ACCESS_FILE) if we use it on a Unix Socket 108 // on Windows. In this case, we need to use a different method to check if it's a Unix Socket. 109 if isSystemCannotAccessErr(err) { 110 if isSocket, errSocket := filesystem.IsUnixDomainSocket(pathname); errSocket == nil && isSocket { 111 return FileTypeSocket, nil 112 } 113 } 114 115 return filetype, err 116 } 117 118 // PathExists checks whether the path exists 119 func (hu *HostUtil) PathExists(pathname string) (bool, error) { 120 return utilpath.Exists(utilpath.CheckFollowSymlink, pathname) 121 } 122 123 // EvalHostSymlinks returns the path name after evaluating symlinks 124 func (hu *HostUtil) EvalHostSymlinks(pathname string) (string, error) { 125 return filepath.EvalSymlinks(pathname) 126 } 127 128 // GetOwner returns the integer ID for the user and group of the given path 129 // Note that on windows, it always returns 0. We actually don't set Group on 130 // windows platform, see SetVolumeOwnership implementation. 131 func (hu *HostUtil) GetOwner(pathname string) (int64, int64, error) { 132 return -1, -1, nil 133 } 134 135 // GetSELinuxSupport returns a boolean indicating support for SELinux. 136 // Windows does not support SELinux. 137 func (hu *HostUtil) GetSELinuxSupport(pathname string) (bool, error) { 138 return false, nil 139 } 140 141 // GetMode returns permissions of the path. 142 func (hu *HostUtil) GetMode(pathname string) (os.FileMode, error) { 143 info, err := os.Stat(pathname) 144 if err != nil { 145 return 0, err 146 } 147 return info.Mode(), nil 148 } 149 150 // GetSELinuxMountContext returns value of -o context=XYZ mount option on 151 // given mount point. 152 func (hu *HostUtil) GetSELinuxMountContext(pathname string) (string, error) { 153 return "", nil 154 }