Skip to content

Commit 5799c68

Browse files
authored
Merge pull request #66 from andyzhangx/smb-remount
fix: SMB remount issue
2 parents 6841c76 + f817ce8 commit 5799c68

File tree

6 files changed

+89
-0
lines changed

6 files changed

+89
-0
lines changed

internal/os/filesystem/api.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package filesystem
33
import (
44
"fmt"
55
"os"
6+
"os/exec"
7+
"strings"
68
)
79

810
// Implements the Filesystem OS API calls. All code here should be very simple
@@ -31,6 +33,25 @@ func (APIImplementor) PathExists(path string) (bool, error) {
3133
return pathExists(path)
3234
}
3335

36+
func pathValid(path string) (bool, error) {
37+
cmd := exec.Command("powershell", "/c", `Test-Path $Env:remoteapth`)
38+
cmd.Env = append(os.Environ(), fmt.Sprintf("remoteapth=%s", path))
39+
output, err := cmd.CombinedOutput()
40+
if err != nil {
41+
return false, fmt.Errorf("returned output: %s, error: %v", string(output), err)
42+
}
43+
44+
return strings.HasPrefix(strings.ToLower(string(output)), "true"), nil
45+
}
46+
47+
// PathValid determines whether all elements of a path exist
48+
// https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/test-path?view=powershell-7
49+
// for a remote path, determines whether connection is ok
50+
// e.g. in a SMB server connection, if password is changed, connection will be lost, this func will return false
51+
func (APIImplementor) PathValid(path string) (bool, error) {
52+
return pathValid(path)
53+
}
54+
3455
func (APIImplementor) Mkdir(path string) error {
3556
return os.MkdirAll(path, 0755)
3657
}

internal/os/filesystem/api_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// +build windows
2+
3+
package filesystem
4+
5+
import (
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestPathValid(t *testing.T) {
12+
tests := []struct {
13+
remotepath string
14+
expectedResult bool
15+
expectError bool
16+
}{
17+
{
18+
"c:",
19+
true,
20+
false,
21+
},
22+
{
23+
"invalid-path",
24+
false,
25+
false,
26+
},
27+
}
28+
29+
for _, test := range tests {
30+
result, err := pathValid(test.remotepath)
31+
assert.Equal(t, result, test.expectedResult, "Expect result not equal with pathValid(%s) return: %q, expected: %q, error: %v",
32+
test.remotepath, result, test.expectedResult, err)
33+
if test.expectError {
34+
assert.NotNil(t, err, "Expect error during pathValid(%s)", test.remotepath)
35+
} else {
36+
assert.Nil(t, err, "Expect error is nil during pathValid(%s)", test.remotepath)
37+
}
38+
}
39+
}

internal/server/filesystem/server.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ var absPathRegexWindows = regexp.MustCompile(`^[a-zA-Z]:\\`)
2323

2424
type API interface {
2525
PathExists(path string) (bool, error)
26+
PathValid(path string) (bool, error)
2627
Mkdir(path string) error
2728
Rmdir(path string, force bool) error
2829
LinkPath(tgt string, src string) error
@@ -139,6 +140,12 @@ func (s *Server) PathExists(ctx context.Context, request *internal.PathExistsReq
139140
}, err
140141
}
141142

143+
// PathValid checks if the given path is accessiable.
144+
func (s *Server) PathValid(ctx context.Context, path string) (bool, error) {
145+
klog.V(4).Infof("calling PathValid with path %q", path)
146+
return s.hostAPI.PathValid(path)
147+
}
148+
142149
func (s *Server) Mkdir(ctx context.Context, request *internal.MkdirRequest, version apiversion.Version) (*internal.MkdirResponse, error) {
143150
klog.V(4).Infof("calling Mkdir with path %q", request.Path)
144151
err := s.validatePathWindows(request.Context, request.Path)

internal/server/filesystem/server_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ type fakeFileSystemAPI struct{}
1313
func (fakeFileSystemAPI) PathExists(path string) (bool, error) {
1414
return true, nil
1515
}
16+
func (fakeFileSystemAPI) PathValid(path string) (bool, error) {
17+
return true, nil
18+
}
1619
func (fakeFileSystemAPI) Mkdir(path string) error {
1720
return nil
1821
}

internal/server/smb/server.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,22 @@ func (s *Server) NewSmbGlobalMapping(context context.Context, request *internal.
4545
isMapped = false
4646
}
4747

48+
valid, err := s.fsServer.PathValid(context, remotePath)
49+
if err != nil {
50+
klog.Errorf("PathValid(%s) failed with %v", remotePath, err)
51+
return response, fmt.Errorf("PathValid(%s) failed with %v", remotePath, err)
52+
}
53+
54+
if isMapped && !valid {
55+
klog.V(4).Infof("Remote %s is not valid, removing now", remotePath)
56+
err := s.hostAPI.RemoveSmbGlobalMapping(remotePath)
57+
if err != nil {
58+
klog.Errorf("RemoveSmbGlobalMapping(%s) failed with %v", remotePath, err)
59+
return response, err
60+
}
61+
isMapped = false
62+
}
63+
4864
if !isMapped {
4965
klog.V(4).Infof("Remote %s not mapped. Mapping now!", remotePath)
5066
err := s.hostAPI.NewSmbGlobalMapping(remotePath, request.Username, request.Password)

internal/server/smb/server_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ type fakeFileSystemAPI struct{}
3232
func (fakeFileSystemAPI) PathExists(path string) (bool, error) {
3333
return true, nil
3434
}
35+
func (fakeFileSystemAPI) PathValid(path string) (bool, error) {
36+
return true, nil
37+
}
3538
func (fakeFileSystemAPI) Mkdir(path string) error {
3639
return nil
3740
}

0 commit comments

Comments
 (0)