smb support
This commit is contained in:
parent
5ae0248ba8
commit
8c0d67a56e
15
README.md
15
README.md
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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/
|
||||||
|
|
|
||||||
|
|
@ -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", [
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue