Skip to content

Commit 3e149ed

Browse files
committed
IsMountPoint implementation
1 parent 1a574c1 commit 3e149ed

File tree

4 files changed

+76
-4
lines changed

4 files changed

+76
-4
lines changed

client/api/filesystem/v1alpha1/api.proto

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ service Filesystem {
1616
// LinkPath creates a local directory symbolic link between a source path
1717
// and target path in the host's filesystem
1818
rpc LinkPath(LinkPathRequest) returns (LinkPathResponse) {}
19+
20+
//IsMountPoint checks if a given path is mount or not
21+
rpc IsMountPoint(IsMountPointRequest) returns (IsMountPointResponse) {}
1922
}
2023

2124
// Context of the paths used for path prefix validation
@@ -150,3 +153,16 @@ message LinkPathResponse {
150153
// Error message if any. Empty string indicates success
151154
string error = 1;
152155
}
156+
157+
message IsMountPointRequest {
158+
// The path whose existence we want to check in the host's filesystem
159+
string path = 1;
160+
}
161+
162+
message IsMountPointResponse {
163+
// Error message if any. Empty string indicates success
164+
string error = 1;
165+
166+
// Indicates whether the path in PathExistsRequest exists in the host's filesystem
167+
bool is_mount_point = 2;
168+
}

internal/os/filesystem/api.go

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package filesystem
22

33
import (
4-
// "fmt"
4+
"fmt"
55
"os"
6-
// "os/exec"
7-
// "runtime"
86
)
97

108
// Implements the Filesystem OS API calls. All code here should be very simple
@@ -18,7 +16,7 @@ func New() APIImplementor {
1816
return APIImplementor{}
1917
}
2018

21-
func (APIImplementor) PathExists(path string) (bool, error) {
19+
func pathExists(path string) (bool, error) {
2220
_, err := os.Stat(path)
2321
if err == nil {
2422
return true, nil
@@ -29,6 +27,10 @@ func (APIImplementor) PathExists(path string) (bool, error) {
2927
return false, err
3028
}
3129

30+
func (APIImplementor) PathExists(path string) (bool, error) {
31+
return pathExists(path)
32+
}
33+
3234
func (APIImplementor) Mkdir(path string) error {
3335
return os.MkdirAll(path, 0755)
3436
}
@@ -43,3 +45,33 @@ func (APIImplementor) Rmdir(path string, force bool) error {
4345
func (APIImplementor) LinkPath(tgt string, src string) error {
4446
return os.Symlink(tgt, src)
4547
}
48+
49+
// IsMountPoint - returns true if its a mount point.
50+
// A path is considered a mount point if:
51+
// - directory exists and
52+
// - it is a soft link and
53+
// - the target path of the link exists.
54+
func (APIImplementor) IsMountPoint(tgt string) (bool, error) {
55+
// This code is similar to k8s.io/kubernetes/pkg/util/mount except the pathExists usage.
56+
// Also in a remote call environment the os error cannot be passed directly back, hence the callers
57+
// are expected to perform the isExists check before calling this call in CSI proxy.
58+
stat, err := os.Lstat(tgt)
59+
if err != nil {
60+
return false, err
61+
}
62+
63+
// If its a link and it points to an existing file then its a mount point.
64+
if stat.Mode()&os.ModeSymlink != 0 {
65+
target, err := os.Readlink(tgt)
66+
if err != nil {
67+
return false, fmt.Errorf("readlink error: %v", err)
68+
}
69+
exists, err := pathExists(target)
70+
if err != nil {
71+
return false, err
72+
}
73+
return exists, nil
74+
}
75+
76+
return false, nil
77+
}

internal/server/filesystem/internal/types.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,12 @@ type LinkPathResponse struct {
123123
// Error message if any. Empty string indicates success
124124
Error string
125125
}
126+
127+
type IsMountPointRequest struct {
128+
Path string
129+
}
130+
131+
type IsMountPointResponse struct {
132+
Error string
133+
IsMountPoint bool
134+
}

internal/server/filesystem/server.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type API interface {
2525
Mkdir(path string) error
2626
Rmdir(path string, force bool) error
2727
LinkPath(tgt string, src string) error
28+
IsMountPoint(path string) (bool, error)
2829
}
2930

3031
func NewServer(kubeletCSIPluginsPath string, kubeletPodPath string, hostAPI API) (*Server, error) {
@@ -184,3 +185,17 @@ func (s *Server) LinkPath(ctx context.Context, request *internal.LinkPathRequest
184185
Error: errString,
185186
}, nil
186187
}
188+
189+
func (s *Server) IsMountPoint(ctx context.Context, request *internal.IsMountPointRequest, version apiversion.Version) (*internal.IsMountPointResponse, error) {
190+
isMount, err := s.hostAPI.IsMountPoint(request.Path)
191+
if err != nil {
192+
return &internal.IsMountPointResponse{
193+
IsMountPoint: false,
194+
Error: err.Error(),
195+
}, nil
196+
}
197+
return &internal.IsMountPointResponse{
198+
Error: "",
199+
IsMountPoint: isMount,
200+
}, nil
201+
}

0 commit comments

Comments
 (0)