From 16813d9592868bb67d328f908539c5dabc71b713 Mon Sep 17 00:00:00 2001 From: Zhongcheng Lao Date: Sun, 1 Jun 2025 00:37:39 +0800 Subject: [PATCH] Move PathValid API to use Win32 API --- pkg/os/filesystem/api.go | 14 +------------- pkg/os/filesystem/api_test.go | 3 ++- pkg/utils/utils.go | 23 +++++++++++++++++++++++ 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/pkg/os/filesystem/api.go b/pkg/os/filesystem/api.go index f93fb2e9..a2fc4d26 100644 --- a/pkg/os/filesystem/api.go +++ b/pkg/os/filesystem/api.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "path/filepath" - "strings" "github.com/kubernetes-csi/csi-proxy/pkg/utils" ) @@ -49,17 +48,6 @@ func (filesystemAPI) PathExists(path string) (bool, error) { return pathExists(path) } -func pathValid(path string) (bool, error) { - cmd := `Test-Path $Env:remotepath` - cmdEnv := fmt.Sprintf("remotepath=%s", path) - output, err := utils.RunPowershellCmd(cmd, cmdEnv) - if err != nil { - return false, fmt.Errorf("returned output: %s, error: %v", string(output), err) - } - - return strings.HasPrefix(strings.ToLower(string(output)), "true"), nil -} - // PathValid determines whether all elements of a path exist // // https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/test-path?view=powershell-7 @@ -68,7 +56,7 @@ func pathValid(path string) (bool, error) { // // e.g. in a SMB server connection, if password is changed, connection will be lost, this func will return false func (filesystemAPI) PathValid(path string) (bool, error) { - return pathValid(path) + return utils.IsPathValid(path) } // Mkdir makes a dir with `os.MkdirAll`. diff --git a/pkg/os/filesystem/api_test.go b/pkg/os/filesystem/api_test.go index 13b81ab0..67027966 100644 --- a/pkg/os/filesystem/api_test.go +++ b/pkg/os/filesystem/api_test.go @@ -3,6 +3,7 @@ package filesystem import ( "testing" + "github.com/kubernetes-csi/csi-proxy/pkg/utils" "github.com/stretchr/testify/assert" ) @@ -25,7 +26,7 @@ func TestPathValid(t *testing.T) { } for _, test := range tests { - result, err := pathValid(test.remotepath) + result, err := utils.IsPathValid(test.remotepath) assert.Equal(t, result, test.expectedResult, "Expect result not equal with pathValid(%s) return: %q, expected: %q, error: %v", test.remotepath, result, test.expectedResult, err) if test.expectError { diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 102675ac..bfe446f7 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -1,10 +1,13 @@ package utils import ( + "fmt" "os" "os/exec" "strings" + "github.com/pkg/errors" + "golang.org/x/sys/windows" "k8s.io/klog/v2" ) @@ -29,3 +32,23 @@ func RunPowershellCmd(command string, envs ...string) ([]byte, error) { out, err := cmd.CombinedOutput() return out, err } + +func IsPathValid(path string) (bool, error) { + pathString, err := windows.UTF16PtrFromString(path) + if err != nil { + return false, fmt.Errorf("invalid path: %w", err) + } + + attrs, err := windows.GetFileAttributes(pathString) + if err != nil { + if errors.Is(err, windows.ERROR_PATH_NOT_FOUND) || errors.Is(err, windows.ERROR_FILE_NOT_FOUND) || errors.Is(err, windows.ERROR_INVALID_NAME) { + return false, nil + } + + // GetFileAttribute returns user or password incorrect for a disconnected SMB connection after the password is changed + return false, fmt.Errorf("failed to get path %s attribute: %w", path, err) + } + + klog.V(6).Infof("Path %s attribute: %d", path, attrs) + return attrs != windows.INVALID_FILE_ATTRIBUTES, nil +}