smb support

This commit is contained in:
Travis Glenn Hansen 2020-09-12 12:58:51 -06:00
parent 5ae0248ba8
commit 8c0d67a56e
8 changed files with 77 additions and 35 deletions

View File

@ -14,6 +14,7 @@ have access to resizing, snapshots, clones, etc functionality.
- several implementations of `csi` drivers - several implementations of `csi` drivers
- `freenas-nfs` (manages zfs datasets to share over nfs) - `freenas-nfs` (manages zfs datasets to share over nfs)
- `freenas-iscsi` (manages zfs zvols to share over iscsi) - `freenas-iscsi` (manages zfs zvols to share over iscsi)
- `freenas-smb` (manages zfs datasets to share over smb)
- `zfs-generic-nfs` (works with any ZoL installation...ie: Ubuntu) - `zfs-generic-nfs` (works with any ZoL installation...ie: Ubuntu)
- `zfs-generic-iscsi` (works with any ZoL installation...ie: Ubuntu) - `zfs-generic-iscsi` (works with any ZoL installation...ie: Ubuntu)
- `zfs-local-ephemeral-inline` (provisions node-local zfs datasets) - `zfs-local-ephemeral-inline` (provisions node-local zfs datasets)
@ -43,6 +44,16 @@ If you are running Kubernetes with rancher/rke please see the following:
- https://github.com/rancher/rke/issues/1846 - https://github.com/rancher/rke/issues/1846
### freenas-smb
If using with Windows based machines you may need to enable guest access (even
if you are connecting with credentiasl)
```
Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters AllowInsecureGuestAuth -Value 1
Restart-Service LanmanWorkstation -Force
```
### zfs-local-ephemeral-inline ### zfs-local-ephemeral-inline
This `driver` provisions node-local ephemeral storage on a per-pod basis. Each This `driver` provisions node-local ephemeral storage on a per-pod basis. Each
@ -58,13 +69,15 @@ necessary.
Server preparation depends slightly on which `driver` you are using. Server preparation depends slightly on which `driver` you are using.
### FreeNAS (freenas-nfs, freenas-iscsi) ### FreeNAS (freenas-nfs, freenas-iscsi, freenas-smb)
Ensure the following services are configurged and running: Ensure the following services are configurged and running:
- ssh (if you use a password for authentication make sure it is allowed) - ssh (if you use a password for authentication make sure it is allowed)
- ensure `zsh`, `bash`, or `sh` is set as the root shell, `csh` gives false errors due to quoting
- nfs - nfs
- iscsi - iscsi
- smb
### ZoL (zfs-generic-nfs, zfs-generic-iscsi) ### ZoL (zfs-generic-nfs, zfs-generic-iscsi)

View File

@ -41,6 +41,10 @@ zfs:
datasetPermissionsMode: "0777" datasetPermissionsMode: "0777"
datasetPermissionsUser: root datasetPermissionsUser: root
datasetPermissionsGroup: wheel datasetPermissionsGroup: wheel
#datasetPermissionsAcls:
#- "-m everyone@:full_set:allow"
#- "-m u:kube:full_set:allow"
nfs: nfs:
shareHost: server address shareHost: server address
shareAlldirs: false shareAlldirs: false

View File

@ -38,6 +38,10 @@ zfs:
datasetPermissionsMode: "0777" datasetPermissionsMode: "0777"
datasetPermissionsUser: root datasetPermissionsUser: root
datasetPermissionsGroup: root datasetPermissionsGroup: root
#datasetPermissionsAcls:
#- "-m everyone@:full_set:allow"
#- "-m u:kube:full_set:allow"
nfs: nfs:
# https://docs.oracle.com/cd/E23824_01/html/821-1448/gayne.html # 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/ # https://www.hiroom2.com/2016/05/18/ubuntu-16-04-share-zfs-storage-via-nfs-smb/

View File

@ -696,6 +696,7 @@ class ControllerZfsSshBaseDriver extends CsiBaseDriver {
// set acls // set acls
// TODO: this is unsfafe approach, make it better // TODO: this is unsfafe approach, make it better
// probably could see if ^-.*\s and split and then shell escape
if (this.options.zfs.datasetPermissionsAcls) { if (this.options.zfs.datasetPermissionsAcls) {
for (const acl of this.options.zfs.datasetPermissionsAcls) { for (const acl of this.options.zfs.datasetPermissionsAcls) {
command = sshClient.buildCommand("setfacl", [ command = sshClient.buildCommand("setfacl", [

View File

@ -45,12 +45,12 @@ class FreeNASDriver extends ControllerZfsSshBaseDriver {
case "freenas-nfs": case "freenas-nfs":
case "truenas-nfs": case "truenas-nfs":
return "nfs"; return "nfs";
case "freenas-iscsi":
case "truenas-iscsi":
return "iscsi";
case "freenas-smb": case "freenas-smb":
case "truenas-smb": case "truenas-smb":
return "smb"; return "smb";
case "freenas-iscsi":
case "truenas-iscsi":
return "iscsi";
default: default:
throw new Error("unknown driver: " + this.ctx.args.driver); throw new Error("unknown driver: " + this.ctx.args.driver);
} }
@ -301,7 +301,7 @@ class FreeNASDriver extends ControllerZfsSshBaseDriver {
}; };
let propertyMapping = { let propertyMapping = {
shareTemplate: "auxsmbconf", shareAuxiliaryConfigurationTemplate: "auxsmbconf",
shareHome: "home", shareHome: "home",
shareAllowedHosts: "hostsallow", shareAllowedHosts: "hostsallow",
shareDeniedHosts: "hostsdeny", shareDeniedHosts: "hostsdeny",
@ -320,9 +320,9 @@ class FreeNASDriver extends ControllerZfsSshBaseDriver {
if (this.options.smb.hasOwnProperty(key)) { if (this.options.smb.hasOwnProperty(key)) {
let value; let value;
switch (key) { switch (key) {
case "shareTemplate": case "shareAuxiliaryConfigurationTemplate":
value = Handlebars.compile( value = Handlebars.compile(
this.options.smb.shareTemplate this.options.smb.shareAuxiliaryConfigurationTemplate
)({ )({
name: call.request.name, name: call.request.name,
parameters: call.request.parameters, parameters: call.request.parameters,

View File

@ -272,9 +272,19 @@ class CsiBaseDriver {
const bind_mount_flags = []; const bind_mount_flags = [];
bind_mount_flags.push("defaults"); bind_mount_flags.push("defaults");
const normalizedSecrets = this.getNormalizedParameters(
call.request.secrets,
call.request.volume_context.provisioner_driver,
call.request.volume_context.provisioner_driver_instance_id
);
if (access_type == "mount") { if (access_type == "mount") {
fs_type = capability.mount.fs_type; fs_type = capability.mount.fs_type;
mount_flags = capability.mount.mount_flags || []; mount_flags = capability.mount.mount_flags || [];
// add secrets mount_flags
if (normalizedSecrets.mount_flags) {
mount_flags.push(normalizedSecrets.mount_flags);
}
mount_flags.push("defaults"); mount_flags.push("defaults");
} }
@ -307,11 +317,6 @@ class CsiBaseDriver {
"node.startup": "manual", "node.startup": "manual",
}; };
const nodeDBKeyPrefix = "node-db."; const nodeDBKeyPrefix = "node-db.";
const normalizedSecrets = this.getNormalizedParameters(
call.request.secrets,
call.request.volume_context.provisioner_driver,
call.request.volume_context.provisioner_driver_instance_id
);
for (const key in normalizedSecrets) { for (const key in normalizedSecrets) {
if (key.startsWith(nodeDBKeyPrefix)) { if (key.startsWith(nodeDBKeyPrefix)) {
nodeDB[key.substr(nodeDBKeyPrefix.length)] = normalizedSecrets[key]; nodeDB[key.substr(nodeDBKeyPrefix.length)] = normalizedSecrets[key];
@ -355,6 +360,9 @@ class CsiBaseDriver {
switch (access_type) { switch (access_type) {
case "mount": case "mount":
switch (node_attach_driver) {
// block specific logic
case "iscsi":
if (await filesystem.isBlockDevice(device)) { if (await filesystem.isBlockDevice(device)) {
// format // format
result = await filesystem.deviceIsFormatted(device); result = await filesystem.deviceIsFormatted(device);
@ -374,6 +382,10 @@ class CsiBaseDriver {
await filesystem.checkFilesystem(device, fs_type); await filesystem.checkFilesystem(device, fs_type);
} }
} }
break;
default:
break;
}
result = await mount.deviceIsMountedAtPath(device, staging_target_path); result = await mount.deviceIsMountedAtPath(device, staging_target_path);
if (!result) { if (!result) {
@ -614,6 +626,7 @@ class CsiBaseDriver {
switch (node_attach_driver) { switch (node_attach_driver) {
case "nfs": case "nfs":
case "smb":
case "iscsi": case "iscsi":
// ensure appropriate directories/files // ensure appropriate directories/files
switch (access_type) { switch (access_type) {

View File

@ -22,7 +22,7 @@ class Filesystem {
if (!options.executor) { if (!options.executor) {
options.executor = { options.executor = {
spawn: cp.spawn spawn: cp.spawn,
}; };
} }
} }
@ -35,13 +35,20 @@ class Filesystem {
async isBlockDevice(device) { async isBlockDevice(device) {
const filesystem = this; const filesystem = this;
// nfs paths
if (!device.startsWith("/")) { if (!device.startsWith("/")) {
return false; return false;
} }
// smb paths
if (device.startsWith("//")) {
return false;
}
const device_path = await filesystem.realpath(device); const device_path = await filesystem.realpath(device);
const blockdevices = await filesystem.getAllBlockDevices(); const blockdevices = await filesystem.getAllBlockDevices();
return blockdevices.some(i => { return blockdevices.some((i) => {
if (i.path == device_path) { if (i.path == device_path) {
return true; return true;
} }
@ -192,7 +199,7 @@ class Filesystem {
const entries = result.stdout.trim().split("\n"); const entries = result.stdout.trim().split("\n");
const properties = {}; const properties = {};
let fields, key, value; let fields, key, value;
entries.forEach(entry => { entries.forEach((entry) => {
fields = entry.split("="); fields = entry.split("=");
key = fields[0].toLowerCase(); key = fields[0].toLowerCase();
value = fields[1]; value = fields[1];
@ -440,15 +447,15 @@ class Filesystem {
} }
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
child.stdout.on("data", function(data) { child.stdout.on("data", function (data) {
stdout = stdout + data; stdout = stdout + data;
}); });
child.stderr.on("data", function(data) { child.stderr.on("data", function (data) {
stderr = stderr + data; stderr = stderr + data;
}); });
child.on("close", function(code) { child.on("close", function (code) {
const result = { code, stdout, stderr }; const result = { code, stdout, stderr };
if (timeout) { if (timeout) {
clearTimeout(timeout); clearTimeout(timeout);

View File

@ -111,7 +111,7 @@ class Mount {
*/ */
async deviceIsMountedAtPath(device, path) { async deviceIsMountedAtPath(device, path) {
const filesystem = new Filesystem(); const filesystem = new Filesystem();
if (device.startsWith("/")) { if (device.startsWith("/") && !device.startsWith("//")) {
device = await filesystem.realpath(device); device = await filesystem.realpath(device);
} }