preview support for cifs/smb
This commit is contained in:
parent
f5ba51c9b8
commit
5ae0248ba8
|
|
@ -116,7 +116,7 @@ You may install multiple deployments of each/any driver. It requires the followi
|
||||||
|
|
||||||
Install beta (v1.17+) CRDs (once per cluster):
|
Install beta (v1.17+) CRDs (once per cluster):
|
||||||
|
|
||||||
- https://github.com/kubernetes-csi/external-snapshotter/tree/master/config/crd
|
- https://github.com/kubernetes-csi/external-snapshotter/tree/master/client/config/crd
|
||||||
|
|
||||||
```
|
```
|
||||||
kubectl apply -f snapshot.storage.k8s.io_volumesnapshotclasses.yaml
|
kubectl apply -f snapshot.storage.k8s.io_volumesnapshotclasses.yaml
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ class ControllerZfsSshBaseDriver extends CsiBaseDriver {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
capability.mount.fs_type &&
|
capability.mount.fs_type &&
|
||||||
!["nfs"].includes(capability.mount.fs_type)
|
!["nfs", "cifs"].includes(capability.mount.fs_type)
|
||||||
) {
|
) {
|
||||||
message = `invalid fs_type ${capability.mount.fs_type}`;
|
message = `invalid fs_type ${capability.mount.fs_type}`;
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -694,9 +694,21 @@ class ControllerZfsSshBaseDriver extends CsiBaseDriver {
|
||||||
response = await sshClient.exec(command);
|
response = await sshClient.exec(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set acls
|
||||||
|
// TODO: this is unsfafe approach, make it better
|
||||||
|
if (this.options.zfs.datasetPermissionsAcls) {
|
||||||
|
for (const acl of this.options.zfs.datasetPermissionsAcls) {
|
||||||
|
command = sshClient.buildCommand("setfacl", [
|
||||||
|
acl,
|
||||||
|
properties.mountpoint.value,
|
||||||
|
]);
|
||||||
|
driver.ctx.logger.verbose("set acl command: %s", command);
|
||||||
|
response = await sshClient.exec(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "volume":
|
case "volume":
|
||||||
// TODO: create all the necessary iscsi stuff
|
|
||||||
// set properties
|
// set properties
|
||||||
// set reserve
|
// set reserve
|
||||||
setProps = true;
|
setProps = true;
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,10 @@ const { ControllerNfsClientDriver } = require("./controller-nfs-client");
|
||||||
function factory(ctx, options) {
|
function factory(ctx, options) {
|
||||||
switch (options.driver) {
|
switch (options.driver) {
|
||||||
case "freenas-nfs":
|
case "freenas-nfs":
|
||||||
|
case "freenas-smb":
|
||||||
case "freenas-iscsi":
|
case "freenas-iscsi":
|
||||||
case "truenas-nfs":
|
case "truenas-nfs":
|
||||||
|
case "truenas-smb":
|
||||||
case "truenas-iscsi":
|
case "truenas-iscsi":
|
||||||
return new FreeNASDriver(ctx, options);
|
return new FreeNASDriver(ctx, options);
|
||||||
case "zfs-generic-nfs":
|
case "zfs-generic-nfs":
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ const Handlebars = require("handlebars");
|
||||||
|
|
||||||
// freenas properties
|
// freenas properties
|
||||||
const FREENAS_NFS_SHARE_PROPERTY_NAME = "democratic-csi:freenas_nfs_share_id";
|
const FREENAS_NFS_SHARE_PROPERTY_NAME = "democratic-csi:freenas_nfs_share_id";
|
||||||
|
const FREENAS_SMB_SHARE_PROPERTY_NAME = "democratic-csi:freenas_smb_share_id";
|
||||||
const FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME =
|
const FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME =
|
||||||
"democratic-csi:freenas_iscsi_target_id";
|
"democratic-csi:freenas_iscsi_target_id";
|
||||||
const FREENAS_ISCSI_EXTENT_ID_PROPERTY_NAME =
|
const FREENAS_ISCSI_EXTENT_ID_PROPERTY_NAME =
|
||||||
|
|
@ -22,6 +23,8 @@ class FreeNASDriver extends ControllerZfsSshBaseDriver {
|
||||||
switch (this.options.driver) {
|
switch (this.options.driver) {
|
||||||
case "freenas-nfs":
|
case "freenas-nfs":
|
||||||
case "truenas-nfs":
|
case "truenas-nfs":
|
||||||
|
case "freenas-smb":
|
||||||
|
case "truenas-smb":
|
||||||
return "filesystem";
|
return "filesystem";
|
||||||
case "freenas-iscsi":
|
case "freenas-iscsi":
|
||||||
case "truenas-iscsi":
|
case "truenas-iscsi":
|
||||||
|
|
@ -45,6 +48,9 @@ class FreeNASDriver extends ControllerZfsSshBaseDriver {
|
||||||
case "freenas-iscsi":
|
case "freenas-iscsi":
|
||||||
case "truenas-iscsi":
|
case "truenas-iscsi":
|
||||||
return "iscsi";
|
return "iscsi";
|
||||||
|
case "freenas-smb":
|
||||||
|
case "truenas-smb":
|
||||||
|
return "smb";
|
||||||
default:
|
default:
|
||||||
throw new Error("unknown driver: " + this.ctx.args.driver);
|
throw new Error("unknown driver: " + this.ctx.args.driver);
|
||||||
}
|
}
|
||||||
|
|
@ -123,6 +129,7 @@ class FreeNASDriver extends ControllerZfsSshBaseDriver {
|
||||||
const zb = this.getZetabyte();
|
const zb = this.getZetabyte();
|
||||||
|
|
||||||
let properties;
|
let properties;
|
||||||
|
let endpoint;
|
||||||
let response;
|
let response;
|
||||||
let share = {};
|
let share = {};
|
||||||
|
|
||||||
|
|
@ -207,7 +214,9 @@ class FreeNASDriver extends ControllerZfsSshBaseDriver {
|
||||||
} else {
|
} else {
|
||||||
throw new GrpcError(
|
throw new GrpcError(
|
||||||
grpc.status.UNKNOWN,
|
grpc.status.UNKNOWN,
|
||||||
`received error creating nfs share - code: ${response.statusCode} body: ${response.body}`
|
`received error creating nfs share - code: ${
|
||||||
|
response.statusCode
|
||||||
|
} body: ${JSON.stringify(response.body)}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -234,6 +243,179 @@ class FreeNASDriver extends ControllerZfsSshBaseDriver {
|
||||||
return volume_context;
|
return volume_context;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "smb":
|
||||||
|
properties = await zb.zfs.get(datasetName, [
|
||||||
|
"mountpoint",
|
||||||
|
FREENAS_SMB_SHARE_PROPERTY_NAME,
|
||||||
|
]);
|
||||||
|
properties = properties[datasetName];
|
||||||
|
this.ctx.logger.debug("zfs props data: %j", properties);
|
||||||
|
|
||||||
|
let smbName;
|
||||||
|
|
||||||
|
if (this.options.smb.nameTemplate) {
|
||||||
|
smbName = Handlebars.compile(this.options.smb.nameTemplate)({
|
||||||
|
name: call.request.name,
|
||||||
|
parameters: call.request.parameters,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
smbName = zb.helpers.extractLeafName(datasetName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.smb.namePrefix) {
|
||||||
|
smbName = this.options.smb.namePrefix + smbName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.smb.nameSuffix) {
|
||||||
|
smbName += this.options.smb.nameSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
smbName = smbName.toLowerCase();
|
||||||
|
|
||||||
|
this.ctx.logger.info(
|
||||||
|
"FreeNAS creating smb share with name: " + smbName
|
||||||
|
);
|
||||||
|
|
||||||
|
// create smb share
|
||||||
|
if (
|
||||||
|
!zb.helpers.isPropertyValueSet(
|
||||||
|
properties[FREENAS_SMB_SHARE_PROPERTY_NAME].value
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* The only required parameters are:
|
||||||
|
* - path
|
||||||
|
* - name
|
||||||
|
*
|
||||||
|
* Note that over time it appears the list of available parameters has increased
|
||||||
|
* so in an effort to best support old versions of FreeNAS we should check the
|
||||||
|
* presense of each parameter in the config and set the corresponding parameter in
|
||||||
|
* the API request *only* if present in the config.
|
||||||
|
*/
|
||||||
|
switch (apiVersion) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
share = {
|
||||||
|
name: smbName,
|
||||||
|
path: properties.mountpoint.value,
|
||||||
|
};
|
||||||
|
|
||||||
|
let propertyMapping = {
|
||||||
|
shareTemplate: "auxsmbconf",
|
||||||
|
shareHome: "home",
|
||||||
|
shareAllowedHosts: "hostsallow",
|
||||||
|
shareDeniedHosts: "hostsdeny",
|
||||||
|
shareDefaultPermissions: "default_permissions",
|
||||||
|
shareGuestOk: "guestok",
|
||||||
|
shareGuestOnly: "guestonly",
|
||||||
|
shareShowHiddenFiles: "showhiddenfiles",
|
||||||
|
shareRecycleBin: "recyclebin",
|
||||||
|
shareBrowsable: "browsable",
|
||||||
|
shareAccessBasedEnumeration: "abe",
|
||||||
|
shareTimeMachine: "timemachine",
|
||||||
|
shareStorageTask: "storage_task",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const key in propertyMapping) {
|
||||||
|
if (this.options.smb.hasOwnProperty(key)) {
|
||||||
|
let value;
|
||||||
|
switch (key) {
|
||||||
|
case "shareTemplate":
|
||||||
|
value = Handlebars.compile(
|
||||||
|
this.options.smb.shareTemplate
|
||||||
|
)({
|
||||||
|
name: call.request.name,
|
||||||
|
parameters: call.request.parameters,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
value = this.options.smb[key];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
share[propertyMapping[key]] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (apiVersion) {
|
||||||
|
case 1:
|
||||||
|
endpoint = "/sharing/cifs";
|
||||||
|
|
||||||
|
// rename keys with cifs_ prefix
|
||||||
|
for (const key in share) {
|
||||||
|
share["cifs_" + key] = share[key];
|
||||||
|
delete share[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert to comma-separated list
|
||||||
|
if (share.cifs_hostsallow) {
|
||||||
|
share.cifs_hostsallow = share.cifs_hostsallow.join(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert to comma-separated list
|
||||||
|
if (share.cifs_hostsdeny) {
|
||||||
|
share.cifs_hostsdeny = share.cifs_hostsdeny.join(",");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
endpoint = "/sharing/smb";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
response = await httpClient.post(endpoint, share);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v1 = 201
|
||||||
|
* v2 = 200
|
||||||
|
*/
|
||||||
|
if ([200, 201].includes(response.statusCode)) {
|
||||||
|
//set zfs property
|
||||||
|
await zb.zfs.set(datasetName, {
|
||||||
|
[FREENAS_SMB_SHARE_PROPERTY_NAME]: response.body.id,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
/**
|
||||||
|
* v1 = 409
|
||||||
|
* v2 = 422
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
[409, 422].includes(response.statusCode) &&
|
||||||
|
JSON.stringify(response.body).includes(
|
||||||
|
"You can't share same filesystem with all hosts twice."
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
// move along
|
||||||
|
} else {
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.UNKNOWN,
|
||||||
|
`received error creating smb share - code: ${
|
||||||
|
response.statusCode
|
||||||
|
} body: ${JSON.stringify(response.body)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let volume_context = {
|
||||||
|
node_attach_driver: "smb",
|
||||||
|
server: this.options.smb.shareHost,
|
||||||
|
share: smbName,
|
||||||
|
};
|
||||||
|
return volume_context;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.FAILED_PRECONDITION,
|
||||||
|
`invalid configuration: unknown apiVersion ${apiVersion}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let volume_context = {
|
||||||
|
node_attach_driver: "smb",
|
||||||
|
server: this.options.smb.shareHost,
|
||||||
|
share: smbName,
|
||||||
|
};
|
||||||
|
return volume_context;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "iscsi":
|
case "iscsi":
|
||||||
properties = await zb.zfs.get(datasetName, [
|
properties = await zb.zfs.get(datasetName, [
|
||||||
FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME,
|
FREENAS_ISCSI_TARGET_ID_PROPERTY_NAME,
|
||||||
|
|
@ -835,6 +1017,7 @@ class FreeNASDriver extends ControllerZfsSshBaseDriver {
|
||||||
let properties;
|
let properties;
|
||||||
let response;
|
let response;
|
||||||
let endpoint;
|
let endpoint;
|
||||||
|
let shareId;
|
||||||
|
|
||||||
switch (driverShareType) {
|
switch (driverShareType) {
|
||||||
case "nfs":
|
case "nfs":
|
||||||
|
|
@ -851,7 +1034,7 @@ class FreeNASDriver extends ControllerZfsSshBaseDriver {
|
||||||
properties = properties[datasetName];
|
properties = properties[datasetName];
|
||||||
this.ctx.logger.debug("zfs props data: %j", properties);
|
this.ctx.logger.debug("zfs props data: %j", properties);
|
||||||
|
|
||||||
let shareId = properties[FREENAS_NFS_SHARE_PROPERTY_NAME].value;
|
shareId = properties[FREENAS_NFS_SHARE_PROPERTY_NAME].value;
|
||||||
|
|
||||||
// remove nfs share
|
// remove nfs share
|
||||||
if (
|
if (
|
||||||
|
|
@ -896,6 +1079,68 @@ class FreeNASDriver extends ControllerZfsSshBaseDriver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "smb":
|
||||||
|
try {
|
||||||
|
properties = await zb.zfs.get(datasetName, [
|
||||||
|
FREENAS_SMB_SHARE_PROPERTY_NAME,
|
||||||
|
]);
|
||||||
|
} catch (err) {
|
||||||
|
if (err.toString().includes("dataset does not exist")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
properties = properties[datasetName];
|
||||||
|
this.ctx.logger.debug("zfs props data: %j", properties);
|
||||||
|
|
||||||
|
shareId = properties[FREENAS_SMB_SHARE_PROPERTY_NAME].value;
|
||||||
|
|
||||||
|
// remove smb share
|
||||||
|
if (
|
||||||
|
properties &&
|
||||||
|
properties[FREENAS_SMB_SHARE_PROPERTY_NAME] &&
|
||||||
|
properties[FREENAS_SMB_SHARE_PROPERTY_NAME].value != "-"
|
||||||
|
) {
|
||||||
|
switch (apiVersion) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
switch (apiVersion) {
|
||||||
|
case 1:
|
||||||
|
endpoint = `/sharing/cifs/${shareId}`;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
endpoint = `/sharing/smb/id/${shareId}`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
response = await httpClient.get(endpoint);
|
||||||
|
|
||||||
|
// assume share is gone for now
|
||||||
|
if ([404, 500].includes(response.statusCode)) {
|
||||||
|
} else {
|
||||||
|
response = await httpClient.delete(endpoint);
|
||||||
|
|
||||||
|
// returns a 500 if does not exist
|
||||||
|
// v1 = 204
|
||||||
|
// v2 = 200
|
||||||
|
if (![200, 204].includes(response.statusCode)) {
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.UNKNOWN,
|
||||||
|
`received error deleting smb share - share: ${shareId} code: ${
|
||||||
|
response.statusCode
|
||||||
|
} body: ${JSON.stringify(response.body)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.FAILED_PRECONDITION,
|
||||||
|
`invalid configuration: unknown apiVersion ${apiVersion}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "iscsi":
|
case "iscsi":
|
||||||
// Delete target
|
// Delete target
|
||||||
// NOTE: deletting a target inherently deletes associated targetgroup(s) and targettoextent(s)
|
// NOTE: deletting a target inherently deletes associated targetgroup(s) and targettoextent(s)
|
||||||
|
|
|
||||||
|
|
@ -75,14 +75,14 @@ class CsiBaseDriver {
|
||||||
async GetPluginInfo(call) {
|
async GetPluginInfo(call) {
|
||||||
return {
|
return {
|
||||||
name: this.ctx.args.csiName,
|
name: this.ctx.args.csiName,
|
||||||
vendor_version: this.ctx.args.version
|
vendor_version: this.ctx.args.version,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async GetPluginCapabilities(call) {
|
async GetPluginCapabilities(call) {
|
||||||
let capabilities;
|
let capabilities;
|
||||||
const response = {
|
const response = {
|
||||||
capabilities: []
|
capabilities: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
//UNKNOWN = 0;
|
//UNKNOWN = 0;
|
||||||
|
|
@ -104,12 +104,12 @@ class CsiBaseDriver {
|
||||||
// accessible from a given node when scheduling workloads.
|
// accessible from a given node when scheduling workloads.
|
||||||
//VOLUME_ACCESSIBILITY_CONSTRAINTS = 2;
|
//VOLUME_ACCESSIBILITY_CONSTRAINTS = 2;
|
||||||
capabilities = this.options.service.identity.capabilities.service || [
|
capabilities = this.options.service.identity.capabilities.service || [
|
||||||
"UNKNOWN"
|
"UNKNOWN",
|
||||||
];
|
];
|
||||||
|
|
||||||
capabilities.forEach(item => {
|
capabilities.forEach((item) => {
|
||||||
response.capabilities.push({
|
response.capabilities.push({
|
||||||
service: { type: item }
|
service: { type: item },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -155,9 +155,9 @@ class CsiBaseDriver {
|
||||||
capabilities = this.options.service.identity.capabilities
|
capabilities = this.options.service.identity.capabilities
|
||||||
.volume_expansion || ["UNKNOWN"];
|
.volume_expansion || ["UNKNOWN"];
|
||||||
|
|
||||||
capabilities.forEach(item => {
|
capabilities.forEach((item) => {
|
||||||
response.capabilities.push({
|
response.capabilities.push({
|
||||||
volume_expansion: { type: item }
|
volume_expansion: { type: item },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -171,7 +171,7 @@ class CsiBaseDriver {
|
||||||
async ControllerGetCapabilities(call) {
|
async ControllerGetCapabilities(call) {
|
||||||
let capabilities;
|
let capabilities;
|
||||||
const response = {
|
const response = {
|
||||||
capabilities: []
|
capabilities: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
//UNKNOWN = 0;
|
//UNKNOWN = 0;
|
||||||
|
|
@ -199,12 +199,12 @@ class CsiBaseDriver {
|
||||||
// See VolumeExpansion for details.
|
// See VolumeExpansion for details.
|
||||||
//EXPAND_VOLUME = 9;
|
//EXPAND_VOLUME = 9;
|
||||||
capabilities = this.options.service.controller.capabilities.rpc || [
|
capabilities = this.options.service.controller.capabilities.rpc || [
|
||||||
"UNKNOWN"
|
"UNKNOWN",
|
||||||
];
|
];
|
||||||
|
|
||||||
capabilities.forEach(item => {
|
capabilities.forEach((item) => {
|
||||||
response.capabilities.push({
|
response.capabilities.push({
|
||||||
rpc: { type: item }
|
rpc: { type: item },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -214,7 +214,7 @@ class CsiBaseDriver {
|
||||||
async NodeGetCapabilities(call) {
|
async NodeGetCapabilities(call) {
|
||||||
let capabilities;
|
let capabilities;
|
||||||
const response = {
|
const response = {
|
||||||
capabilities: []
|
capabilities: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
//UNKNOWN = 0;
|
//UNKNOWN = 0;
|
||||||
|
|
@ -227,9 +227,9 @@ class CsiBaseDriver {
|
||||||
//EXPAND_VOLUME = 3;
|
//EXPAND_VOLUME = 3;
|
||||||
capabilities = this.options.service.node.capabilities.rpc || ["UNKNOWN"];
|
capabilities = this.options.service.node.capabilities.rpc || ["UNKNOWN"];
|
||||||
|
|
||||||
capabilities.forEach(item => {
|
capabilities.forEach((item) => {
|
||||||
response.capabilities.push({
|
response.capabilities.push({
|
||||||
rpc: { type: item }
|
rpc: { type: item },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -239,7 +239,7 @@ class CsiBaseDriver {
|
||||||
async NodeGetInfo(call) {
|
async NodeGetInfo(call) {
|
||||||
return {
|
return {
|
||||||
node_id: process.env.CSI_NODE_ID || os.hostname(),
|
node_id: process.env.CSI_NODE_ID || os.hostname(),
|
||||||
max_volumes_per_node: 0
|
max_volumes_per_node: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -296,12 +296,15 @@ class CsiBaseDriver {
|
||||||
case "nfs":
|
case "nfs":
|
||||||
device = `${volume_context.server}:${volume_context.share}`;
|
device = `${volume_context.server}:${volume_context.share}`;
|
||||||
break;
|
break;
|
||||||
|
case "smb":
|
||||||
|
device = `//${volume_context.server}/${volume_context.share}`;
|
||||||
|
break;
|
||||||
case "iscsi":
|
case "iscsi":
|
||||||
// create DB entry
|
// create DB entry
|
||||||
// https://library.netapp.com/ecmdocs/ECMP1654943/html/GUID-8EC685B4-8CB6-40D8-A8D5-031A3899BCDC.html
|
// https://library.netapp.com/ecmdocs/ECMP1654943/html/GUID-8EC685B4-8CB6-40D8-A8D5-031A3899BCDC.html
|
||||||
// put these options in place to force targets managed by csi to be explicitly attached (in the case of unclearn shutdown etc)
|
// put these options in place to force targets managed by csi to be explicitly attached (in the case of unclearn shutdown etc)
|
||||||
let nodeDB = {
|
let nodeDB = {
|
||||||
"node.startup": "manual"
|
"node.startup": "manual",
|
||||||
};
|
};
|
||||||
const nodeDBKeyPrefix = "node-db.";
|
const nodeDBKeyPrefix = "node-db.";
|
||||||
const normalizedSecrets = this.getNormalizedParameters(
|
const normalizedSecrets = this.getNormalizedParameters(
|
||||||
|
|
@ -420,7 +423,7 @@ class CsiBaseDriver {
|
||||||
|
|
||||||
await mount.bindMount(device, block_path, [
|
await mount.bindMount(device, block_path, [
|
||||||
"-o",
|
"-o",
|
||||||
bind_mount_flags.join(",")
|
bind_mount_flags.join(","),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -506,7 +509,7 @@ class CsiBaseDriver {
|
||||||
session.attached_scsi_devices.host.devices
|
session.attached_scsi_devices.host.devices
|
||||||
) {
|
) {
|
||||||
is_attached_to_session = session.attached_scsi_devices.host.devices.some(
|
is_attached_to_session = session.attached_scsi_devices.host.devices.some(
|
||||||
device => {
|
(device) => {
|
||||||
if (device.attached_scsi_disk == block_device_info.name) {
|
if (device.attached_scsi_disk == block_device_info.name) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -525,7 +528,7 @@ class CsiBaseDriver {
|
||||||
while (!loggedOut) {
|
while (!loggedOut) {
|
||||||
try {
|
try {
|
||||||
await iscsi.iscsiadm.logout(session.target, [
|
await iscsi.iscsiadm.logout(session.target, [
|
||||||
session.persistent_portal
|
session.persistent_portal,
|
||||||
]);
|
]);
|
||||||
loggedOut = true;
|
loggedOut = true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -659,7 +662,7 @@ class CsiBaseDriver {
|
||||||
if (!result) {
|
if (!result) {
|
||||||
await mount.bindMount(normalized_staging_path, target_path, [
|
await mount.bindMount(normalized_staging_path, target_path, [
|
||||||
"-o",
|
"-o",
|
||||||
bind_mount_flags.join(",")
|
bind_mount_flags.join(","),
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
// if is mounted, ensure proper source
|
// if is mounted, ensure proper source
|
||||||
|
|
@ -760,9 +763,9 @@ class CsiBaseDriver {
|
||||||
available: result.avail,
|
available: result.avail,
|
||||||
total: result.size,
|
total: result.size,
|
||||||
used: result.used,
|
used: result.used,
|
||||||
unit: "BYTES"
|
unit: "BYTES",
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
case "block":
|
case "block":
|
||||||
result = await filesystem.getBlockDevice(device_path);
|
result = await filesystem.getBlockDevice(device_path);
|
||||||
|
|
@ -771,9 +774,9 @@ class CsiBaseDriver {
|
||||||
usage: [
|
usage: [
|
||||||
{
|
{
|
||||||
total: result.size,
|
total: result.size,
|
||||||
unit: "BYTES"
|
unit: "BYTES",
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
throw new GrpcError(
|
throw new GrpcError(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue