Skip to content

Commit 245c9c9

Browse files
authored
Merge pull request #383 from aramase/create-target-path
feat: create target path in node publish
2 parents 97cc603 + 266f5bd commit 245c9c9

File tree

8 files changed

+108
-80
lines changed

8 files changed

+108
-80
lines changed

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@ go 1.15
44

55
require (
66
github.com/blang/semver v3.5.0+incompatible
7-
github.com/container-storage-interface/spec v1.0.0
7+
github.com/container-storage-interface/spec v1.3.0
88
github.com/go-logr/logr v0.2.1 // indirect
99
github.com/golang/protobuf v1.4.3
1010
github.com/google/go-cmp v0.5.2
11-
github.com/kubernetes-csi/csi-lib-utils v0.6.1
12-
github.com/kubernetes-csi/csi-test v1.1.0
11+
github.com/kubernetes-csi/csi-lib-utils v0.7.1
12+
github.com/kubernetes-csi/csi-test/v4 v4.0.2
1313
github.com/onsi/gomega v1.10.1
1414
github.com/prometheus/client_golang v1.8.0 // indirect
1515
github.com/stretchr/testify v1.6.1
1616
go.opentelemetry.io/otel v0.13.0
1717
go.opentelemetry.io/otel/exporters/metric/prometheus v0.13.0
1818
golang.org/x/net v0.0.0-20200707034311-ab3426394381
1919
golang.org/x/sys v0.0.0-20201107080550-4d91cf3a1aaf // indirect
20-
google.golang.org/grpc v1.27.1
20+
google.golang.org/grpc v1.29.1
2121
google.golang.org/protobuf v1.25.0
2222
k8s.io/api v0.19.3
2323
k8s.io/apimachinery v0.19.3

go.sum

Lines changed: 43 additions & 8 deletions
Large diffs are not rendered by default.

pkg/csi-common/controllerserver-default.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,11 @@ func (cs *DefaultControllerServer) DeleteSnapshot(ctx context.Context, req *csi.
7474
func (cs *DefaultControllerServer) ListSnapshots(ctx context.Context, req *csi.ListSnapshotsRequest) (*csi.ListSnapshotsResponse, error) {
7575
return nil, status.Error(codes.Unimplemented, "")
7676
}
77+
78+
func (cs *DefaultControllerServer) ControllerExpandVolume(ctx context.Context, req *csi.ControllerExpandVolumeRequest) (*csi.ControllerExpandVolumeResponse, error) {
79+
return &csi.ControllerExpandVolumeResponse{}, status.Error(codes.Unimplemented, "ControllerExpandVolume is not implemented")
80+
}
81+
82+
func (cs *DefaultControllerServer) ControllerGetVolume(ctx context.Context, req *csi.ControllerGetVolumeRequest) (*csi.ControllerGetVolumeResponse, error) {
83+
return &csi.ControllerGetVolumeResponse{}, status.Error(codes.Unimplemented, "ControllerGetVolume is not implemented")
84+
}

pkg/csi-common/utils.go

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -71,30 +71,6 @@ func NewControllerServiceCapability(cap csi.ControllerServiceCapability_RPC_Type
7171
}
7272
}
7373

74-
func RunNodePublishServer(endpoint string, d *CSIDriver, ns csi.NodeServer) {
75-
ids := NewDefaultIdentityServer(d)
76-
77-
s := NewNonBlockingGRPCServer()
78-
s.Start(context.Background(), endpoint, ids, nil, ns)
79-
s.Wait()
80-
}
81-
82-
func RunControllerPublishServer(endpoint string, d *CSIDriver, cs csi.ControllerServer) {
83-
ids := NewDefaultIdentityServer(d)
84-
85-
s := NewNonBlockingGRPCServer()
86-
s.Start(context.Background(), endpoint, ids, cs, nil)
87-
s.Wait()
88-
}
89-
90-
func RunControllerandNodePublishServer(endpoint string, d *CSIDriver, cs csi.ControllerServer, ns csi.NodeServer) {
91-
ids := NewDefaultIdentityServer(d)
92-
93-
s := NewNonBlockingGRPCServer()
94-
s.Start(context.Background(), endpoint, ids, cs, ns)
95-
s.Wait()
96-
}
97-
9874
func logGRPC(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
9975
klog.V(3).Infof("GRPC call: %s", info.FullMethod)
10076
klog.V(3).Infof("GRPC request: %s", pbSanitizer.StripSecrets(req).String())

pkg/secrets-store/nodeserver.go

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,18 @@ import (
2525
"os/exec"
2626
"runtime"
2727

28-
"github.com/container-storage-interface/spec/lib/go/csi"
29-
30-
"sigs.k8s.io/controller-runtime/pkg/client"
31-
3228
csicommon "sigs.k8s.io/secrets-store-csi-driver/pkg/csi-common"
3329
internalerrors "sigs.k8s.io/secrets-store-csi-driver/pkg/errors"
3430
"sigs.k8s.io/secrets-store-csi-driver/pkg/util/fileutil"
3531
"sigs.k8s.io/secrets-store-csi-driver/pkg/version"
3632

33+
"github.com/container-storage-interface/spec/lib/go/csi"
3734
"golang.org/x/net/context"
3835
"google.golang.org/grpc/codes"
3936
"google.golang.org/grpc/status"
40-
41-
"k8s.io/utils/mount"
42-
4337
"k8s.io/klog/v2"
38+
"k8s.io/utils/mount"
39+
"sigs.k8s.io/controller-runtime/pkg/client"
4440
)
4541

4642
type nodeServer struct {
@@ -115,15 +111,23 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
115111

116112
mounted, err = ns.ensureMountPoint(targetPath)
117113
if err != nil {
118-
errorReason = internalerrors.FailedToEnsureMountPoint
119-
return nil, status.Errorf(codes.Internal, "Could not mount target %q: %v", targetPath, err)
114+
// kubelet will not create the CSI NodePublishVolume target directory in 1.20+, in accordance with the CSI specification.
115+
// CSI driver needs to properly create and process the target path
116+
if os.IsNotExist(err) {
117+
if err = os.MkdirAll(targetPath, 0750); err != nil {
118+
return nil, status.Errorf(codes.Internal, "failed to create target path %s, err: %v", targetPath, err)
119+
}
120+
} else {
121+
errorReason = internalerrors.FailedToEnsureMountPoint
122+
return nil, status.Errorf(codes.Internal, "failed to check if target path %s is mount point, err: %v", targetPath, err)
123+
}
120124
}
121125
if mounted {
122126
klog.InfoS("target path is already mounted", "targetPath", targetPath, "pod", klog.ObjectRef{Namespace: podNamespace, Name: podName})
123127
return &csi.NodePublishVolumeResponse{}, nil
124128
}
125129

126-
klog.V(2).InfoS("node publish volume", "target", targetPath, "volumeId", volumeID, "attributes", attrib, "mountflags", mountFlags)
130+
klog.V(2).InfoS("node publish volume", "target", targetPath, "volumeId", volumeID, "attributes", attrib, "mount flags", mountFlags)
127131

128132
if isMockProvider(providerName) {
129133
// mock provider is used only for running sanity tests against the driver
@@ -206,8 +210,6 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
206210
}
207211

208212
func (ns *nodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpublishVolumeRequest) (nuvr *csi.NodeUnpublishVolumeResponse, err error) {
209-
var podUID string
210-
211213
defer func() {
212214
if err != nil {
213215
ns.reporter.ReportNodeUnPublishErrorCtMetric()
@@ -231,27 +233,23 @@ func (ns *nodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpu
231233
return &csi.NodeUnpublishVolumeResponse{}, nil
232234
}
233235

234-
podUID = fileutil.GetPodUIDFromTargetPath(targetPath)
235-
if len(podUID) == 0 {
236-
return nil, status.Error(codes.InvalidArgument, "Cannot get podUID from Target path")
237-
}
238236
// remove files
239237
if runtime.GOOS == "windows" {
240238
for _, file := range files {
241239
err = os.RemoveAll(file)
242240
if err != nil {
243-
klog.ErrorS(err, "failed to remove file from target path", "file", file, "podUID", podUID)
241+
klog.ErrorS(err, "failed to remove file from target path", "file", file)
244242
return nil, status.Error(codes.Internal, err.Error())
245243
}
246244
}
247245
}
248246
err = mount.CleanupMountPoint(targetPath, ns.mounter, false)
249-
if err != nil {
250-
klog.ErrorS(err, "failed to clean and unmount target path", "targetPath", targetPath, "podUID", podUID)
247+
if err != nil && !os.IsNotExist(err) {
248+
klog.ErrorS(err, "failed to clean and unmount target path", "targetPath", targetPath)
251249
return nil, status.Error(codes.Internal, err.Error())
252250
}
253251

254-
klog.InfoS("node unpublish volume complete", "targetPath", targetPath, "podUID", podUID)
252+
klog.InfoS("node unpublish volume complete", "targetPath", targetPath)
255253
return &csi.NodeUnpublishVolumeResponse{}, nil
256254
}
257255

@@ -357,3 +355,7 @@ func (ns *nodeServer) mountSecretsStoreObjectContent(ctx context.Context, provid
357355
}
358356
return nil, "", nil
359357
}
358+
359+
func (ns *nodeServer) NodeExpandVolume(ctx context.Context, req *csi.NodeExpandVolumeRequest) (*csi.NodeExpandVolumeResponse, error) {
360+
return nil, status.Error(codes.Unimplemented, "NodeExpandVolume is not implemented")
361+
}

pkg/secrets-store/nodeserver_test.go

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,21 @@ import (
2323
"path/filepath"
2424
"testing"
2525

26+
"sigs.k8s.io/secrets-store-csi-driver/apis/v1alpha1"
2627
internalerrors "sigs.k8s.io/secrets-store-csi-driver/pkg/errors"
27-
28-
"k8s.io/apimachinery/pkg/runtime/schema"
28+
"sigs.k8s.io/secrets-store-csi-driver/pkg/secrets-store/mocks"
2929

3030
"github.com/container-storage-interface/spec/lib/go/csi"
3131
"golang.org/x/net/context"
3232
"google.golang.org/grpc/codes"
3333
"google.golang.org/grpc/status"
3434
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3535
"k8s.io/apimachinery/pkg/runtime"
36+
"k8s.io/apimachinery/pkg/runtime/schema"
3637
"k8s.io/client-go/kubernetes/scheme"
3738
"k8s.io/utils/mount"
3839
"sigs.k8s.io/controller-runtime/pkg/client"
3940
"sigs.k8s.io/controller-runtime/pkg/client/fake"
40-
"sigs.k8s.io/secrets-store-csi-driver/apis/v1alpha1"
41-
"sigs.k8s.io/secrets-store-csi-driver/pkg/secrets-store/mocks"
4241
)
4342

4443
func testNodeServer(mountPoints []mount.MountPoint, client client.Client, grpcSupportProviders string, reporter StatsReporter, providerBinaryName string) (*nodeServer, error) {
@@ -462,17 +461,6 @@ func TestNodeUnpublishVolume(t *testing.T) {
462461
RPCCode: codes.InvalidArgument,
463462
shouldRetryUnmount: true,
464463
},
465-
{
466-
name: "Failure: target path does not contain valid podUID",
467-
nodeUnpublishVolReq: csi.NodeUnpublishVolumeRequest{
468-
VolumeId: "testvolid1",
469-
TargetPath: getTestTargetPath("", t),
470-
},
471-
wantsErr: true,
472-
wantsRPCCode: true,
473-
RPCCode: codes.InvalidArgument,
474-
shouldRetryUnmount: true,
475-
},
476464
{
477465
name: "Success for a mounted volume with a retry",
478466
nodeUnpublishVolReq: csi.NodeUnpublishVolumeRequest{

pkg/secrets-store/utils.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package secretsstore
1919
import (
2020
"fmt"
2121
"io/ioutil"
22-
"os"
2322
"runtime"
2423
"strings"
2524

@@ -53,7 +52,7 @@ func normalizeWindowsPath(path string) string {
5352
// ensureMountPoint ensures mount point is valid
5453
func (ns *nodeServer) ensureMountPoint(target string) (bool, error) {
5554
notMnt, err := ns.mounter.IsLikelyNotMountPoint(target)
56-
if err != nil && !os.IsNotExist(err) {
55+
if err != nil {
5756
return !notMnt, err
5857
}
5958

test/sanity/sanity_test.go

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,17 @@ package sanity
1515

1616
import (
1717
"context"
18+
"fmt"
19+
"os"
20+
"path/filepath"
1821
"testing"
1922

20-
"github.com/kubernetes-csi/csi-test/pkg/sanity"
23+
"github.com/kubernetes-csi/csi-test/v4/pkg/sanity"
2124

2225
secretsstore "sigs.k8s.io/secrets-store-csi-driver/pkg/secrets-store"
2326
)
2427

2528
const (
26-
mountPath = "/tmp/csi/mount"
27-
stagePath = "/tmp/csi/stage"
2829
socket = "/tmp/csi.sock"
2930
endpoint = "unix://" + socket
3031
providerVolumePath = "/etc/kubernetes/secrets-store-csi-providers"
@@ -36,10 +37,29 @@ func TestSanity(t *testing.T) {
3637
driver.Run(context.Background(), "secrets-store.csi.k8s.io", "somenodeid", endpoint, providerVolumePath, "provider1=0.0.2,provider2=0.0.4", "", nil)
3738
}()
3839

39-
config := &sanity.Config{
40-
TargetPath: mountPath,
41-
StagingPath: stagePath,
42-
Address: endpoint,
40+
tmpPath := filepath.Join(os.TempDir(), "csi")
41+
config := sanity.NewTestConfig()
42+
config.Address = endpoint
43+
config.CreateTargetDir = func(targetPath string) (string, error) {
44+
targetPath = filepath.Join(tmpPath, targetPath)
45+
return targetPath, createTargetDir(targetPath)
46+
}
47+
config.RemoveTargetPath = func(targetPath string) error {
48+
return os.RemoveAll(targetPath)
4349
}
4450
sanity.Test(t, config)
4551
}
52+
53+
func createTargetDir(targetPath string) error {
54+
fileInfo, err := os.Stat(targetPath)
55+
if err != nil && os.IsNotExist(err) {
56+
return os.MkdirAll(targetPath, 0755)
57+
} else if err != nil {
58+
return err
59+
}
60+
if !fileInfo.IsDir() {
61+
return fmt.Errorf("target location %s is not a directory", targetPath)
62+
}
63+
64+
return nil
65+
}

0 commit comments

Comments
 (0)