Skip to content

Commit 05c5b04

Browse files
committed
Move utility functions to utils package
1 parent 9d85ca4 commit 05c5b04

File tree

3 files changed

+72
-65
lines changed

3 files changed

+72
-65
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: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package utils
22

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

9+
"golang.org/x/sys/windows"
810
"k8s.io/klog/v2"
911
)
1012

@@ -29,3 +31,69 @@ func RunPowershellCmd(command string, envs ...string) ([]byte, error) {
2931
out, err := cmd.CombinedOutput()
3032
return out, err
3133
}
34+
35+
// IsMountedFolder checks whether the `path` is a mounted folder.
36+
func IsMountedFolder(path string) (bool, error) {
37+
// https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point
38+
utf16Path, _ := windows.UTF16PtrFromString(path)
39+
attrs, err := windows.GetFileAttributes(utf16Path)
40+
if err != nil {
41+
return false, err
42+
}
43+
44+
if (attrs & windows.FILE_ATTRIBUTE_REPARSE_POINT) == 0 {
45+
return false, nil
46+
}
47+
48+
var findData windows.Win32finddata
49+
findHandle, err := windows.FindFirstFile(utf16Path, &findData)
50+
if err != nil && !errors.Is(err, windows.ERROR_NO_MORE_FILES) {
51+
return false, err
52+
}
53+
54+
for err == nil {
55+
if findData.Reserved0&windows.IO_REPARSE_TAG_MOUNT_POINT != 0 {
56+
return true, nil
57+
}
58+
59+
err = windows.FindNextFile(findHandle, &findData)
60+
if err != nil && !errors.Is(err, windows.ERROR_NO_MORE_FILES) {
61+
return false, err
62+
}
63+
}
64+
65+
return false, nil
66+
}
67+
68+
func IsPathSymlink(path string) (bool, error) {
69+
fi, err := os.Lstat(path)
70+
if err != nil {
71+
return false, err
72+
}
73+
// for windows NTFS, check if the path is symlink instead of directory.
74+
isSymlink := fi.Mode()&os.ModeSymlink != 0 || fi.Mode()&os.ModeIrregular != 0
75+
return isSymlink, nil
76+
}
77+
78+
func CreateSymlink(link, target string, isDir bool) error {
79+
linkPtr, err := windows.UTF16PtrFromString(link)
80+
if err != nil {
81+
return err
82+
}
83+
targetPtr, err := windows.UTF16PtrFromString(target)
84+
if err != nil {
85+
return err
86+
}
87+
88+
var flags uint32
89+
if isDir {
90+
flags = windows.SYMBOLIC_LINK_FLAG_DIRECTORY
91+
}
92+
93+
err = windows.CreateSymbolicLink(
94+
linkPtr,
95+
targetPtr,
96+
flags,
97+
)
98+
return err
99+
}

0 commit comments

Comments
 (0)