From 3810363066c92fe0ef0018f8feeadada3053f6a0 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 24 Nov 2025 19:18:59 +0000 Subject: [PATCH] Rename all FreeNAS references to TrueNAS - Renamed src/driver/freenas/ directory to src/driver/truenas/ - Renamed FreeNASApiDriver class to TrueNASApiDriver - Updated all FREENAS_* constants to TRUENAS_* - Updated registry namespace from FreeNASApiDriver to TrueNASApiDriver - Updated driver factory to import TrueNASApiDriver from truenas directory - Rewrote example configurations for TrueNAS SCALE 25.04+ WebSocket API: - truenas-nfs.yaml: Clean NFS configuration - truenas-iscsi.yaml: Clean iSCSI configuration - truenas-nvmeof.yaml: New NVMe-oF configuration - Removed freenas-api-smb.yaml (SMB not supported) - All driver names updated: truenas-nfs, truenas-iscsi, truenas-nvmeof --- examples/freenas-api-iscsi.yaml | 91 ------------ examples/freenas-api-nfs.yaml | 62 -------- examples/freenas-api-smb.yaml | 81 ---------- examples/truenas-iscsi.yaml | 106 ++++++++++++++ examples/truenas-nfs.yaml | 65 +++++++++ examples/truenas-nvmeof.yaml | 99 +++++++++++++ src/driver/factory.js | 4 +- src/driver/{freenas => truenas}/api.js | 138 +++++++++--------- src/driver/{freenas => truenas}/http/api.js | 2 +- src/driver/{freenas => truenas}/http/index.js | 0 10 files changed, 339 insertions(+), 309 deletions(-) delete mode 100644 examples/freenas-api-iscsi.yaml delete mode 100644 examples/freenas-api-nfs.yaml delete mode 100644 examples/freenas-api-smb.yaml create mode 100644 examples/truenas-iscsi.yaml create mode 100644 examples/truenas-nfs.yaml create mode 100644 examples/truenas-nvmeof.yaml rename src/driver/{freenas => truenas}/api.js (96%) rename src/driver/{freenas => truenas}/http/api.js (99%) rename src/driver/{freenas => truenas}/http/index.js (100%) diff --git a/examples/freenas-api-iscsi.yaml b/examples/freenas-api-iscsi.yaml deleted file mode 100644 index 3b2d922..0000000 --- a/examples/freenas-api-iscsi.yaml +++ /dev/null @@ -1,91 +0,0 @@ -driver: freenas-api-iscsi -instance_id: -httpConnection: - protocol: http - host: server address - port: 80 - # use only 1 of apiKey or username/password - # if both are present, apiKey is preferred - # apiKey is only available starting in TrueNAS-12 - #apiKey: - username: root - password: - allowInsecure: true - # use apiVersion 2 for TrueNAS-12 and up (will work on 11.x in some scenarios as well) - # leave unset for auto-detection - #apiVersion: 2 -zfs: - # can be used to override defaults if necessary - # the example below is useful for TrueNAS 12 - #cli: - # sudoEnabled: true - # - # leave paths unset for auto-detection - # 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: - # "org.freenas:description": "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}/{{ parameters.[csi.storage.k8s.io/pvc/name] }}" - # "org.freenas:test": "{{ parameters.foo }}" - # "org.freenas:test2": "some value" - - # total volume name (zvol//) length cannot exceed 63 chars - # https://www.ixsystems.com/documentation/freenas/11.2-U5/storage.html#zfs-zvol-config-opts-tab - # standard volume naming overhead is 46 chars - # datasetParentName should therefore be 17 chars or less when using TrueNAS 12 or below (SCALE and 13+ do not have the same limits) - # for work-arounds see https://github.com/democratic-csi/democratic-csi/issues/54 - datasetParentName: tank/k8s/b/vols - # do NOT make datasetParentName and detachedSnapshotsDatasetParentName overlap - # they may be siblings, but neither should be nested in the other - # do NOT comment this option out even if you don't plan to use snapshots, just leave it with dummy value - detachedSnapshotsDatasetParentName: tanks/k8s/b/snaps - # "" (inherit), lz4, gzip-9, etc - zvolCompression: - # "" (inherit), on, off, verify - zvolDedup: - zvolEnableReservation: false - # 512, 1K, 2K, 4K, 8K, 16K, 64K, 128K default is 16K - zvolBlocksize: -iscsi: - targetPortal: "server[:port]" - # for multipath - targetPortals: [] # [ "server[:port]", "server[:port]", ... ] - # leave empty to omit usage of -I with iscsiadm - interface: - - # MUST ensure uniqueness - # full iqn limit is 223 bytes, plan accordingly - # default is "{{ name }}" - #nameTemplate: "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}-{{ parameters.[csi.storage.k8s.io/pvc/name] }}" - namePrefix: csi- - nameSuffix: "-clustera" - - # add as many as needed - targetGroups: - # get the correct ID from the "portal" section in the UI - # https://github.com/democratic-csi/democratic-csi/issues/302 - # NOTE: the ID in the UI does NOT always match the ID in the DB, you must use the DB value - - targetGroupPortalGroup: 1 - # get the correct ID from the "initiators" section in the UI - targetGroupInitiatorGroup: 1 - # None, CHAP, or CHAP Mutual - targetGroupAuthType: None - # get the correct ID from the "Authorized Access" section of the UI - # only required if using Chap - targetGroupAuthGroup: - - #extentCommentTemplate: "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}/{{ parameters.[csi.storage.k8s.io/pvc/name] }}" - extentInsecureTpc: true - extentXenCompat: false - extentDisablePhysicalBlocksize: true - # 512, 1024, 2048, or 4096, - extentBlocksize: 512 - # "" (let FreeNAS decide, currently defaults to SSD), Unknown, SSD, 5400, 7200, 10000, 15000 - extentRpm: "SSD" - # 0-100 (0 == ignore) - extentAvailThreshold: 0 diff --git a/examples/freenas-api-nfs.yaml b/examples/freenas-api-nfs.yaml deleted file mode 100644 index 1ec960e..0000000 --- a/examples/freenas-api-nfs.yaml +++ /dev/null @@ -1,62 +0,0 @@ -driver: freenas-api-nfs -instance_id: -httpConnection: - protocol: http - host: server address - port: 80 - # use only 1 of apiKey or username/password - # if both are present, apiKey is preferred - # apiKey is only available starting in TrueNAS-12 - #apiKey: - username: root - password: - allowInsecure: true - # use apiVersion 2 for TrueNAS-12 and up (will work on 11.x in some scenarios as well) - # leave unset for auto-detection - #apiVersion: 2 -zfs: - # can be used to override defaults if necessary - # the example below is useful for TrueNAS 12 - #cli: - # sudoEnabled: true - # - # leave paths unset for auto-detection - # 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: - # "org.freenas:description": "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}/{{ parameters.[csi.storage.k8s.io/pvc/name] }}" - # "org.freenas:test": "{{ parameters.foo }}" - # "org.freenas:test2": "some value" - - datasetParentName: tank/k8s/a/vols - # do NOT make datasetParentName and detachedSnapshotsDatasetParentName overlap - # they may be siblings, but neither should be nested in the other - # do NOT comment this option out even if you don't plan to use snapshots, just leave it with dummy value - detachedSnapshotsDatasetParentName: tank/k8s/a/snaps - datasetEnableQuotas: true - datasetEnableReservation: false - datasetPermissionsMode: "0777" - datasetPermissionsUser: 0 - datasetPermissionsGroup: 0 - - # not supported yet - #datasetPermissionsAcls: - #- "-m everyone@:full_set:allow" - #- "-m u:kube:full_set:allow" - -nfs: - #shareCommentTemplate: "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}-{{ parameters.[csi.storage.k8s.io/pvc/name] }}" - shareHost: server address - shareAlldirs: false - shareAllowedHosts: [] - shareAllowedNetworks: [] - shareMaprootUser: root - shareMaprootGroup: root - shareMapallUser: "" - shareMapallGroup: "" diff --git a/examples/freenas-api-smb.yaml b/examples/freenas-api-smb.yaml deleted file mode 100644 index 9d13cef..0000000 --- a/examples/freenas-api-smb.yaml +++ /dev/null @@ -1,81 +0,0 @@ -driver: freenas-api-smb -instance_id: -httpConnection: - protocol: http - host: server address - port: 80 - # use only 1 of apiKey or username/password - # if both are present, apiKey is preferred - # apiKey is only available starting in TrueNAS-12 - #apiKey: - username: root - password: - allowInsecure: true - # use apiVersion 2 for TrueNAS-12 and up (will work on 11.x in some scenarios as well) - # leave unset for auto-detection - #apiVersion: 2 -zfs: - # can be used to override defaults if necessary - # the example below is useful for TrueNAS 12 - #cli: - # sudoEnabled: true - # - # leave paths unset for auto-detection - # 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: - # "org.freenas:description": "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}/{{ parameters.[csi.storage.k8s.io/pvc/name] }}" - # "org.freenas:test": "{{ parameters.foo }}" - # "org.freenas:test2": "some value" - - # these are managed automatically via the volume creation process when flagged as an smb volume - #datasetProperties: - # aclmode: restricted - # casesensitivity: mixed - - datasetParentName: tank/k8s/a/vols - # do NOT make datasetParentName and detachedSnapshotsDatasetParentName overlap - # they may be siblings, but neither should be nested in the other - # do NOT comment this option out even if you don't plan to use snapshots, just leave it with dummy value - detachedSnapshotsDatasetParentName: tank/k8s/a/snaps - datasetEnableQuotas: true - datasetEnableReservation: false - datasetPermissionsMode: "0777" - datasetPermissionsUser: 0 - datasetPermissionsGroup: 0 - - # not supported yet in api - #datasetPermissionsAcls: - #- "-m everyone@:full_set:allow" - #- "-m u:kube:full_set:allow" - -smb: - shareHost: server address - nameTemplate: "" - namePrefix: "" - nameSuffix: "" - - # if any of the shareFoo parameters do not work with your version of FreeNAS - # simply comment the param (and use the configuration template if necessary) - - shareAuxiliaryConfigurationTemplate: | - #guest ok = yes - #guest only = yes - shareHome: false - shareAllowedHosts: [] - shareDeniedHosts: [] - #shareDefaultPermissions: true - shareGuestOk: true - #shareGuestOnly: true - #shareShowHiddenFiles: true - shareRecycleBin: true - shareBrowsable: false - shareAccessBasedEnumeration: true - shareTimeMachine: false - #shareStorageTask: diff --git a/examples/truenas-iscsi.yaml b/examples/truenas-iscsi.yaml new file mode 100644 index 0000000..e9fb385 --- /dev/null +++ b/examples/truenas-iscsi.yaml @@ -0,0 +1,106 @@ +# TrueNAS SCALE 25.04+ iSCSI Driver Configuration +# Uses WebSocket JSON-RPC 2.0 API (no SSH required) + +driver: truenas-iscsi +instance_id: + +# WebSocket connection to TrueNAS SCALE 25.04+ +httpConnection: + protocol: https + host: truenas.example.com + port: 443 + + # Use API key for authentication (recommended) + # Generate API key in TrueNAS UI: Settings -> API Keys + apiKey: 1-xxxxxxxxxxxxxxxxxxxxx + + # OR use username/password (less secure) + #username: root + #password: your-password + + # Allow self-signed certificates (not recommended for production) + allowInsecure: true + +# ZFS zvol configuration +zfs: + # Parent dataset for volumes (zvols) + datasetParentName: tank/k8s/volumes + + # Parent dataset for detached snapshots + # IMPORTANT: Do NOT nest these datasets - they should be siblings + detachedSnapshotsDatasetParentName: tank/k8s/snapshots + + # Enable reservations for zvols (recommended for iSCSI) + zvolEnableReservation: true + + # Compression: "" (inherit), lz4, gzip-9, etc. + zvolCompression: lz4 + + # Deduplication: "" (inherit), on, off, verify + zvolDedup: "" + + # Block size: 512, 1K, 2K, 4K, 8K, 16K, 64K, 128K (default: 16K) + zvolBlocksize: 16K + + # Set custom ZFS properties using Handlebars templates + #datasetProperties: + # "org.truenas:description": "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}/{{ parameters.[csi.storage.k8s.io/pvc/name] }}" + # "org.truenas:pvc-name": "{{ parameters.[csi.storage.k8s.io/pvc/name] }}" + +# iSCSI configuration +iscsi: + # Target portal (TrueNAS iSCSI server) + targetPortal: "truenas.example.com:3260" + + # For multipath support, specify multiple portals + targetPortals: [] + # Example: ["truenas1.example.com:3260", "truenas2.example.com:3260"] + + # iSCSI interface for iscsiadm (leave empty to omit -I flag) + interface: "" + + # Target naming + # Full IQN limit is 223 bytes, plan accordingly + # Default template is "{{ name }}" + #nameTemplate: "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}-{{ parameters.[csi.storage.k8s.io/pvc/name] }}" + namePrefix: csi- + nameSuffix: "-k8s" + + # Target groups configuration + # Add as many as needed for your storage classes + targetGroups: + # Portal Group ID from TrueNAS UI: Sharing -> iSCSI -> Portals + # NOTE: Use the DB ID, not the UI display value + - targetGroupPortalGroup: 1 + + # Initiator Group ID from TrueNAS UI: Sharing -> iSCSI -> Initiators + targetGroupInitiatorGroup: 1 + + # Authentication type: None, CHAP, or CHAP Mutual + targetGroupAuthType: None + + # Authorized Access ID (only required if using CHAP) + # From TrueNAS UI: Sharing -> iSCSI -> Authorized Access + targetGroupAuthGroup: + + # Extent configuration + # Custom comment template for extents + #extentCommentTemplate: "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}/{{ parameters.[csi.storage.k8s.io/pvc/name] }}" + + # Insecure TPC (Tape Priority Commands) + extentInsecureTpc: true + + # Xen compatibility mode + extentXenCompat: false + + # Disable physical block size reporting + extentDisablePhysicalBlocksize: true + + # Logical block size: 512, 1024, 2048, or 4096 + extentBlocksize: 512 + + # RPM: "" (let TrueNAS decide, defaults to SSD), Unknown, SSD, 5400, 7200, 10000, 15000 + extentRpm: "SSD" + + # Available space threshold (0-100, 0 = ignore) + extentAvailThreshold: 0 diff --git a/examples/truenas-nfs.yaml b/examples/truenas-nfs.yaml new file mode 100644 index 0000000..8a6f361 --- /dev/null +++ b/examples/truenas-nfs.yaml @@ -0,0 +1,65 @@ +# TrueNAS SCALE 25.04+ NFS Driver Configuration +# Uses WebSocket JSON-RPC 2.0 API (no SSH required) + +driver: truenas-nfs +instance_id: + +# WebSocket connection to TrueNAS SCALE 25.04+ +httpConnection: + protocol: https + host: truenas.example.com + port: 443 + + # Use API key for authentication (recommended) + # Generate API key in TrueNAS UI: Settings -> API Keys + apiKey: 1-xxxxxxxxxxxxxxxxxxxxx + + # OR use username/password (less secure) + #username: root + #password: your-password + + # Allow self-signed certificates (not recommended for production) + allowInsecure: true + +# ZFS dataset configuration +zfs: + # Parent dataset for volumes + datasetParentName: tank/k8s/volumes + + # Parent dataset for detached snapshots + # IMPORTANT: Do NOT nest these datasets - they should be siblings + detachedSnapshotsDatasetParentName: tank/k8s/snapshots + + # Enable quotas on datasets (recommended for NFS) + datasetEnableQuotas: true + + # Enable reservations (not recommended - wastes space) + datasetEnableReservation: false + + # Default permissions + datasetPermissionsMode: "0777" + datasetPermissionsUser: 0 + datasetPermissionsGroup: 0 + + # Set custom ZFS properties using Handlebars templates + #datasetProperties: + # "org.truenas:description": "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}/{{ parameters.[csi.storage.k8s.io/pvc/name] }}" + # "org.truenas:pvc-name": "{{ parameters.[csi.storage.k8s.io/pvc/name] }}" + +# NFS share configuration +nfs: + # NFS server hostname/IP (should match TrueNAS system) + shareHost: truenas.example.com + + # Custom share comment template + #shareCommentTemplate: "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}-{{ parameters.[csi.storage.k8s.io/pvc/name] }}" + + # NFS export options + shareAllowedHosts: [] + shareAllowedNetworks: [] + + # User/group mapping (root squashing) + shareMaprootUser: root + shareMaprootGroup: wheel + shareMapallUser: "" + shareMapallGroup: "" diff --git a/examples/truenas-nvmeof.yaml b/examples/truenas-nvmeof.yaml new file mode 100644 index 0000000..06554bb --- /dev/null +++ b/examples/truenas-nvmeof.yaml @@ -0,0 +1,99 @@ +# TrueNAS SCALE 25.04+ NVMe-oF Driver Configuration +# Uses WebSocket JSON-RPC 2.0 API (no SSH required) + +driver: truenas-nvmeof +instance_id: + +# WebSocket connection to TrueNAS SCALE 25.04+ +httpConnection: + protocol: https + host: truenas.example.com + port: 443 + + # Use API key for authentication (recommended) + # Generate API key in TrueNAS UI: Settings -> API Keys + apiKey: 1-xxxxxxxxxxxxxxxxxxxxx + + # OR use username/password (less secure) + #username: root + #password: your-password + + # Allow self-signed certificates (not recommended for production) + allowInsecure: true + +# ZFS zvol configuration +zfs: + # Parent dataset for volumes (zvols) + datasetParentName: tank/k8s/volumes + + # Parent dataset for detached snapshots + # IMPORTANT: Do NOT nest these datasets - they should be siblings + detachedSnapshotsDatasetParentName: tank/k8s/snapshots + + # Enable reservations for zvols (recommended for NVMe-oF) + zvolEnableReservation: true + + # Compression: "" (inherit), lz4, gzip-9, etc. + zvolCompression: lz4 + + # Deduplication: "" (inherit), on, off, verify + zvolDedup: "" + + # Block size: 512, 1K, 2K, 4K, 8K, 16K, 64K, 128K (default: 16K) + zvolBlocksize: 16K + + # Set custom ZFS properties using Handlebars templates + #datasetProperties: + # "org.truenas:description": "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}/{{ parameters.[csi.storage.k8s.io/pvc/name] }}" + # "org.truenas:pvc-name": "{{ parameters.[csi.storage.k8s.io/pvc/name] }}" + +# NVMe-oF configuration +nvmeof: + # NVMe-oF target address (TrueNAS NVMe-oF server) + targetAddress: truenas.example.com + + # NVMe-oF transport protocol + # Supported: tcp, rdma + transport: tcp + + # Port for NVMe-oF target (default: 4420 for TCP, 4420 for RDMA) + port: 4420 + + # NQN (NVMe Qualified Name) prefix + # Full NQN format: nqn.2014-08.org.nvmexpress:uuid: + nqnPrefix: "nqn.2014-08.com.example" + + # Subsystem naming + # Default template is "{{ name }}" + #nameTemplate: "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}-{{ parameters.[csi.storage.k8s.io/pvc/name] }}" + namePrefix: csi- + nameSuffix: "-k8s" + + # Subsystem configuration + subsystem: + # Allow any host to connect (true) or restrict to specific hosts (false) + allowAnyHost: true + + # Serial number for the subsystem (auto-generated if not specified) + #serialNumber: "" + + # Namespace configuration + namespace: + # Namespace ID (1-based, auto-assigned if not specified) + #nsid: 1 + + # UUID for the namespace (auto-generated if not specified) + #uuid: "" + + # Enable NGUID (Namespace Globally Unique Identifier) + enableNguid: true + + # Host access configuration (only used if allowAnyHost is false) + hosts: + # List of allowed host NQNs + # Example: + # - "nqn.2014-08.org.nvmexpress:uuid:12345678-1234-1234-1234-123456789abc" + # - "nqn.2014-08.org.nvmexpress:uuid:87654321-4321-4321-4321-cba987654321" + + # Custom comment template for subsystems/namespaces + #commentTemplate: "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}/{{ parameters.[csi.storage.k8s.io/pvc/name] }}" diff --git a/src/driver/factory.js b/src/driver/factory.js index 204fc46..f64e1ac 100644 --- a/src/driver/factory.js +++ b/src/driver/factory.js @@ -1,4 +1,4 @@ -const { FreeNASApiDriver } = require("./freenas/api"); +const { TrueNASApiDriver } = require("./truenas/api"); function factory(ctx, options) { switch (options.driver) { @@ -6,7 +6,7 @@ function factory(ctx, options) { case "truenas-nfs": case "truenas-iscsi": case "truenas-nvmeof": - return new FreeNASApiDriver(ctx, options); + return new TrueNASApiDriver(ctx, options); default: throw new Error("invalid csi driver: " + options.driver + ". Only truenas-nfs, truenas-iscsi, and truenas-nvmeof are supported."); } diff --git a/src/driver/freenas/api.js b/src/driver/truenas/api.js similarity index 96% rename from src/driver/freenas/api.js rename to src/driver/truenas/api.js index fdd1234..3f8cf4c 100644 --- a/src/driver/freenas/api.js +++ b/src/driver/truenas/api.js @@ -11,16 +11,16 @@ const uuidv4 = require("uuid").v4; const semver = require("semver"); // TrueNAS SCALE share properties -const FREENAS_NFS_SHARE_PROPERTY_NAME = "democratic-csi:truenas_nfs_share_id"; -const FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME = +const TRUENAS_NFS_SHARE_PROPERTY_NAME = "democratic-csi:truenas_nfs_share_id"; +const TRUENAS_ISCSI_TARGET_ID_PROPERTY_NAME = "democratic-csi:truenas_iscsi_target_id"; -const FREENAS_ISCSI_EXTENT_ID_PROPERTY_NAME = +const TRUENAS_ISCSI_EXTENT_ID_PROPERTY_NAME = "democratic-csi:truenas_iscsi_extent_id"; -const FREENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME = +const TRUENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME = "democratic-csi:truenas_iscsi_targetextent_id"; -const FREENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME = +const TRUENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME = "democratic-csi:truenas_nvmeof_subsystem_id"; -const FREENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME = +const TRUENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME = "democratic-csi:truenas_nvmeof_namespace_id"; // zfs common properties @@ -44,9 +44,9 @@ const VOLUME_CONTEXT_PROVISIONER_DRIVER_PROPERTY_NAME = const VOLUME_CONTEXT_PROVISIONER_INSTANCE_ID_PROPERTY_NAME = "democratic-csi:volume_context_provisioner_instance_id"; -const __REGISTRY_NS__ = "FreeNASApiDriver"; +const __REGISTRY_NS__ = "TrueNASApiDriver"; -class FreeNASApiDriver extends CsiBaseDriver { +class TrueNASApiDriver extends CsiBaseDriver { constructor(ctx, options) { super(...arguments); @@ -218,13 +218,13 @@ class FreeNASApiDriver extends CsiBaseDriver { // Get dataset properties const properties = await httpApiClient.DatasetGet(datasetName, [ "mountpoint", - FREENAS_NFS_SHARE_PROPERTY_NAME, + TRUENAS_NFS_SHARE_PROPERTY_NAME, ]); this.ctx.logger.debug("Dataset properties: %j", properties); const mountpoint = properties.mountpoint.value; - const shareId = properties[FREENAS_NFS_SHARE_PROPERTY_NAME].value; + const shareId = properties[TRUENAS_NFS_SHARE_PROPERTY_NAME].value; // Check if share already exists if (!zb.helpers.isPropertyValueSet(shareId)) { @@ -270,7 +270,7 @@ class FreeNASApiDriver extends CsiBaseDriver { // Store share ID in ZFS property await httpApiClient.DatasetSet(datasetName, { - [FREENAS_NFS_SHARE_PROPERTY_NAME]: share.id, + [TRUENAS_NFS_SHARE_PROPERTY_NAME]: share.id, }); } catch (error) { // Check if share already exists for this path @@ -287,7 +287,7 @@ class FreeNASApiDriver extends CsiBaseDriver { // Store existing share ID await httpApiClient.DatasetSet(datasetName, { - [FREENAS_NFS_SHARE_PROPERTY_NAME]: existingShare.id, + [TRUENAS_NFS_SHARE_PROPERTY_NAME]: existingShare.id, }); } else { throw new GrpcError( @@ -313,14 +313,14 @@ class FreeNASApiDriver extends CsiBaseDriver { // Get dataset properties const properties = await httpApiClient.DatasetGet(datasetName, [ "name", - FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME, - FREENAS_ISCSI_EXTENT_ID_PROPERTY_NAME, - FREENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME, + TRUENAS_ISCSI_TARGET_ID_PROPERTY_NAME, + TRUENAS_ISCSI_EXTENT_ID_PROPERTY_NAME, + TRUENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME, ]); - const targetId = properties[FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME].value; - const extentId = properties[FREENAS_ISCSI_EXTENT_ID_PROPERTY_NAME].value; - const targetExtentId = properties[FREENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME].value; + const targetId = properties[TRUENAS_ISCSI_TARGET_ID_PROPERTY_NAME].value; + const extentId = properties[TRUENAS_ISCSI_EXTENT_ID_PROPERTY_NAME].value; + const targetExtentId = properties[TRUENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME].value; // Check if already fully configured if (zb.helpers.isPropertyValueSet(targetExtentId)) { @@ -366,7 +366,7 @@ class FreeNASApiDriver extends CsiBaseDriver { this.ctx.logger.info(`iSCSI target created with ID: ${target.id}`); await httpApiClient.DatasetSet(datasetName, { - [FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME]: target.id, + [TRUENAS_ISCSI_TARGET_ID_PROPERTY_NAME]: target.id, }); } catch (error) { if (error.message && error.message.includes("already exists")) { @@ -375,7 +375,7 @@ class FreeNASApiDriver extends CsiBaseDriver { if (targets && targets.length > 0) { target = targets[0]; await httpApiClient.DatasetSet(datasetName, { - [FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME]: target.id, + [TRUENAS_ISCSI_TARGET_ID_PROPERTY_NAME]: target.id, }); } else { throw new GrpcError( @@ -436,7 +436,7 @@ class FreeNASApiDriver extends CsiBaseDriver { this.ctx.logger.info(`iSCSI extent created with ID: ${extent.id}`); await httpApiClient.DatasetSet(datasetName, { - [FREENAS_ISCSI_EXTENT_ID_PROPERTY_NAME]: extent.id, + [TRUENAS_ISCSI_EXTENT_ID_PROPERTY_NAME]: extent.id, }); } catch (error) { if (error.message && error.message.includes("already exists")) { @@ -445,7 +445,7 @@ class FreeNASApiDriver extends CsiBaseDriver { if (extents && extents.length > 0) { extent = extents[0]; await httpApiClient.DatasetSet(datasetName, { - [FREENAS_ISCSI_EXTENT_ID_PROPERTY_NAME]: extent.id, + [TRUENAS_ISCSI_EXTENT_ID_PROPERTY_NAME]: extent.id, }); } else { throw new GrpcError( @@ -463,12 +463,12 @@ class FreeNASApiDriver extends CsiBaseDriver { if (!zb.helpers.isPropertyValueSet(targetExtentId)) { // Get current target and extent IDs from properties const currentProps = await httpApiClient.DatasetGet(datasetName, [ - FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME, - FREENAS_ISCSI_EXTENT_ID_PROPERTY_NAME, + TRUENAS_ISCSI_TARGET_ID_PROPERTY_NAME, + TRUENAS_ISCSI_EXTENT_ID_PROPERTY_NAME, ]); - const finalTargetId = currentProps[FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME].value; - const finalExtentId = currentProps[FREENAS_ISCSI_EXTENT_ID_PROPERTY_NAME].value; + const finalTargetId = currentProps[TRUENAS_ISCSI_TARGET_ID_PROPERTY_NAME].value; + const finalExtentId = currentProps[TRUENAS_ISCSI_EXTENT_ID_PROPERTY_NAME].value; const targetExtentConfig = { target: parseInt(finalTargetId), @@ -480,16 +480,16 @@ class FreeNASApiDriver extends CsiBaseDriver { this.ctx.logger.info(`iSCSI target-extent created with ID: ${targetExtent.id}`); await httpApiClient.DatasetSet(datasetName, { - [FREENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME]: targetExtent.id, + [TRUENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME]: targetExtent.id, }); } } // Get final target name for volume context const finalProps = await httpApiClient.DatasetGet(datasetName, [ - FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME, + TRUENAS_ISCSI_TARGET_ID_PROPERTY_NAME, ]); - const finalTargetId = finalProps[FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME].value; + const finalTargetId = finalProps[TRUENAS_ISCSI_TARGET_ID_PROPERTY_NAME].value; const targets = await httpApiClient.ISCSITargetQuery([["id", "=", parseInt(finalTargetId)]]); const targetName = targets[0].name; @@ -514,12 +514,12 @@ class FreeNASApiDriver extends CsiBaseDriver { // Get dataset properties const properties = await httpApiClient.DatasetGet(datasetName, [ "name", - FREENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME, - FREENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME, + TRUENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME, + TRUENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME, ]); - const subsystemId = properties[FREENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME].value; - const namespaceId = properties[FREENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME].value; + const subsystemId = properties[TRUENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME].value; + const namespaceId = properties[TRUENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME].value; // Check if already fully configured if (zb.helpers.isPropertyValueSet(namespaceId)) { @@ -560,7 +560,7 @@ class FreeNASApiDriver extends CsiBaseDriver { this.ctx.logger.info(`NVMe-oF subsystem created with ID: ${subsystem.id}`); await httpApiClient.DatasetSet(datasetName, { - [FREENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME]: subsystem.id, + [TRUENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME]: subsystem.id, }); } catch (error) { if (error.message && error.message.includes("already exists")) { @@ -569,7 +569,7 @@ class FreeNASApiDriver extends CsiBaseDriver { if (subsystems && subsystems.length > 0) { subsystem = subsystems[0]; await httpApiClient.DatasetSet(datasetName, { - [FREENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME]: subsystem.id, + [TRUENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME]: subsystem.id, }); } else { throw new GrpcError( @@ -586,9 +586,9 @@ class FreeNASApiDriver extends CsiBaseDriver { // Create namespace if (!zb.helpers.isPropertyValueSet(namespaceId)) { const currentProps = await httpApiClient.DatasetGet(datasetName, [ - FREENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME, + TRUENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME, ]); - const finalSubsystemId = currentProps[FREENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME].value; + const finalSubsystemId = currentProps[TRUENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME].value; const namespacePath = `/dev/zvol/${datasetName}`; @@ -602,16 +602,16 @@ class FreeNASApiDriver extends CsiBaseDriver { this.ctx.logger.info(`NVMe-oF namespace created with ID: ${namespace.id}`); await httpApiClient.DatasetSet(datasetName, { - [FREENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME]: namespace.id, + [TRUENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME]: namespace.id, }); } } // Get final subsystem NQN for volume context const finalProps = await httpApiClient.DatasetGet(datasetName, [ - FREENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME, + TRUENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME, ]); - const finalSubsystemId = finalProps[FREENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME].value; + const finalSubsystemId = finalProps[TRUENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME].value; const subsystems = await httpApiClient.NVMeOFSubsystemQuery([["id", "=", parseInt(finalSubsystemId)]]); const subsystemNqn = subsystems[0].nqn; @@ -677,10 +677,10 @@ class FreeNASApiDriver extends CsiBaseDriver { async deleteNFSShare(datasetName, httpApiClient, zb) { try { const properties = await httpApiClient.DatasetGet(datasetName, [ - FREENAS_NFS_SHARE_PROPERTY_NAME, + TRUENAS_NFS_SHARE_PROPERTY_NAME, ]); - const shareId = properties[FREENAS_NFS_SHARE_PROPERTY_NAME].value; + const shareId = properties[TRUENAS_NFS_SHARE_PROPERTY_NAME].value; if (zb.helpers.isPropertyValueSet(shareId)) { this.ctx.logger.debug(`Deleting NFS share ID: ${shareId}`); @@ -689,7 +689,7 @@ class FreeNASApiDriver extends CsiBaseDriver { // Remove property await httpApiClient.DatasetInherit( datasetName, - FREENAS_NFS_SHARE_PROPERTY_NAME + TRUENAS_NFS_SHARE_PROPERTY_NAME ); } } catch (error) { @@ -706,14 +706,14 @@ class FreeNASApiDriver extends CsiBaseDriver { async deleteISCSIShare(datasetName, httpApiClient, zb) { try { const properties = await httpApiClient.DatasetGet(datasetName, [ - FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME, - FREENAS_ISCSI_EXTENT_ID_PROPERTY_NAME, - FREENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME, + TRUENAS_ISCSI_TARGET_ID_PROPERTY_NAME, + TRUENAS_ISCSI_EXTENT_ID_PROPERTY_NAME, + TRUENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME, ]); - const targetId = properties[FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME].value; - const extentId = properties[FREENAS_ISCSI_EXTENT_ID_PROPERTY_NAME].value; - const targetExtentId = properties[FREENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME].value; + const targetId = properties[TRUENAS_ISCSI_TARGET_ID_PROPERTY_NAME].value; + const extentId = properties[TRUENAS_ISCSI_EXTENT_ID_PROPERTY_NAME].value; + const targetExtentId = properties[TRUENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME].value; // Delete target-extent association first if (zb.helpers.isPropertyValueSet(targetExtentId)) { @@ -721,7 +721,7 @@ class FreeNASApiDriver extends CsiBaseDriver { await httpApiClient.ISCSITargetExtentDelete(parseInt(targetExtentId), true); await httpApiClient.DatasetInherit( datasetName, - FREENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME + TRUENAS_ISCSI_TARGETTOEXTENT_ID_PROPERTY_NAME ); } @@ -731,7 +731,7 @@ class FreeNASApiDriver extends CsiBaseDriver { await httpApiClient.ISCSIExtentDelete(parseInt(extentId), false, true); await httpApiClient.DatasetInherit( datasetName, - FREENAS_ISCSI_EXTENT_ID_PROPERTY_NAME + TRUENAS_ISCSI_EXTENT_ID_PROPERTY_NAME ); } @@ -741,7 +741,7 @@ class FreeNASApiDriver extends CsiBaseDriver { await httpApiClient.ISCSITargetDelete(parseInt(targetId), true); await httpApiClient.DatasetInherit( datasetName, - FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME + TRUENAS_ISCSI_TARGET_ID_PROPERTY_NAME ); } } catch (error) { @@ -758,12 +758,12 @@ class FreeNASApiDriver extends CsiBaseDriver { async deleteNVMeOFShare(datasetName, httpApiClient, zb) { try { const properties = await httpApiClient.DatasetGet(datasetName, [ - FREENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME, - FREENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME, + TRUENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME, + TRUENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME, ]); - const subsystemId = properties[FREENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME].value; - const namespaceId = properties[FREENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME].value; + const subsystemId = properties[TRUENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME].value; + const namespaceId = properties[TRUENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME].value; // Delete namespace first if (zb.helpers.isPropertyValueSet(namespaceId)) { @@ -771,7 +771,7 @@ class FreeNASApiDriver extends CsiBaseDriver { await httpApiClient.NVMeOFNamespaceDelete(parseInt(namespaceId)); await httpApiClient.DatasetInherit( datasetName, - FREENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME + TRUENAS_NVMEOF_NAMESPACE_ID_PROPERTY_NAME ); } @@ -781,7 +781,7 @@ class FreeNASApiDriver extends CsiBaseDriver { await httpApiClient.NVMeOFSubsystemDelete(parseInt(subsystemId)); await httpApiClient.DatasetInherit( datasetName, - FREENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME + TRUENAS_NVMEOF_SUBSYSTEM_ID_PROPERTY_NAME ); } } catch (error) { @@ -927,13 +927,10 @@ class FreeNASApiDriver extends CsiBaseDriver { */ getDriverZfsResourceType() { switch (this.options.driver) { - case "freenas-api-nfs": - case "truenas-api-nfs": - case "freenas-api-smb": - case "truenas-api-smb": + case "truenas-nfs": return "filesystem"; - case "freenas-api-iscsi": - case "truenas-api-iscsi": + case "truenas-iscsi": + case "truenas-nvmeof": return "volume"; default: throw new Error("unknown driver: " + this.ctx.args.driver); @@ -942,15 +939,12 @@ class FreeNASApiDriver extends CsiBaseDriver { getDriverShareType() { switch (this.options.driver) { - case "freenas-api-nfs": - case "truenas-api-nfs": + case "truenas-nfs": return "nfs"; - case "freenas-api-smb": - case "truenas-api-smb": - return "smb"; - case "freenas-api-iscsi": - case "truenas-api-iscsi": + case "truenas-iscsi": return "iscsi"; + case "truenas-nvmeof": + return "nvmeof"; default: throw new Error("unknown driver: " + this.ctx.args.driver); } @@ -3416,4 +3410,4 @@ class FreeNASApiDriver extends CsiBaseDriver { } } -module.exports.FreeNASApiDriver = FreeNASApiDriver; +module.exports.TrueNASApiDriver = TrueNASApiDriver; diff --git a/src/driver/freenas/http/api.js b/src/driver/truenas/http/api.js similarity index 99% rename from src/driver/freenas/http/api.js rename to src/driver/truenas/http/api.js index fc444f7..e63ba4a 100644 --- a/src/driver/freenas/http/api.js +++ b/src/driver/truenas/http/api.js @@ -10,7 +10,7 @@ const __REGISTRY_NS__ = "TrueNASWebSocketApi"; * This class provides a clean interface to TrueNAS SCALE 25.04+ API * using WebSocket JSON-RPC 2.0 protocol only. * - * All legacy support for FreeNAS and old TrueNAS versions has been removed. + * All legacy support for TrueNAS and old TrueNAS versions has been removed. * * API Documentation: https://api.truenas.com/v25.04.2/ */ diff --git a/src/driver/freenas/http/index.js b/src/driver/truenas/http/index.js similarity index 100% rename from src/driver/freenas/http/index.js rename to src/driver/truenas/http/index.js