Docs
News
Merch/Store
Democratic CSI is a multi-platform CSI, mostly using either local or network (NFS/iSCSI) based storage.
Their Helm-Chart is available at: https://democratic-csi.github.io/charts/ All below examples, are based on their Helm-Chart
csiDriver: name: "nfs"storageClasses:- name: nfs defaultClass: true reclaimPolicy: Delete volumeBindingMode: Immediate allowVolumeExpansion: true parameters: fsType: nfs detachedVolumesFromSnapshots: "false" secrets: provisioner-secret: controller-publish-secret: node-stage-secret: node-publish-secret: controller-expand-secret:# if you want to use snapshotsvolumeSnapshotClasses:- name: nfs-snapshot parameters: detachedSnapshots: "true"driver: config: driver: freenas-api-nfs instance_id: httpConnection: protocol: http host: ${CONFIG_TRUENAS_IP} port: 81 allowInsecure: true apiKey: ${TRUENAS_API_KEY} zfs: datasetParentName: ${PATH TO YOUR PARENT SHARE} detachedSnapshotsDatasetParentName: ${PATH TO YOUR PARENT SNAPSHOT SHARE} datasetEnableQuotas: true datasetEnableReservation: false datasetPermissionsMode: "0770" datasetPermissionsUser: 0 datasetPermissionsGroup: 0 nfs: shareHost: ${CONFIG_TRUENAS_IP} shareAlldirs: false shareAllowedHosts: [] shareAllowedNetworks: [] shareMaprootUser: root shareMaprootGroup: root shareMapallUser: "" shareMapallGroup: ""
csiDriver: name: "iscsi"storageClasses: - name: iscsi defaultClass: true reclaimPolicy: Delete volumeBindingMode: Immediate allowVolumeExpansion: true parameters: fsType: ext4 detachedVolumesFromSnapshots: "false" mountOptions: [] secrets: provisioner-secret: controller-publish-secret: node-stage-secret: node-publish-secret: controller-expand-secret:volumeSnapshotClasses: - name: iscsi parameters: detachedSnapshots: "true"driver: config: driver: freenas-api-iscsi instance_id: httpConnection: protocol: http host: ${TRUENAS_IP} port: 81 allowInsecure: true apiKey: ${SECRET_TRUENAS_API} zfs: datasetParentName: ${PATH TO YOUR PARENT SHARE} detachedSnapshotsDatasetParentName: ${PATH TO YOUR PARENT SNAPSHOT SHARE} zvolCompression: zvolDedup: zvolEnableReservation: false zvolBlocksize: iscsi: targetPortal: "${TRUENAS_IP}:3260" interface: namePrefix: csi- nameSuffix: "-talos" targetGroups: - targetGroupPortalGroup: 1 targetGroupInitiatorGroup: 1 targetGroupAuthType: None targetGroupAuthGroup: extentInsecureTpc: true extentXenCompat: false extentDisablePhysicalBlocksize: true extentBlocksize: 512 extentRpm: "SSD" extentAvailThreshold: 0"
Due to flaws in TrueNAS SCALE, this script needs to run each day est. 20min after volsync cycle to clear stuck jobs. (Truenas Cronjob)
from datetime import datetime, timedelta, timezonefrom truenas_api_client import Clientimport subprocess def main(): # Initialize Middleware Client middleware = Client() try: # Get current time as a timezone-aware datetime in UTC current_time = datetime.now(timezone.utc) ten_minutes_ago = current_time - timedelta(minutes=10) filters = [ ['state', '=', 'RUNNING'], ['method', '=', 'replication.run_onetime'], ['progress.description', '=', ''] ] jobs = middleware.call('core.get_jobs', filters) for job in jobs: start_time = job['time_started'] # Check if the job started more than 10 minutes ago if start_time <= ten_minutes_ago: job_id = job['id'] start_time_formatted = start_time.strftime("%d %B %Y %H:%M:%S") running_time = current_time - start_time running_time_minutes = running_time.total_seconds() // 60.0 print(f'{job_id}') print(f'- Started: {start_time_formatted}') print(f'- Runtime: {running_time_minutes}m') print(f'- Aborting: {job_id}') # Abort the job abort_result = middleware.call('core.job_abort', job_id) if abort_result is None: print(f"-- Success") else: print(f"-- Failed") # Parse and format target dataset path target_dataset = job['arguments'][0]['target_dataset'] target_dataset = target_dataset.rsplit('/snapshot-', 1)[0] print(f'- Destroying ZFS dataset "{target_dataset}"') # Quote dataset path, in case it contains spaces destroy_command = f'zfs destroy "{target_dataset}"' # Destroy the ZFS dataset destroy_result = subprocess.run(destroy_command, capture_output=True, shell=True) if destroy_result.returncode == 0: print(f"-- Success") else: print(f"-- Failed") print("") finally: # Close the middleware client connection middleware.close() if __name__ == "__main__": main()
Other resource for guidance: https://github.com/fenio/k8s-truenas