Skip to content

Commit

Permalink
Merge pull request #159 from darkowlzz/flexible-target-dirs
Browse files Browse the repository at this point in the history
Make mount and staging dir creation flexible
  • Loading branch information
k8s-ci-robot authored Mar 20, 2019
2 parents 82d19e4 + 506d128 commit ca4c526
Show file tree
Hide file tree
Showing 6 changed files with 311 additions and 33 deletions.
6 changes: 6 additions & 0 deletions cmd/csi-sanity/sanity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ func init() {
flag.BoolVar(&version, prefix+"version", false, "Version of this program")
flag.StringVar(&config.TargetPath, prefix+"mountdir", os.TempDir()+"/csi", "Mount point for NodePublish")
flag.StringVar(&config.StagingPath, prefix+"stagingdir", os.TempDir()+"/csi", "Mount point for NodeStage if staging is supported")
flag.StringVar(&config.CreateTargetPathCmd, prefix+"createmountpathcmd", "", "Command to run for target path creation")
flag.StringVar(&config.CreateStagingPathCmd, prefix+"createstagingpathcmd", "", "Command to run for staging path creation")
flag.IntVar(&config.CreatePathCmdTimeout, prefix+"createpathcmdtimeout", 10, "Timeout for the commands to create target and staging paths, in seconds")
flag.StringVar(&config.RemoveTargetPathCmd, prefix+"removemountpathcmd", "", "Command to run for target path removal")
flag.StringVar(&config.RemoveStagingPathCmd, prefix+"removestagingpathcmd", "", "Command to run for staging path removal")
flag.IntVar(&config.RemovePathCmdTimeout, prefix+"removepathcmdtimeout", 10, "Timeout for the commands to remove target and staging paths, in seconds")
flag.StringVar(&config.SecretsFile, prefix+"secrets", "", "CSI secrets file")
flag.Int64Var(&config.TestVolumeSize, prefix+"testvolumesize", sanity.DefTestVolumeSize, "Base volume size used for provisioned volumes")
flag.StringVar(&config.TestVolumeParametersFile, prefix+"testvolumeparameters", "", "YAML file of volume parameters for provisioned volumes")
Expand Down
82 changes: 82 additions & 0 deletions hack/_apitest2/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package apitest2

import (
"fmt"
"os"
"path"
"testing"

"github.com/kubernetes-csi/csi-test/pkg/sanity"
)

// TestMyDriverWithCustomTargetPaths verifies that CreateTargetDir and
// CreateStagingDir are called a specific number of times.
func TestMyDriverWithCustomTargetPaths(t *testing.T) {
var createTargetDirCalls, createStagingDirCalls,
removeTargetDirCalls, removeStagingDirCalls int

wantCreateTargetCalls := 3
wantCreateStagingCalls := 3
wantRemoveTargetCalls := 3
wantRemoveStagingCalls := 3

// tmpPath could be a CO specific directory under which all the target dirs
// are created. For k8s, it could be /var/lib/kubelet/pods under which the
// mount directories could be created.
tmpPath := path.Join(os.TempDir(), "csi")
config := &sanity.Config{
TargetPath: "foo/target/mount",
StagingPath: "foo/staging/mount",
Address: "/tmp/e2e-csi-sanity.sock",
CreateTargetDir: func(targetPath string) (string, error) {
createTargetDirCalls++
targetPath = path.Join(tmpPath, targetPath)
return targetPath, createTargetDir(targetPath)
},
CreateStagingDir: func(targetPath string) (string, error) {
createStagingDirCalls++
targetPath = path.Join(tmpPath, targetPath)
return targetPath, createTargetDir(targetPath)
},
RemoveTargetPath: func(targetPath string) error {
removeTargetDirCalls++
return os.RemoveAll(targetPath)
},
RemoveStagingPath: func(targetPath string) error {
removeStagingDirCalls++
return os.RemoveAll(targetPath)
},
}

sanity.Test(t, config)

if createTargetDirCalls != wantCreateTargetCalls {
t.Errorf("unexpected number of CreateTargetDir calls:\n(WNT) %d\n(GOT) %d", wantCreateTargetCalls, createTargetDirCalls)
}

if createStagingDirCalls != wantCreateStagingCalls {
t.Errorf("unexpected number of CreateStagingDir calls:\n(WNT) %d\n(GOT) %d", wantCreateStagingCalls, createStagingDirCalls)
}

if removeTargetDirCalls != wantRemoveTargetCalls {
t.Errorf("unexpected number of RemoveTargetDir calls:\n(WNT) %d\n(GOT) %d", wantRemoveTargetCalls, removeTargetDirCalls)
}

if removeStagingDirCalls != wantRemoveStagingCalls {
t.Errorf("unexpected number of RemoveStagingDir calls:\n(WNT) %d\n(GOT) %d", wantRemoveStagingCalls, removeStagingDirCalls)
}
}

func createTargetDir(targetPath string) error {
fileInfo, err := os.Stat(targetPath)
if err != nil && os.IsNotExist(err) {
return os.MkdirAll(targetPath, 0755)
} else if err != nil {
return err
}
if !fileInfo.IsDir() {
return fmt.Errorf("Target location %s is not a directory", targetPath)
}

return nil
}
59 changes: 59 additions & 0 deletions hack/e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,59 @@ runTestAPI()
fi
}

runTestAPIWithCustomTargetPaths()
{
CSI_ENDPOINT=$1 ./bin/mock-driver &
local pid=$!

# Running a specific test to verify that the custom target paths are called
# a deterministic number of times.
GOCACHE=off go test -v ./hack/_apitest2/api_test.go -ginkgo.focus="NodePublishVolume"; ret=$?

if [ $ret -ne 0 ] ; then
exit $ret
fi
}

runTestWithCustomTargetPaths()
{
CSI_ENDPOINT=$1 ./bin/mock-driver &
local pid=$!

# Create a script for custom target path creation.
echo '#!/bin/bash
targetpath="/tmp/csi/$@"
mkdir -p $targetpath
echo $targetpath
' > custompathcreation.bash

# Create a script for custom target path removal.
echo '#!/bin/bash
rm -rf $@
' > custompathremoval.bash

chmod +x custompathcreation.bash custompathremoval.bash
local creationscriptpath="$PWD/custompathcreation.bash"
local removalscriptpath="$PWD/custompathremoval.bash"

./cmd/csi-sanity/csi-sanity $TESTARGS \
--csi.endpoint=$2 \
--csi.mountdir="foo/target/mount" \
--csi.stagingdir="foo/staging/mount" \
--csi.createmountpathcmd=$creationscriptpath \
--csi.createstagingpathcmd=$creationscriptpath \
--csi.removemountpathcmd=$removalscriptpath \
--csi.removestagingpathcmd=$removalscriptpath; ret=$?
kill -9 $pid

# Delete the script.
rm $creationscriptpath $removalscriptpath

if [ $ret -ne 0 ] ; then
exit $ret
fi
}

make

cd cmd/csi-sanity
Expand All @@ -88,4 +141,10 @@ runTestWithDifferentAddresses "${UDS_NODE}" "${UDS_CONTROLLER}"
rm -f $UDS_NODE
rm -f $UDS_CONTROLLER

runTestAPIWithCustomTargetPaths "${UDS}"
rm -rf $UDS

runTestWithCustomTargetPaths "${UDS}" "${UDS}"
rm -rf $UDS

exit 0
22 changes: 22 additions & 0 deletions mock/service/node.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package service

import (
"os"
"path"
"strconv"

Expand Down Expand Up @@ -40,6 +41,10 @@ func (s *service) NodeStageVolume(
return nil, status.Error(codes.InvalidArgument, "Volume Capability cannot be empty")
}

if err := checkTargetExists(req.StagingTargetPath); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

s.volsRWL.Lock()
defer s.volsRWL.Unlock()

Expand Down Expand Up @@ -131,6 +136,10 @@ func (s *service) NodePublishVolume(
return nil, status.Error(codes.InvalidArgument, "Volume Capability cannot be empty")
}

if err := checkTargetExists(req.TargetPath); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

s.volsRWL.Lock()
defer s.volsRWL.Unlock()

Expand All @@ -157,6 +166,9 @@ func (s *service) NodePublishVolume(

// Publish the volume.
if req.GetStagingTargetPath() != "" {
if err := checkTargetExists(req.GetStagingTargetPath()); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
v.VolumeContext[nodeMntPathKey] = req.GetStagingTargetPath()
} else {
v.VolumeContext[nodeMntPathKey] = device
Expand Down Expand Up @@ -336,3 +348,13 @@ func (s *service) NodeGetVolumeStats(ctx context.Context,
},
}, nil
}

// checkTargetExists checks if a given path exists and returns error if the path
// does not exists.
func checkTargetExists(targetPath string) error {
_, err := os.Stat(targetPath)
if err != nil && os.IsNotExist(err) {
return status.Errorf(codes.Internal, "target path %s does not exists", targetPath)
}
return nil
}
34 changes: 15 additions & 19 deletions pkg/sanity/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,6 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
s,
csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME)
nodeStageSupported = isNodeCapabilitySupported(c, csi.NodeServiceCapability_RPC_STAGE_UNSTAGE_VOLUME)
if nodeStageSupported {
err := createMountTargetLocation(sc.Config.StagingPath)
Expect(err).NotTo(HaveOccurred())
}
nodeVolumeStatsSupported = isNodeCapabilitySupported(c, csi.NodeServiceCapability_RPC_GET_VOLUME_STATS)
cl = &Cleanup{
Context: sc,
Expand Down Expand Up @@ -190,7 +186,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
context.Background(),
&csi.NodePublishVolumeRequest{
VolumeId: "id",
TargetPath: sc.Config.TargetPath,
TargetPath: sc.targetPath,
Secrets: sc.Secrets.NodePublishVolumeSecret,
},
)
Expand Down Expand Up @@ -247,7 +243,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
_, err := c.NodeStageVolume(
context.Background(),
&csi.NodeStageVolumeRequest{
StagingTargetPath: sc.Config.StagingPath,
StagingTargetPath: sc.stagingPath,
VolumeCapability: &csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
Expand Down Expand Up @@ -329,7 +325,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
context.Background(),
&csi.NodeStageVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
StagingTargetPath: sc.Config.StagingPath,
StagingTargetPath: sc.stagingPath,
PublishContext: map[string]string{
"device": device,
},
Expand Down Expand Up @@ -368,7 +364,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
_, err := c.NodeUnstageVolume(
context.Background(),
&csi.NodeUnstageVolumeRequest{
StagingTargetPath: sc.Config.StagingPath,
StagingTargetPath: sc.stagingPath,
})
Expect(err).To(HaveOccurred())

Expand Down Expand Up @@ -519,7 +515,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
},
},
StagingTargetPath: sc.Config.StagingPath,
StagingTargetPath: sc.stagingPath,
VolumeContext: vol.GetVolume().GetVolumeContext(),
PublishContext: conpubvol.GetPublishContext(),
Secrets: sc.Secrets.NodeStageVolumeSecret,
Expand All @@ -532,13 +528,13 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
By("publishing the volume on a node")
var stagingPath string
if nodeStageSupported {
stagingPath = sc.Config.StagingPath
stagingPath = sc.stagingPath
}
nodepubvol, err := c.NodePublishVolume(
context.Background(),
&csi.NodePublishVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
TargetPath: sc.Config.TargetPath,
TargetPath: sc.targetPath,
StagingTargetPath: stagingPath,
VolumeCapability: &csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{
Expand Down Expand Up @@ -577,7 +573,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
context.Background(),
&csi.NodeUnpublishVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
TargetPath: sc.Config.TargetPath,
TargetPath: sc.targetPath,
})
Expect(err).NotTo(HaveOccurred())
Expect(nodeunpubvol).NotTo(BeNil())
Expand All @@ -588,7 +584,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
context.Background(),
&csi.NodeUnstageVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
StagingTargetPath: sc.Config.StagingPath,
StagingTargetPath: sc.stagingPath,
},
)
Expect(err).NotTo(HaveOccurred())
Expand Down Expand Up @@ -703,7 +699,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
},
},
StagingTargetPath: sc.Config.StagingPath,
StagingTargetPath: sc.stagingPath,
VolumeContext: vol.GetVolume().GetVolumeContext(),
PublishContext: conpubvol.GetPublishContext(),
Secrets: sc.Secrets.NodeStageVolumeSecret,
Expand All @@ -716,13 +712,13 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
By("publishing the volume on a node")
var stagingPath string
if nodeStageSupported {
stagingPath = sc.Config.StagingPath
stagingPath = sc.stagingPath
}
nodepubvol, err := c.NodePublishVolume(
context.Background(),
&csi.NodePublishVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
TargetPath: sc.Config.TargetPath,
TargetPath: sc.targetPath,
StagingTargetPath: stagingPath,
VolumeCapability: &csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{
Expand All @@ -747,7 +743,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
context.Background(),
&csi.NodeGetVolumeStatsRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
VolumePath: sc.Config.TargetPath,
VolumePath: sc.targetPath,
},
)
Expect(err).ToNot(HaveOccurred())
Expand All @@ -760,7 +756,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
context.Background(),
&csi.NodeUnpublishVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
TargetPath: sc.Config.TargetPath,
TargetPath: sc.targetPath,
})
Expect(err).NotTo(HaveOccurred())
Expect(nodeunpubvol).NotTo(BeNil())
Expand All @@ -771,7 +767,7 @@ var _ = DescribeSanity("Node Service", func(sc *SanityContext) {
context.Background(),
&csi.NodeUnstageVolumeRequest{
VolumeId: vol.GetVolume().GetVolumeId(),
StagingTargetPath: sc.Config.StagingPath,
StagingTargetPath: sc.stagingPath,
},
)
Expect(err).NotTo(HaveOccurred())
Expand Down
Loading

0 comments on commit ca4c526

Please sign in to comment.