From 3a692a4360f0270a63d95cd27c7e2c0b15effb72 Mon Sep 17 00:00:00 2001 From: Tim Gross Date: Mon, 7 Mar 2022 09:06:50 -0500 Subject: [PATCH] csi: get plugin ID for creating snapshot from volume, not args (#12195) The `CreateSnapshot` RPC expects a plugin ID to be set by the API, but in the common case of the `nomad volume snapshot create` command, we don't ask the user for the plugin ID because it's available from the volume we're snapshotting. Change the order of the RPC so that we get the volume first and then use the volume's plugin ID for the plugin if the API didn't set the value. --- .changelog/12195.txt | 3 +++ nomad/csi_endpoint.go | 39 +++++++++++++++++++++----------------- nomad/csi_endpoint_test.go | 1 - 3 files changed, 25 insertions(+), 18 deletions(-) create mode 100644 .changelog/12195.txt diff --git a/.changelog/12195.txt b/.changelog/12195.txt new file mode 100644 index 000000000..97ec9bc75 --- /dev/null +++ b/.changelog/12195.txt @@ -0,0 +1,3 @@ +```release-note:bug +csi: Fixed a bug where creating snapshots required a plugin ID instead of falling back to the volume's plugin ID +``` diff --git a/nomad/csi_endpoint.go b/nomad/csi_endpoint.go index ed0f95131..b95afc3a4 100644 --- a/nomad/csi_endpoint.go +++ b/nomad/csi_endpoint.go @@ -1095,22 +1095,6 @@ func (v *CSIVolume) CreateSnapshot(args *structs.CSISnapshotCreateRequest, reply return fmt.Errorf("snapshot cannot be nil") } - plugin, err := state.CSIPluginByID(nil, snap.PluginID) - if err != nil { - multierror.Append(&mErr, - fmt.Errorf("error querying plugin %q: %v", snap.PluginID, err)) - continue - } - if plugin == nil { - multierror.Append(&mErr, fmt.Errorf("no such plugin %q", snap.PluginID)) - continue - } - if !plugin.HasControllerCapability(structs.CSIControllerSupportsCreateDeleteSnapshot) { - multierror.Append(&mErr, - fmt.Errorf("plugin %q does not support snapshot", snap.PluginID)) - continue - } - vol, err := state.CSIVolumeByID(nil, args.RequestNamespace(), snap.SourceVolumeID) if err != nil { multierror.Append(&mErr, fmt.Errorf("error querying volume %q: %v", snap.SourceVolumeID, err)) @@ -1121,13 +1105,34 @@ func (v *CSIVolume) CreateSnapshot(args *structs.CSISnapshotCreateRequest, reply continue } + pluginID := snap.PluginID + if pluginID == "" { + pluginID = vol.PluginID + } + + plugin, err := state.CSIPluginByID(nil, pluginID) + if err != nil { + multierror.Append(&mErr, + fmt.Errorf("error querying plugin %q: %v", pluginID, err)) + continue + } + if plugin == nil { + multierror.Append(&mErr, fmt.Errorf("no such plugin %q", pluginID)) + continue + } + if !plugin.HasControllerCapability(structs.CSIControllerSupportsCreateDeleteSnapshot) { + multierror.Append(&mErr, + fmt.Errorf("plugin %q does not support snapshot", pluginID)) + continue + } + cReq := &cstructs.ClientCSIControllerCreateSnapshotRequest{ ExternalSourceVolumeID: vol.ExternalID, Name: snap.Name, Secrets: vol.Secrets, Parameters: snap.Parameters, } - cReq.PluginID = plugin.ID + cReq.PluginID = pluginID cResp := &cstructs.ClientCSIControllerCreateSnapshotResponse{} err = v.srv.RPC(method, cReq, cResp) if err != nil { diff --git a/nomad/csi_endpoint_test.go b/nomad/csi_endpoint_test.go index 4c846d549..305604a5c 100644 --- a/nomad/csi_endpoint_test.go +++ b/nomad/csi_endpoint_test.go @@ -1200,7 +1200,6 @@ func TestCSIVolumeEndpoint_CreateSnapshot(t *testing.T) { SourceVolumeID: "test-volume0", Secrets: structs.CSISecrets{"mysecret": "secretvalue"}, Parameters: map[string]string{"myparam": "paramvalue"}, - PluginID: "minnie", }}, WriteRequest: structs.WriteRequest{ Region: "global",