Skip to content

Commit 692e5bd

Browse files
authored
Merge pull request #182 from pohly/publish-dir
strict staging and target directory
2 parents edc1a4f + 267dbbc commit 692e5bd

File tree

6 files changed

+63
-32
lines changed

6 files changed

+63
-32
lines changed

cmd/csi-sanity/sanity_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ func init() {
3838
flag.StringVar(&config.Address, prefix+"endpoint", "", "CSI endpoint")
3939
flag.StringVar(&config.ControllerAddress, prefix+"controllerendpoint", "", "CSI controller endpoint")
4040
flag.BoolVar(&version, prefix+"version", false, "Version of this program")
41-
flag.StringVar(&config.TargetPath, prefix+"mountdir", os.TempDir()+"/csi", "Mount point for NodePublish")
42-
flag.StringVar(&config.StagingPath, prefix+"stagingdir", os.TempDir()+"/csi", "Mount point for NodeStage if staging is supported")
41+
flag.StringVar(&config.TargetPath, prefix+"mountdir", os.TempDir()+"/csi-mount", "Mount point for NodePublish")
42+
flag.StringVar(&config.StagingPath, prefix+"stagingdir", os.TempDir()+"/csi-staging", "Mount point for NodeStage if staging is supported")
4343
flag.StringVar(&config.CreateTargetPathCmd, prefix+"createmountpathcmd", "", "Command to run for target path creation")
4444
flag.StringVar(&config.CreateStagingPathCmd, prefix+"createstagingpathcmd", "", "Command to run for staging path creation")
4545
flag.IntVar(&config.CreatePathCmdTimeout, prefix+"createpathcmdtimeout", 10, "Timeout for the commands to create target and staging paths, in seconds")

hack/_apitest/api_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import (
99

1010
func TestMyDriver(t *testing.T) {
1111
config := &sanity.Config{
12-
TargetPath: os.TempDir() + "/csi",
13-
StagingPath: os.TempDir() + "/csi",
12+
TargetPath: os.TempDir() + "/csi-target",
13+
StagingPath: os.TempDir() + "/csi-staging",
1414
Address: "/tmp/e2e-csi-sanity.sock",
1515
TestNodeVolumeAttachLimit: true,
1616
}

hack/_embedded/embedded_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ var _ = AfterSuite(func() {})
2626
var _ = Describe("MyCSIDriver", func() {
2727
Context("Config A", func() {
2828
config := &sanity.Config{
29-
TargetPath: os.TempDir() + "/csi",
30-
StagingPath: os.TempDir() + "/csi",
29+
TargetPath: os.TempDir() + "/csi-target",
30+
StagingPath: os.TempDir() + "/csi-staging",
3131
Address: "/tmp/e2e-csi-sanity.sock",
3232
TestNodeVolumeAttachLimit: true,
3333
}

mock/service/node.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func (s *service) NodePublishVolume(
136136
return nil, status.Error(codes.InvalidArgument, "Volume Capability cannot be empty")
137137
}
138138

139-
if err := checkTargetExists(req.TargetPath); err != nil {
139+
if err := checkTargetNotExists(req.TargetPath); err != nil {
140140
return nil, status.Error(codes.Internal, err.Error())
141141
}
142142

@@ -353,8 +353,24 @@ func (s *service) NodeGetVolumeStats(ctx context.Context,
353353
// does not exists.
354354
func checkTargetExists(targetPath string) error {
355355
_, err := os.Stat(targetPath)
356-
if err != nil && os.IsNotExist(err) {
356+
if err == nil {
357+
return nil
358+
}
359+
if os.IsNotExist(err) {
357360
return status.Errorf(codes.Internal, "target path %s does not exists", targetPath)
358361
}
359-
return nil
362+
return status.Errorf(codes.Internal, "stat target path %s: %s", targetPath, err)
363+
}
364+
365+
// checkTargetNotExists checks if a given path does not exist and returns error if the path
366+
// does exist.
367+
func checkTargetNotExists(targetPath string) error {
368+
_, err := os.Stat(targetPath)
369+
if err == nil {
370+
return status.Errorf(codes.Internal, "target path %s does exist", targetPath)
371+
}
372+
if os.IsNotExist(err) {
373+
return nil
374+
}
375+
return status.Errorf(codes.Internal, "stat target path %s: %s", targetPath, err)
360376
}

pkg/sanity/node.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
186186
context.Background(),
187187
&csi.NodePublishVolumeRequest{
188188
VolumeId: "id",
189-
TargetPath: sc.targetPath,
189+
TargetPath: sc.targetPath + "/target",
190190
Secrets: sc.Secrets.NodePublishVolumeSecret,
191191
},
192192
)
@@ -534,7 +534,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
534534
context.Background(),
535535
&csi.NodePublishVolumeRequest{
536536
VolumeId: vol.GetVolume().GetVolumeId(),
537-
TargetPath: sc.targetPath,
537+
TargetPath: sc.targetPath + "/target",
538538
StagingTargetPath: stagingPath,
539539
VolumeCapability: &csi.VolumeCapability{
540540
AccessType: &csi.VolumeCapability_Mount{
@@ -573,7 +573,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
573573
context.Background(),
574574
&csi.NodeUnpublishVolumeRequest{
575575
VolumeId: vol.GetVolume().GetVolumeId(),
576-
TargetPath: sc.targetPath,
576+
TargetPath: sc.targetPath + "/target",
577577
})
578578
Expect(err).NotTo(HaveOccurred())
579579
Expect(nodeunpubvol).NotTo(BeNil())
@@ -718,7 +718,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
718718
context.Background(),
719719
&csi.NodePublishVolumeRequest{
720720
VolumeId: vol.GetVolume().GetVolumeId(),
721-
TargetPath: sc.targetPath,
721+
TargetPath: sc.targetPath + "/target",
722722
StagingTargetPath: stagingPath,
723723
VolumeCapability: &csi.VolumeCapability{
724724
AccessType: &csi.VolumeCapability_Mount{
@@ -743,7 +743,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
743743
context.Background(),
744744
&csi.NodeGetVolumeStatsRequest{
745745
VolumeId: vol.GetVolume().GetVolumeId(),
746-
VolumePath: sc.targetPath,
746+
VolumePath: sc.targetPath + "/target",
747747
},
748748
)
749749
Expect(err).ToNot(HaveOccurred())
@@ -756,7 +756,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
756756
context.Background(),
757757
&csi.NodeUnpublishVolumeRequest{
758758
VolumeId: vol.GetVolume().GetVolumeId(),
759-
TargetPath: sc.targetPath,
759+
TargetPath: sc.targetPath + "/target",
760760
})
761761
Expect(err).NotTo(HaveOccurred())
762762
Expect(nodeunpubvol).NotTo(BeNil())

pkg/sanity/sanity.go

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,14 @@ type CSISecrets struct {
5353
// Config provides the configuration for the sanity tests. It
5454
// needs to be initialized by the user of the sanity package.
5555
type Config struct {
56-
TargetPath string
57-
StagingPath string
56+
// TargetPath is the *parent* directory for NodePublishVolumeRequest.target_path.
57+
// It gets created and removed by csi-sanity.
58+
TargetPath string
59+
60+
// StagingPath is the NodeStageVolumeRequest.staging_target_path.
61+
// It gets created and removed by csi-sanity.
62+
StagingPath string
63+
5864
Address string
5965
ControllerAddress string
6066
SecretsFile string
@@ -70,13 +76,30 @@ type Config struct {
7076
// directories. Returns the new paths for mount and staging.
7177
// If not defined, directories are created in the default way at TargetPath
7278
// and StagingPath on the host.
79+
//
80+
// Both functions can replace the suggested path. What the test then uses
81+
// is the path returned by them.
82+
//
83+
// Note that target and staging directory have different
84+
// semantics in the CSI spec: for NodeStateVolume,
85+
// CreateTargetDir must create the directory and return the
86+
// full path to it. For NodePublishVolume, CreateStagingDir
87+
// must create the *parent* directory of `path` (or some other
88+
// directory) and return the full path for an entry inside
89+
// that created directory.
7390
CreateTargetDir func(path string) (string, error)
7491
CreateStagingDir func(path string) (string, error)
7592

7693
// Callback functions to customize the removal of the target and staging
7794
// directories.
7895
// If not defined, directories are removed in the default way at TargetPath
7996
// and StagingPath on the host.
97+
//
98+
// Both functions are passed the actual paths as used during the test.
99+
//
100+
// Note that RemoveTargetPath only needs to remove the *parent* of the
101+
// given path. The CSI driver should have removed the entry at that path
102+
// already.
80103
RemoveTargetPath func(path string) error
81104
RemoveStagingPath func(path string) error
82105

@@ -255,20 +278,11 @@ func createMountTargetLocation(targetPath string, createPathCmd string, customCr
255278
}
256279
newTargetPath = newpath
257280
} else {
258-
// Create the target path using mkdir.
259-
fileInfo, err := os.Stat(targetPath)
260-
if err != nil {
261-
if !os.IsNotExist(err) {
262-
return "", err
263-
}
264-
if err := os.MkdirAll(targetPath, 0755); err != nil {
265-
return "", err
266-
}
267-
return targetPath, nil
268-
}
269-
270-
if !fileInfo.IsDir() {
271-
return "", fmt.Errorf("Target location %s is not a directory", targetPath)
281+
// Create the target path. Only the directory itself
282+
// and not its parents get created, and it is an error
283+
// if the directory already exists.
284+
if err := os.Mkdir(targetPath, 0755); err != nil {
285+
return "", err
272286
}
273287
newTargetPath = targetPath
274288
}
@@ -299,7 +313,8 @@ func removeMountTargetLocation(targetPath string, removePathCmd string, customRe
299313
return err
300314
}
301315
} else {
302-
return os.RemoveAll(targetPath)
316+
// It's an error if the directory is not empty by now.
317+
return os.Remove(targetPath)
303318
}
304319
return nil
305320
}

0 commit comments

Comments
 (0)