Skip to content

Commit ed56374

Browse files
committed
Assert NodePublishVolume behavior for single node single writer volumes
Ensure that a single node single writer volume cannot be mounted at two different target paths on the same node. See the second table in the NodePublishVolume section of the CSI spec for more details: https://github.com/container-storage-interface/spec/blob/v1.7.0/spec.md#nodepublishvolume
1 parent 45cd08b commit ed56374

File tree

2 files changed

+61
-7
lines changed

2 files changed

+61
-7
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ build-sanity:
3838
$(MAKE) -C cmd/csi-sanity all
3939

4040

41-
TEST_HOSTPATH_VERSION=v1.7.3
41+
TEST_HOSTPATH_VERSION=v1.11.0
4242
TEST_HOSTPATH_SOURCE=bin/hostpath-source
4343
TEST_HOSTPATH_REPO=https://github.com/kubernetes-csi/csi-driver-host-path.git
4444
bin/hostpathplugin:

pkg/sanity/node.go

+60-6
Original file line numberDiff line numberDiff line change
@@ -183,12 +183,13 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) {
183183
var (
184184
r *Resources
185185

186-
providesControllerService bool
187-
controllerPublishSupported bool
188-
nodeStageSupported bool
189-
nodeVolumeStatsSupported bool
190-
nodeExpansionSupported bool
191-
controllerExpansionSupported bool
186+
providesControllerService bool
187+
controllerPublishSupported bool
188+
nodeStageSupported bool
189+
nodeVolumeStatsSupported bool
190+
nodeExpansionSupported bool
191+
controllerExpansionSupported bool
192+
singleNodeMultiWriterSupported bool
192193
)
193194

194195
createVolumeWithCapability := func(volumeName string, cap *csi.VolumeCapability) *csi.CreateVolumeResponse {
@@ -319,6 +320,8 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) {
319320
nodeVolumeStatsSupported = isNodeCapabilitySupported(n, csi.NodeServiceCapability_RPC_GET_VOLUME_STATS)
320321
nodeExpansionSupported = isNodeCapabilitySupported(n, csi.NodeServiceCapability_RPC_EXPAND_VOLUME)
321322
controllerExpansionSupported = isControllerCapabilitySupported(cl, csi.ControllerServiceCapability_RPC_EXPAND_VOLUME)
323+
singleNodeMultiWriterSupported = isNodeCapabilitySupported(n, csi.NodeServiceCapability_RPC_SINGLE_NODE_MULTI_WRITER)
324+
322325
r = &Resources{
323326
Context: sc,
324327
ControllerClient: cl,
@@ -431,6 +434,57 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) {
431434
Expect(ok).To(BeTrue())
432435
Expect(serverError.Code()).To(Equal(codes.InvalidArgument), "unexpected error: %s", serverError.Message())
433436
})
437+
438+
Describe("with single node multi writer capability", func() {
439+
BeforeEach(func() {
440+
if !singleNodeMultiWriterSupported {
441+
Skip("Service does not have single node multi writer capability")
442+
}
443+
})
444+
445+
It("should fail when volume with single node single writer access mode is already mounted at a different target path", func() {
446+
By("creating a single node single writer volume")
447+
name := UniqueString("sanity-node-publish-single-node-single-writer")
448+
cap := TestVolumeCapabilityWithAccessType(sc, csi.VolumeCapability_AccessMode_SINGLE_NODE_SINGLE_WRITER)
449+
vol := createVolumeWithCapability(name, cap)
450+
451+
By("Getting a node id")
452+
nid, err := r.NodeGetInfo(
453+
context.Background(),
454+
&csi.NodeGetInfoRequest{})
455+
Expect(err).NotTo(HaveOccurred())
456+
Expect(nid).NotTo(BeNil())
457+
Expect(nid.GetNodeId()).NotTo(BeEmpty())
458+
459+
By("Staging and publishing a volume")
460+
conpubvol := controllerPublishVolumeWithCapability(name, vol, nid, cap)
461+
_ = nodeStageVolumeWithCapability(name, vol, conpubvol, cap)
462+
_ = nodePublishVolumeWithCapability(name, vol, conpubvol, cap)
463+
464+
nodePublishRequest := &csi.NodePublishVolumeRequest{
465+
VolumeId: vol.GetVolume().GetVolumeId(),
466+
TargetPath: sc.TargetPath + "/other_target",
467+
VolumeCapability: cap,
468+
VolumeContext: vol.GetVolume().GetVolumeContext(),
469+
Secrets: sc.Secrets.NodePublishVolumeSecret,
470+
}
471+
if conpubvol != nil {
472+
nodePublishRequest.PublishContext = conpubvol.GetPublishContext()
473+
}
474+
if nodeStageSupported {
475+
nodePublishRequest.StagingTargetPath = sc.StagingPath
476+
}
477+
478+
_, err = r.NodePublishVolume(
479+
context.Background(),
480+
nodePublishRequest)
481+
Expect(err).To(HaveOccurred())
482+
483+
serverError, ok := status.FromError(err)
484+
Expect(ok).To(BeTrue())
485+
Expect(serverError.Code()).To(Equal(codes.FailedPrecondition), "unexpected error: %s", serverError.Message())
486+
})
487+
})
434488
})
435489

436490
Describe("NodeUnpublishVolume", func() {

0 commit comments

Comments
 (0)