From 6cde0d3a700a1218e293f09eaf700a43e42a6493 Mon Sep 17 00:00:00 2001 From: Travis Glenn Hansen Date: Mon, 18 Apr 2022 10:23:31 -0600 Subject: [PATCH] zfs-generic-smb driver (sharesmb=on) Signed-off-by: Travis Glenn Hansen --- .github/workflows/main.yml | 1 + bin/democratic-csi | 7 ++- ci/configs/zfs-generic/nfs.yaml | 2 +- ci/configs/zfs-generic/smb.yaml | 40 ++++++++++++ examples/zfs-generic-smb.yaml | 57 +++++++++++++++++ src/driver/controller-zfs-generic/index.js | 73 ++++++++++++++++++++++ src/driver/factory.js | 1 + src/driver/index.js | 4 ++ 8 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 ci/configs/zfs-generic/smb.yaml create mode 100644 examples/zfs-generic-smb.yaml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bcab4e5..c0c594c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -167,6 +167,7 @@ jobs: config: - zfs-generic/iscsi.yaml - zfs-generic/nfs.yaml + - zfs-generic/smb.yaml runs-on: - self-hosted - csi-sanity-zfs-generic diff --git a/bin/democratic-csi b/bin/democratic-csi index df94d93..0f465e2 100755 --- a/bin/democratic-csi +++ b/bin/democratic-csi @@ -1,4 +1,9 @@ -#!/usr/bin/env -S node --expose-gc ${NODE_OPTIONS_CSI_1} ${NODE_OPTIONS_CSI_2} ${NODE_OPTIONS_CSI_3} ${NODE_OPTIONS_CSI_4} ${NODE_OPTIONS_CSI_5} +#!/usr/bin/env -S node --expose-gc ${NODE_OPTIONS_CSI_1} ${NODE_OPTIONS_CSI_2} ${NODE_OPTIONS_CSI_3} ${NODE_OPTIONS_CSI_4} + +/** + * keep the shebang line length under 128 + * https://github.com/democratic-csi/democratic-csi/issues/171 + */ const yaml = require("js-yaml"); const fs = require("fs"); diff --git a/ci/configs/zfs-generic/nfs.yaml b/ci/configs/zfs-generic/nfs.yaml index a3a8b88..e451a73 100644 --- a/ci/configs/zfs-generic/nfs.yaml +++ b/ci/configs/zfs-generic/nfs.yaml @@ -11,7 +11,7 @@ zfs: detachedSnapshotsDatasetParentName: tank/ci/${CI_BUILD_KEY}/s datasetEnableQuotas: true - datasetEnableReservation: true + datasetEnableReservation: false datasetPermissionsMode: "0777" datasetPermissionsUser: 0 datasetPermissionsGroup: 0 diff --git a/ci/configs/zfs-generic/smb.yaml b/ci/configs/zfs-generic/smb.yaml new file mode 100644 index 0000000..272a590 --- /dev/null +++ b/ci/configs/zfs-generic/smb.yaml @@ -0,0 +1,40 @@ +driver: zfs-generic-smb + +sshConnection: + host: ${SERVER_HOST} + port: 22 + username: ${SERVER_USERNAME} + password: ${SERVER_PASSWORD} + +zfs: + datasetParentName: tank/ci/${CI_BUILD_KEY}/v + detachedSnapshotsDatasetParentName: tank/ci/${CI_BUILD_KEY}/s + + datasetProperties: + #aclmode: restricted + #aclinherit: passthrough + #acltype: nfsv4 + casesensitivity: insensitive + + datasetEnableQuotas: true + datasetEnableReservation: false + datasetPermissionsMode: "0770" + datasetPermissionsUser: smbroot + datasetPermissionsGroup: smbroot + +smb: + shareHost: ${SERVER_HOST} + shareStrategy: "setDatasetProperties" + shareStrategySetDatasetProperties: + properties: + sharesmb: "on" + +node: + mount: + mount_flags: "username=smbroot,password=smbroot" + +_private: + csi: + volume: + idHash: + strategy: crc16 diff --git a/examples/zfs-generic-smb.yaml b/examples/zfs-generic-smb.yaml new file mode 100644 index 0000000..db60cf3 --- /dev/null +++ b/examples/zfs-generic-smb.yaml @@ -0,0 +1,57 @@ +driver: zfs-generic-smb +sshConnection: + host: server address + port: 22 + username: root + # use either password or key + password: "" + privateKey: | + -----BEGIN RSA PRIVATE KEY----- + ... + -----END RSA PRIVATE KEY----- + +zfs: + # can be used to override defaults if necessary + # the example below is useful for TrueNAS 12 + #cli: + # sudoEnabled: true + # paths: + # zfs: /usr/local/sbin/zfs + # zpool: /usr/local/sbin/zpool + # sudo: /usr/local/bin/sudo + # chroot: /usr/sbin/chroot + + # can be used to set arbitrary values on the dataset/zvol + # can use handlebars templates with the parameters from the storage class/CO + datasetProperties: + #aclmode: restricted + #aclinherit: passthrough + #acltype: nfsv4 + casesensitivity: insensitive + + datasetParentName: tank/k8s/test + # do NOT make datasetParentName and detachedSnapshotsDatasetParentName overlap + # they may be siblings, but neither should be nested in the other + detachedSnapshotsDatasetParentName: tanks/k8s/test-snapshots + + datasetEnableQuotas: true + datasetEnableReservation: false + datasetPermissionsMode: "0770" + datasetPermissionsUser: smbroot + datasetPermissionsGroup: smbroot + + #datasetPermissionsAclsBinary: nfs4_setfacl + #datasetPermissionsAcls: + #- "-m everyone@:full_set:allow" + #- -s group@:modify_set:fd:allow + #- -a owner@:full_set:fd:allow + +smb: + # https://docs.oracle.com/cd/E23824_01/html/821-1448/gayne.html + # https://www.hiroom2.com/2016/05/18/ubuntu-16-04-share-zfs-storage-via-nfs-smb/ + shareStrategy: "setDatasetProperties" + shareStrategySetDatasetProperties: + properties: + sharesmb: "on" + # share: "" + shareHost: "server address" diff --git a/src/driver/controller-zfs-generic/index.js b/src/driver/controller-zfs-generic/index.js index 31c0fa7..756d268 100644 --- a/src/driver/controller-zfs-generic/index.js +++ b/src/driver/controller-zfs-generic/index.js @@ -52,6 +52,7 @@ class ControllerZfsGenericDriver extends ControllerZfsBaseDriver { getDriverZfsResourceType() { switch (this.options.driver) { case "zfs-generic-nfs": + case "zfs-generic-smb": return "filesystem"; case "zfs-generic-iscsi": return "volume"; @@ -109,6 +110,48 @@ class ControllerZfsGenericDriver extends ControllerZfsBaseDriver { }; return volume_context; + case "zfs-generic-smb": + let share; + switch (this.options.smb.shareStrategy) { + case "setDatasetProperties": + function generateShareName(dataset) { + let name = dataset; + name = name.replaceAll("/", "_"); + name = name.replaceAll("-", "_"); + return name; + } + + for (let key of ["share", "sharesmb"]) { + if ( + this.options.smb.shareStrategySetDatasetProperties.properties[ + key + ] + ) { + await zb.zfs.set(datasetName, { + [key]: + this.options.smb.shareStrategySetDatasetProperties + .properties[key], + }); + } + } + + share = generateShareName(datasetName); + break; + default: + break; + } + + properties = await zb.zfs.get(datasetName, ["mountpoint"]); + properties = properties[datasetName]; + this.ctx.logger.debug("zfs props data: %j", properties); + + volume_context = { + node_attach_driver: "smb", + server: this.options.smb.shareHost, + share, + }; + return volume_context; + case "zfs-generic-iscsi": let basename; let iscsiName; @@ -268,6 +311,36 @@ create /backstores/block/${iscsiName} } break; + case "zfs-generic-smb": + switch (this.options.smb.shareStrategy) { + case "setDatasetProperties": + for (let key of ["share", "sharesmb"]) { + if ( + this.options.smb.shareStrategySetDatasetProperties.properties[ + key + ] + ) { + try { + await zb.zfs.inherit(datasetName, key); + } catch (err) { + if (err.toString().includes("dataset does not exist")) { + // do nothing + } else { + throw err; + } + } + } + } + await sleep(2000); // let things settle + break; + default: + throw new GrpcError( + grpc.status.FAILED_PRECONDITION, + `invalid configuration: unknown shareStrategy ${this.options.nfs.shareStrategy}` + ); + } + break; + case "zfs-generic-iscsi": let basename; let iscsiName; diff --git a/src/driver/factory.js b/src/driver/factory.js index 6cb4850..02dc2ae 100644 --- a/src/driver/factory.js +++ b/src/driver/factory.js @@ -33,6 +33,7 @@ function factory(ctx, options) { case "synology-iscsi": return new ControllerSynologyDriver(ctx, options); case "zfs-generic-nfs": + case "zfs-generic-smb": case "zfs-generic-iscsi": return new ControllerZfsGenericDriver(ctx, options); case "zfs-local-dataset": diff --git a/src/driver/index.js b/src/driver/index.js index 1b9d30b..58d2f09 100644 --- a/src/driver/index.js +++ b/src/driver/index.js @@ -679,6 +679,10 @@ class CsiBaseDriver { if (!has_guest) { mount_flags.push("guest"); } + + if (volume_mount_group) { + mount_flags.push(`gid=${volume_mount_group}`); + } } break; case "iscsi":