Skip to content

Commit 3b82d1c

Browse files
committed
Move utility functions to utils package
1 parent 92cafa9 commit 3b82d1c

File tree

3 files changed

+71
-66
lines changed

3 files changed

+71
-66
lines changed

pkg/os/smb/api.go

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@ package smb
33
import (
44
"fmt"
55
"strings"
6-
"syscall"
76

87
"github.com/kubernetes-csi/csi-proxy/pkg/cim"
98
"github.com/kubernetes-csi/csi-proxy/pkg/utils"
10-
"golang.org/x/sys/windows"
119
)
1210

1311
type API interface {
@@ -29,29 +27,6 @@ func New(requirePrivacy bool) *SmbAPI {
2927
}
3028
}
3129

32-
func createSymlink(link, target string, isDir bool) error {
33-
linkPtr, err := syscall.UTF16PtrFromString(link)
34-
if err != nil {
35-
return err
36-
}
37-
targetPtr, err := syscall.UTF16PtrFromString(target)
38-
if err != nil {
39-
return err
40-
}
41-
42-
var flags uint32
43-
if isDir {
44-
flags = windows.SYMBOLIC_LINK_FLAG_DIRECTORY
45-
}
46-
47-
err = windows.CreateSymbolicLink(
48-
linkPtr,
49-
targetPtr,
50-
flags,
51-
)
52-
return err
53-
}
54-
5530
func (*SmbAPI) IsSmbMapped(remotePath string) (bool, error) {
5631
inst, err := cim.QuerySmbGlobalMappingByRemotePath(remotePath)
5732
if err != nil {
@@ -78,7 +53,7 @@ func (*SmbAPI) NewSmbLink(remotePath, localPath string) error {
7853
longRemotePath := utils.EnsureLongPath(remotePath)
7954
longLocalPath := utils.EnsureLongPath(localPath)
8055

81-
err := createSymlink(longLocalPath, longRemotePath, true)
56+
err := utils.CreateSymlink(longLocalPath, longRemotePath, true)
8257
if err != nil {
8358
return fmt.Errorf("error linking %s to %s. err: %v", remotePath, localPath, err)
8459
}

pkg/os/volume/api.go

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package volume
22

33
import (
44
"fmt"
5-
"os"
65
"path/filepath"
76
"regexp"
87
"strings"
@@ -291,7 +290,7 @@ func (VolumeAPI) GetVolumeIDFromTargetPath(mount string) (string, error) {
291290
}
292291

293292
func getTarget(mount string) (string, error) {
294-
mountedFolder, err := isMountedFolder(mount)
293+
mountedFolder, err := utils.IsMountedFolder(mount)
295294
if err != nil {
296295
return "", err
297296
}
@@ -347,15 +346,13 @@ func findClosestVolume(path string) (string, error) {
347346
// The number of iterations is 256, which is similar to the number of iterations in filepath-securejoin
348347
// https://github.com/cyphar/filepath-securejoin/blob/64536a8a66ae59588c981e2199f1dcf410508e07/join.go#L51
349348
for i := 0; i < 256; i += 1 {
350-
fi, err := os.Lstat(candidatePath)
349+
isSymlink, err := utils.IsPathSymlink(candidatePath)
351350
if err != nil {
352351
return "", err
353352
}
354-
// for windows NTFS, check if the path is symlink instead of directory.
355-
isSymlink := fi.Mode()&os.ModeSymlink != 0 || fi.Mode()&os.ModeIrregular != 0
356353

357354
// mounted folder created by SetVolumeMountPoint may still report ModeSymlink == 0
358-
mountedFolder, err := isMountedFolder(candidatePath)
355+
mountedFolder, err := utils.IsMountedFolder(candidatePath)
359356
if err != nil {
360357
return "", err
361358
}
@@ -392,39 +389,6 @@ func findClosestVolume(path string) (string, error) {
392389
return "", fmt.Errorf("failed to find the closest volume for path=%s", path)
393390
}
394391

395-
// isMountedFolder checks whether the `path` is a mounted folder.
396-
func isMountedFolder(path string) (bool, error) {
397-
// https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point
398-
utf16Path, _ := windows.UTF16PtrFromString(path)
399-
attrs, err := windows.GetFileAttributes(utf16Path)
400-
if err != nil {
401-
return false, err
402-
}
403-
404-
if (attrs & windows.FILE_ATTRIBUTE_REPARSE_POINT) == 0 {
405-
return false, nil
406-
}
407-
408-
var findData windows.Win32finddata
409-
findHandle, err := windows.FindFirstFile(utf16Path, &findData)
410-
if err != nil && !errors.Is(err, windows.ERROR_NO_MORE_FILES) {
411-
return false, err
412-
}
413-
414-
for err == nil {
415-
if findData.Reserved0&windows.IO_REPARSE_TAG_MOUNT_POINT != 0 {
416-
return true, nil
417-
}
418-
419-
err = windows.FindNextFile(findHandle, &findData)
420-
if err != nil && !errors.Is(err, windows.ERROR_NO_MORE_FILES) {
421-
return false, err
422-
}
423-
}
424-
425-
return false, nil
426-
}
427-
428392
// getVolumeForDriveLetter gets a volume from a drive letter (e.g. C:/).
429393
func getVolumeForDriveLetter(path string) (string, error) {
430394
if len(path) != 1 {

pkg/utils/utils.go

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package utils
22

33
import (
4+
"errors"
45
"fmt"
56
"os"
67
"os/exec"
78
"strings"
89

9-
"github.com/pkg/errors"
1010
"golang.org/x/sys/windows"
1111
"k8s.io/klog/v2"
1212
)
@@ -52,3 +52,69 @@ func IsPathValid(path string) (bool, error) {
5252
klog.V(6).Infof("Path %s attribute: %d", path, attrs)
5353
return attrs != windows.INVALID_FILE_ATTRIBUTES, nil
5454
}
55+
56+
// IsMountedFolder checks whether the `path` is a mounted folder.
57+
func IsMountedFolder(path string) (bool, error) {
58+
// https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point
59+
utf16Path, _ := windows.UTF16PtrFromString(path)
60+
attrs, err := windows.GetFileAttributes(utf16Path)
61+
if err != nil {
62+
return false, err
63+
}
64+
65+
if (attrs & windows.FILE_ATTRIBUTE_REPARSE_POINT) == 0 {
66+
return false, nil
67+
}
68+
69+
var findData windows.Win32finddata
70+
findHandle, err := windows.FindFirstFile(utf16Path, &findData)
71+
if err != nil && !errors.Is(err, windows.ERROR_NO_MORE_FILES) {
72+
return false, err
73+
}
74+
75+
for err == nil {
76+
if findData.Reserved0&windows.IO_REPARSE_TAG_MOUNT_POINT != 0 {
77+
return true, nil
78+
}
79+
80+
err = windows.FindNextFile(findHandle, &findData)
81+
if err != nil && !errors.Is(err, windows.ERROR_NO_MORE_FILES) {
82+
return false, err
83+
}
84+
}
85+
86+
return false, nil
87+
}
88+
89+
func IsPathSymlink(path string) (bool, error) {
90+
fi, err := os.Lstat(path)
91+
if err != nil {
92+
return false, err
93+
}
94+
// for windows NTFS, check if the path is symlink instead of directory.
95+
isSymlink := fi.Mode()&os.ModeSymlink != 0 || fi.Mode()&os.ModeIrregular != 0
96+
return isSymlink, nil
97+
}
98+
99+
func CreateSymlink(link, target string, isDir bool) error {
100+
linkPtr, err := windows.UTF16PtrFromString(link)
101+
if err != nil {
102+
return err
103+
}
104+
targetPtr, err := windows.UTF16PtrFromString(target)
105+
if err != nil {
106+
return err
107+
}
108+
109+
var flags uint32
110+
if isDir {
111+
flags = windows.SYMBOLIC_LINK_FLAG_DIRECTORY
112+
}
113+
114+
err = windows.CreateSymbolicLink(
115+
linkPtr,
116+
targetPtr,
117+
flags,
118+
)
119+
return err
120+
}

0 commit comments

Comments
 (0)