Skip to content

Commit 0f0451b

Browse files
authored
Merge pull request #36 from hughdanliu/inflight-node
Add inflight checks to node mounting operations
2 parents bec107d + 87f630e commit 0f0451b

File tree

2 files changed

+79
-4
lines changed

2 files changed

+79
-4
lines changed

pkg/driver/node.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ func (d *nodeService) NodePublishVolume(ctx context.Context, req *csi.NodePublis
109109
return nil, status.Error(codes.InvalidArgument, "NodePublishVolume: Volume capability not supported")
110110
}
111111

112+
if ok := d.inFlight.Insert(volumeID); !ok {
113+
return nil, status.Errorf(codes.Aborted, internal.VolumeOperationAlreadyExistsErrorMsg, volumeID)
114+
}
115+
defer func() {
116+
klog.V(4).InfoS("NodePublishVolume: volume operation finished", "volumeId", volumeID)
117+
d.inFlight.Delete(volumeID)
118+
}()
119+
112120
context := req.GetVolumeContext()
113121
dnsName := context[volumeContextDnsName]
114122
volumePath := context[volumeContextVolumePath]
@@ -209,6 +217,14 @@ func (d *nodeService) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpu
209217
return nil, status.Error(codes.InvalidArgument, "NodeUnpublishVolume: Target path not provided")
210218
}
211219

220+
if ok := d.inFlight.Insert(volumeID); !ok {
221+
return nil, status.Errorf(codes.Aborted, internal.VolumeOperationAlreadyExistsErrorMsg, volumeID)
222+
}
223+
defer func() {
224+
klog.V(4).InfoS("NodeUnpublishVolume: volume operation finished", "volumeId", volumeID)
225+
d.inFlight.Delete(volumeID)
226+
}()
227+
212228
// Check if the target is mounted before unmounting
213229
notMnt, _ := d.mounter.IsLikelyNotMountPoint(targetPath)
214230
if notMnt {

pkg/driver/node_test.go

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,38 @@ func TestNodePublishVolume(t *testing.T) {
622622
mockCtl.Finish()
623623
},
624624
},
625+
{
626+
name: "fail: another operation in-flight on given volumeId",
627+
testFunc: func(t *testing.T) {
628+
mockCtl := gomock.NewController(t)
629+
defer mockCtl.Finish()
630+
631+
mockMetadata := cloudMock.NewMockMetadataService(mockCtl)
632+
mockMounter := driverMocks.NewMockMounter(mockCtl)
633+
634+
driver := &nodeService{
635+
metadata: mockMetadata,
636+
mounter: mockMounter,
637+
inFlight: internal.NewInFlight(),
638+
}
639+
640+
ctx := context.Background()
641+
req := &csi.NodePublishVolumeRequest{
642+
VolumeId: volumeId,
643+
VolumeContext: map[string]string{
644+
"DNSName": dnsName,
645+
"ResourceType": volType,
646+
},
647+
VolumeCapability: stdVolCap,
648+
TargetPath: targetPath,
649+
}
650+
651+
driver.inFlight.Insert(volumeId)
652+
653+
_, err := driver.NodePublishVolume(ctx, req)
654+
expectErr(t, err, codes.Aborted)
655+
},
656+
},
625657
}
626658

627659
for _, tc := range testCases {
@@ -756,6 +788,33 @@ func TestNodeUnpublishVolume(t *testing.T) {
756788
}
757789
},
758790
},
791+
{
792+
name: "fail: another operation in-flight on given volumeId",
793+
testFunc: func(t *testing.T) {
794+
mockCtl := gomock.NewController(t)
795+
defer mockCtl.Finish()
796+
797+
mockMetadata := cloudMock.NewMockMetadataService(mockCtl)
798+
mockMounter := driverMocks.NewMockMounter(mockCtl)
799+
800+
driver := &nodeService{
801+
metadata: mockMetadata,
802+
mounter: mockMounter,
803+
inFlight: internal.NewInFlight(),
804+
}
805+
806+
ctx := context.Background()
807+
req := &csi.NodeUnpublishVolumeRequest{
808+
VolumeId: volumeId,
809+
TargetPath: targetPath,
810+
}
811+
812+
driver.inFlight.Insert(volumeId)
813+
814+
_, err := driver.NodeUnpublishVolume(ctx, req)
815+
expectErr(t, err, codes.Aborted)
816+
},
817+
},
759818
}
760819
for _, tc := range testCases {
761820
t.Run(tc.name, tc.testFunc)
@@ -887,15 +946,15 @@ func getNodeMock(mockCtl *gomock.Controller, nodeName string, returnNode *corev1
887946

888947
func expectErr(t *testing.T, actualErr error, expectedCode codes.Code) {
889948
if actualErr == nil {
890-
t.Fatalf("Expect error but got no error")
949+
t.Fatalf("Expected error code %d but got no error", expectedCode)
891950
}
892951

893-
status, ok := status.FromError(actualErr)
952+
errStatus, ok := status.FromError(actualErr)
894953
if !ok {
895954
t.Fatalf("Failed to get error status code from error: %v", actualErr)
896955
}
897956

898-
if status.Code() != expectedCode {
899-
t.Fatalf("Expected error code %d, got %d message %s", expectedCode, status.Code(), status.Message())
957+
if errStatus.Code() != expectedCode {
958+
t.Fatalf("Expected error code %d, got %d message %s", expectedCode, errStatus.Code(), errStatus.Message())
900959
}
901960
}

0 commit comments

Comments
 (0)