From 53b6cc183d2d5c5b3c87d1e4389c253add9846f4 Mon Sep 17 00:00:00 2001 From: Travis Glenn Hansen Date: Sat, 1 Apr 2023 20:05:21 -0600 Subject: [PATCH] MULTI_NODE_MULTI_WRITER for block access by default Signed-off-by: Travis Glenn Hansen --- CHANGELOG.md | 9 +++ src/driver/controller-client-common/index.js | 38 ++++++++--- src/driver/controller-synology/index.js | 66 ++++++++++++++------ src/driver/controller-zfs-local/index.js | 15 ++++- src/driver/controller-zfs/index.js | 29 +++++++-- src/driver/freenas/api.js | 66 ++++++++++++++------ src/driver/node-manual/index.js | 16 +++++ 7 files changed, 182 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15c92ba..fde170a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# v1.8.2 + +Released 2023-04-01 + +- more comprehensive support to manually set `access_modes` +- more intelligent handling of `access_modes` when `access_type=block` + - https://github.com/ceph/ceph-csi/blob/devel/examples/README.md#how-to-test-rbd-multi_node_multi_writer-block-feature + - others? allow this by default + # v1.8.1 Released 2023-02-25 diff --git a/src/driver/controller-client-common/index.js b/src/driver/controller-client-common/index.js index a211888..0279faa 100644 --- a/src/driver/controller-client-common/index.js +++ b/src/driver/controller-client-common/index.js @@ -104,6 +104,33 @@ class ControllerClientCommonDriver extends CsiBaseDriver { } } + getAccessModes(capability) { + let access_modes = _.get(this.options, "csi.access_modes", null); + if (access_modes !== null) { + return access_modes; + } + + access_modes = [ + "UNKNOWN", + "SINGLE_NODE_WRITER", + "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 + "SINGLE_NODE_MULTI_WRITER", // added in v1.5.0 + "SINGLE_NODE_READER_ONLY", + "MULTI_NODE_READER_ONLY", + "MULTI_NODE_SINGLE_WRITER", + "MULTI_NODE_MULTI_WRITER", + ]; + + if ( + capability.access_type == "block" && + !access_modes.includes("MULTI_NODE_MULTI_WRITER") + ) { + access_modes.push("MULTI_NODE_MULTI_WRITER"); + } + + return access_modes; + } + assertCapabilities(capabilities) { const driver = this; this.ctx.logger.verbose("validating capabilities: %j", capabilities); @@ -126,16 +153,7 @@ class ControllerClientCommonDriver extends CsiBaseDriver { } if ( - ![ - "UNKNOWN", - "SINGLE_NODE_WRITER", - "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 - "SINGLE_NODE_MULTI_WRITER", // added in v1.5.0 - "SINGLE_NODE_READER_ONLY", - "MULTI_NODE_READER_ONLY", - "MULTI_NODE_SINGLE_WRITER", - "MULTI_NODE_MULTI_WRITER", - ].includes(capability.access_mode.mode) + !this.getAccessModes(capability).includes(capability.access_mode.mode) ) { message = `invalid access_mode, ${capability.access_mode.mode}`; return false; diff --git a/src/driver/controller-synology/index.js b/src/driver/controller-synology/index.js index 7ce5f18..91619d8 100644 --- a/src/driver/controller-synology/index.js +++ b/src/driver/controller-synology/index.js @@ -208,6 +208,47 @@ class ControllerSynologyDriver extends CsiBaseDriver { return location; } + getAccessModes(capability) { + let access_modes = _.get(this.options, "csi.access_modes", null); + if (access_modes !== null) { + return access_modes; + } + + const driverResourceType = this.getDriverResourceType(); + switch (driverResourceType) { + case "filesystem": + access_modes = [ + "UNKNOWN", + "SINGLE_NODE_WRITER", + "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 + "SINGLE_NODE_MULTI_WRITER", // added in v1.5.0 + "SINGLE_NODE_READER_ONLY", + "MULTI_NODE_READER_ONLY", + "MULTI_NODE_SINGLE_WRITER", + "MULTI_NODE_MULTI_WRITER", + ]; + case "volume": + access_modes = [ + "UNKNOWN", + "SINGLE_NODE_WRITER", + "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 + "SINGLE_NODE_MULTI_WRITER", // added in v1.5.0 + "SINGLE_NODE_READER_ONLY", + "MULTI_NODE_READER_ONLY", + "MULTI_NODE_SINGLE_WRITER", + ]; + } + + if ( + capability.access_type == "block" && + !access_modes.includes("MULTI_NODE_MULTI_WRITER") + ) { + access_modes.push("MULTI_NODE_MULTI_WRITER"); + } + + return access_modes; + } + assertCapabilities(capabilities) { const driverResourceType = this.getDriverResourceType(); this.ctx.logger.verbose("validating capabilities: %j", capabilities); @@ -233,16 +274,9 @@ class ControllerSynologyDriver extends CsiBaseDriver { } if ( - ![ - "UNKNOWN", - "SINGLE_NODE_WRITER", - "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 - "SINGLE_NODE_MULTI_WRITER", // added in v1.5.0 - "SINGLE_NODE_READER_ONLY", - "MULTI_NODE_READER_ONLY", - "MULTI_NODE_SINGLE_WRITER", - "MULTI_NODE_MULTI_WRITER", - ].includes(capability.access_mode.mode) + !this.getAccessModes(capability).includes( + capability.access_mode.mode + ) ) { message = `invalid access_mode, ${capability.access_mode.mode}`; return false; @@ -263,15 +297,9 @@ class ControllerSynologyDriver extends CsiBaseDriver { } if ( - ![ - "UNKNOWN", - "SINGLE_NODE_WRITER", - "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 - "SINGLE_NODE_MULTI_WRITER", // added in v1.5.0 - "SINGLE_NODE_READER_ONLY", - "MULTI_NODE_READER_ONLY", - "MULTI_NODE_SINGLE_WRITER", - ].includes(capability.access_mode.mode) + !this.getAccessModes(capability).includes( + capability.access_mode.mode + ) ) { message = `invalid access_mode, ${capability.access_mode.mode}`; return false; diff --git a/src/driver/controller-zfs-local/index.js b/src/driver/controller-zfs-local/index.js index e22b21a..06740da 100644 --- a/src/driver/controller-zfs-local/index.js +++ b/src/driver/controller-zfs-local/index.js @@ -110,7 +110,7 @@ class ControllerZfsLocalDriver extends ControllerZfsBaseDriver { * * @returns Array */ - getAccessModes() { + getAccessModes(capability) { let access_modes = _.get(this.options, "csi.access_modes", null); if (access_modes !== null) { return access_modes; @@ -119,7 +119,7 @@ class ControllerZfsLocalDriver extends ControllerZfsBaseDriver { const driverZfsResourceType = this.getDriverZfsResourceType(); switch (driverZfsResourceType) { case "filesystem": - return [ + access_modes = [ "UNKNOWN", "SINGLE_NODE_WRITER", "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 @@ -130,7 +130,7 @@ class ControllerZfsLocalDriver extends ControllerZfsBaseDriver { "MULTI_NODE_MULTI_WRITER", ]; case "volume": - return [ + access_modes = [ "UNKNOWN", "SINGLE_NODE_WRITER", "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 @@ -141,6 +141,15 @@ class ControllerZfsLocalDriver extends ControllerZfsBaseDriver { "MULTI_NODE_MULTI_WRITER", ]; } + + if ( + capability.access_type == "block" && + !access_modes.includes("MULTI_NODE_MULTI_WRITER") + ) { + access_modes.push("MULTI_NODE_MULTI_WRITER"); + } + + return access_modes; } /** diff --git a/src/driver/controller-zfs/index.js b/src/driver/controller-zfs/index.js index b19bfd6..dcc2f2e 100644 --- a/src/driver/controller-zfs/index.js +++ b/src/driver/controller-zfs/index.js @@ -39,7 +39,7 @@ const MAX_ZVOL_NAME_LENGTH_CACHE_KEY = "controller-zfs:max_zvol_name_length"; * - async setZetabyteCustomOptions(options) // optional * - getDriverZfsResourceType() // return "filesystem" or "volume" * - getFSTypes() // optional - * - getAccessModes() // optional + * - getAccessModes(capability) // optional * - async getAccessibleTopology() // optional * - async createShare(call, datasetName) // return appropriate volume_context for Node operations * - async deleteShare(call, datasetName) // no return expected @@ -207,7 +207,7 @@ class ControllerZfsBaseDriver extends CsiBaseDriver { } } - getAccessModes() { + getAccessModes(capability) { let access_modes = _.get(this.options, "csi.access_modes", null); if (access_modes !== null) { return access_modes; @@ -216,7 +216,7 @@ class ControllerZfsBaseDriver extends CsiBaseDriver { const driverZfsResourceType = this.getDriverZfsResourceType(); switch (driverZfsResourceType) { case "filesystem": - return [ + access_modes = [ "UNKNOWN", "SINGLE_NODE_WRITER", "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 @@ -227,7 +227,7 @@ class ControllerZfsBaseDriver extends CsiBaseDriver { "MULTI_NODE_MULTI_WRITER", ]; case "volume": - return [ + access_modes = [ "UNKNOWN", "SINGLE_NODE_WRITER", "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 @@ -237,6 +237,15 @@ class ControllerZfsBaseDriver extends CsiBaseDriver { "MULTI_NODE_SINGLE_WRITER", ]; } + + if ( + capability.access_type == "block" && + !access_modes.includes("MULTI_NODE_MULTI_WRITER") + ) { + access_modes.push("MULTI_NODE_MULTI_WRITER"); + } + + return access_modes; } assertCapabilities(capabilities) { @@ -261,7 +270,11 @@ class ControllerZfsBaseDriver extends CsiBaseDriver { return false; } - if (!this.getAccessModes().includes(capability.access_mode.mode)) { + if ( + !this.getAccessModes(capability).includes( + capability.access_mode.mode + ) + ) { message = `invalid access_mode, ${capability.access_mode.mode}`; return false; } @@ -278,7 +291,11 @@ class ControllerZfsBaseDriver extends CsiBaseDriver { } } - if (!this.getAccessModes().includes(capability.access_mode.mode)) { + if ( + !this.getAccessModes(capability).includes( + capability.access_mode.mode + ) + ) { message = `invalid access_mode, ${capability.access_mode.mode}`; return false; } diff --git a/src/driver/freenas/api.js b/src/driver/freenas/api.js index 0a0b969..fd4627b 100644 --- a/src/driver/freenas/api.js +++ b/src/driver/freenas/api.js @@ -2017,6 +2017,47 @@ class FreeNASApiDriver extends CsiBaseDriver { }); } + getAccessModes(capability) { + let access_modes = _.get(this.options, "csi.access_modes", null); + if (access_modes !== null) { + return access_modes; + } + + const driverZfsResourceType = this.getDriverZfsResourceType(); + switch (driverZfsResourceType) { + case "filesystem": + access_modes = [ + "UNKNOWN", + "SINGLE_NODE_WRITER", + "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 + "SINGLE_NODE_MULTI_WRITER", // added in v1.5.0 + "SINGLE_NODE_READER_ONLY", + "MULTI_NODE_READER_ONLY", + "MULTI_NODE_SINGLE_WRITER", + "MULTI_NODE_MULTI_WRITER", + ]; + case "volume": + access_modes = [ + "UNKNOWN", + "SINGLE_NODE_WRITER", + "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 + "SINGLE_NODE_MULTI_WRITER", // added in v1.5.0 + "SINGLE_NODE_READER_ONLY", + "MULTI_NODE_READER_ONLY", + "MULTI_NODE_SINGLE_WRITER", + ]; + } + + if ( + capability.access_type == "block" && + !access_modes.includes("MULTI_NODE_MULTI_WRITER") + ) { + access_modes.push("MULTI_NODE_MULTI_WRITER"); + } + + return access_modes; + } + assertCapabilities(capabilities) { const driverZfsResourceType = this.getDriverZfsResourceType(); this.ctx.logger.verbose("validating capabilities: %j", capabilities); @@ -2040,16 +2081,9 @@ class FreeNASApiDriver extends CsiBaseDriver { } if ( - ![ - "UNKNOWN", - "SINGLE_NODE_WRITER", - "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 - "SINGLE_NODE_MULTI_WRITER", // added in v1.5.0 - "SINGLE_NODE_READER_ONLY", - "MULTI_NODE_READER_ONLY", - "MULTI_NODE_SINGLE_WRITER", - "MULTI_NODE_MULTI_WRITER", - ].includes(capability.access_mode.mode) + !this.getAccessModes(capability).includes( + capability.access_mode.mode + ) ) { message = `invalid access_mode, ${capability.access_mode.mode}`; return false; @@ -2070,15 +2104,9 @@ class FreeNASApiDriver extends CsiBaseDriver { } if ( - ![ - "UNKNOWN", - "SINGLE_NODE_WRITER", - "SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0 - "SINGLE_NODE_MULTI_WRITER", // added in v1.5.0 - "SINGLE_NODE_READER_ONLY", - "MULTI_NODE_READER_ONLY", - "MULTI_NODE_SINGLE_WRITER", - ].includes(capability.access_mode.mode) + !this.getAccessModes(capability).includes( + capability.access_mode.mode + ) ) { message = `invalid access_mode, ${capability.access_mode.mode}`; return false; diff --git a/src/driver/node-manual/index.js b/src/driver/node-manual/index.js index a69f26c..96d6722 100644 --- a/src/driver/node-manual/index.js +++ b/src/driver/node-manual/index.js @@ -165,6 +165,14 @@ class NodeManualDriver extends CsiBaseDriver { "MULTI_NODE_MULTI_WRITER", ]; } + + if ( + capability.access_type == "block" && + !access_modes.includes("MULTI_NODE_MULTI_WRITER") + ) { + access_modes.push("MULTI_NODE_MULTI_WRITER"); + } + if (capability.access_type != "mount") { message = `invalid access_type ${capability.access_type}`; return false; @@ -196,6 +204,14 @@ class NodeManualDriver extends CsiBaseDriver { "MULTI_NODE_SINGLE_WRITER", ]; } + + if ( + capability.access_type == "block" && + !access_modes.includes("MULTI_NODE_MULTI_WRITER") + ) { + access_modes.push("MULTI_NODE_MULTI_WRITER"); + } + if (capability.access_type == "mount") { if ( capability.mount.fs_type &&