From f65fc0eb54ffc7c9f6802c81c6a75e9c46182b59 Mon Sep 17 00:00:00 2001 From: Luiz Aoqui Date: Wed, 16 Aug 2023 20:28:34 -0400 Subject: [PATCH 1/2] csi: prevent panic on volume delete When a CSI volume is deleted when its plugin is not running, the function `volAndPluginLookup` returns a `nil` plugin value resulting a panic in the request handler. --- nomad/csi_endpoint.go | 3 +++ nomad/csi_endpoint_test.go | 54 +++++++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/nomad/csi_endpoint.go b/nomad/csi_endpoint.go index c0d1a4d1e456..7dd217d428a7 100644 --- a/nomad/csi_endpoint.go +++ b/nomad/csi_endpoint.go @@ -1155,6 +1155,9 @@ func (v *CSIVolume) Delete(args *structs.CSIVolumeDeleteRequest, reply *structs. return err } } + if plugin == nil { + return fmt.Errorf("plugin %q for volume %q not found", vol.PluginID, volID) + } // NOTE: deleting the volume in the external storage provider can't be // made atomic with deregistration. We can't delete a volume that's diff --git a/nomad/csi_endpoint_test.go b/nomad/csi_endpoint_test.go index c2174bab9ba8..aa548c1f423c 100644 --- a/nomad/csi_endpoint_test.go +++ b/nomad/csi_endpoint_test.go @@ -1201,7 +1201,7 @@ func TestCSIVolumeEndpoint_Delete(t *testing.T) { } var resp0 structs.NodeUpdateResponse err = client.RPC("Node.Register", req0, &resp0) - require.NoError(t, err) + must.NoError(t, err) testutil.WaitForResult(func() (bool, error) { nodes := srv.connectedNodes() @@ -1236,18 +1236,27 @@ func TestCSIVolumeEndpoint_Delete(t *testing.T) { } }).Node index++ - require.NoError(t, state.UpsertNode(structs.MsgTypeTestSetup, index, node)) + must.NoError(t, state.UpsertNode(structs.MsgTypeTestSetup, index, node)) volID := uuid.Generate() - vols := []*structs.CSIVolume{{ - ID: volID, - Namespace: structs.DefaultNamespace, - PluginID: "minnie", - Secrets: structs.CSISecrets{"mysecret": "secretvalue"}, - }} + noPluginVolID := uuid.Generate() + vols := []*structs.CSIVolume{ + { + ID: volID, + Namespace: structs.DefaultNamespace, + PluginID: "minnie", + Secrets: structs.CSISecrets{"mysecret": "secretvalue"}, + }, + { + ID: noPluginVolID, + Namespace: structs.DefaultNamespace, + PluginID: "doesnt-exist", + Secrets: structs.CSISecrets{"mysecret": "secretvalue"}, + }, + } index++ err = state.UpsertCSIVolume(index, vols) - require.NoError(t, err) + must.NoError(t, err) // Delete volumes @@ -1264,7 +1273,7 @@ func TestCSIVolumeEndpoint_Delete(t *testing.T) { } resp1 := &structs.CSIVolumeCreateResponse{} err = msgpackrpc.CallWithCodec(codec, "CSIVolume.Delete", req1, resp1) - require.EqualError(t, err, "volume not found: bad") + must.EqError(t, err, "volume not found: bad") // Make sure the valid volume wasn't deleted req2 := &structs.CSIVolumeGetRequest{ @@ -1275,19 +1284,34 @@ func TestCSIVolumeEndpoint_Delete(t *testing.T) { } resp2 := &structs.CSIVolumeGetResponse{} err = msgpackrpc.CallWithCodec(codec, "CSIVolume.Get", req2, resp2) - require.NoError(t, err) - require.NotNil(t, resp2.Volume) + must.NoError(t, err) + must.NotNil(t, resp2.Volume) // Fix the delete request fake.NextDeleteError = nil req1.VolumeIDs = []string{volID} err = msgpackrpc.CallWithCodec(codec, "CSIVolume.Delete", req1, resp1) - require.NoError(t, err) + must.NoError(t, err) // Make sure it was deregistered err = msgpackrpc.CallWithCodec(codec, "CSIVolume.Get", req2, resp2) - require.NoError(t, err) - require.Nil(t, resp2.Volume) + must.NoError(t, err) + must.Nil(t, resp2.Volume) + + // Create a delete request for a volume without plugin. + req3 := &structs.CSIVolumeDeleteRequest{ + VolumeIDs: []string{noPluginVolID}, + WriteRequest: structs.WriteRequest{ + Region: "global", + Namespace: ns, + }, + Secrets: structs.CSISecrets{ + "secret-key-1": "secret-val-1", + }, + } + resp3 := &structs.CSIVolumeCreateResponse{} + err = msgpackrpc.CallWithCodec(codec, "CSIVolume.Delete", req3, resp3) + must.EqError(t, err, fmt.Sprintf(`plugin "doesnt-exist" for volume "%s" not found`, noPluginVolID)) } func TestCSIVolumeEndpoint_ListExternal(t *testing.T) { From a95ceca5d8711b5b16716f8100aac663540475b0 Mon Sep 17 00:00:00 2001 From: Luiz Aoqui Date: Wed, 16 Aug 2023 20:36:25 -0400 Subject: [PATCH 2/2] changelog: add entry for #18234 --- .changelog/18234.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/18234.txt diff --git a/.changelog/18234.txt b/.changelog/18234.txt new file mode 100644 index 000000000000..21e0824b3565 --- /dev/null +++ b/.changelog/18234.txt @@ -0,0 +1,3 @@ +```release-note:bug +csi: fixed a bug that could case a panic when deleting volumes +```