support for csi v1.4.0 and v1.5.0, various misc improvements

Signed-off-by: Travis Glenn Hansen <travisghansen@yahoo.com>
This commit is contained in:
Travis Glenn Hansen 2021-08-10 11:59:44 -06:00
parent 3d462e7d09
commit 22031a8467
14 changed files with 3569 additions and 72 deletions

View File

@ -32,7 +32,16 @@ const args = require("yargs")
})
.option("csi-version", {
describe: "versin of the csi spec to load",
choices: ["0.2.0", "0.3.0", "1.0.0", "1.1.0", "1.2.0", "1.3.0"],
choices: [
"0.2.0",
"0.3.0",
"1.0.0",
"1.1.0",
"1.2.0",
"1.3.0",
"1.4.0",
"1.5.0",
],
})
.demandOption(["csi-version"], "csi-version is required")
.option("csi-name", {

View File

@ -10,7 +10,16 @@ const args = require("yargs")
.usage("$0 [options]")
.option("csi-version", {
describe: "versin of the csi spec to load",
choices: ["0.2.0", "0.3.0", "1.0.0", "1.1.0", "1.2.0", "1.3.0"],
choices: [
"0.2.0",
"0.3.0",
"1.0.0",
"1.1.0",
"1.2.0",
"1.3.0",
"1.4.0",
"1.5.0",
],
})
.demandOption(["csi-version"], "csi-version is required")
.option("csi-address", {
@ -49,7 +58,7 @@ const clientIdentity = new csi.Identity(
/**
* Probe the identity service and check for ready state
*
*
* https://github.com/kubernetes-csi/livenessprobe/blob/master/cmd/livenessprobe/main.go
* https://github.com/kubernetes-csi/csi-lib-utils/blob/master/rpc/common.go
*/

1578
csi_proto/csi-v1.4.0.proto Normal file

File diff suppressed because it is too large Load Diff

1635
csi_proto/csi-v1.5.0.proto Normal file

File diff suppressed because it is too large Load Diff

82
package-lock.json generated
View File

@ -8,6 +8,7 @@
"version": "1.2.0",
"license": "MIT",
"dependencies": {
"@grpc/grpc-js": "^1.3.6",
"@grpc/proto-loader": "^0.6.0",
"async-mutex": "^0.3.1",
"bunyan": "^1.8.15",
@ -183,6 +184,17 @@
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/@grpc/grpc-js": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.6.tgz",
"integrity": "sha512-v7+LQFbqZKmd/Tvf5/j1Xlbq6jXL/4d+gUtm2TNX4QiEC3ELWADmGr2dGlUyLl6aKTuYfsN72vAsO5zmavYkEg==",
"dependencies": {
"@types/node": ">=12.12.47"
},
"engines": {
"node": "^8.13.0 || >=10.10.0"
}
},
"node_modules/@grpc/proto-loader": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.4.tgz",
@ -442,7 +454,8 @@
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"devOptional": true
},
"node_modules/bcrypt-pbkdf": {
"version": "1.0.2",
@ -456,6 +469,7 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"devOptional": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -545,14 +559,6 @@
"wrap-ansi": "^7.0.0"
}
},
"node_modules/code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/color": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz",
@ -639,7 +645,8 @@
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"devOptional": true
},
"node_modules/core-util-is": {
"version": "1.0.2",
@ -1119,7 +1126,8 @@
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"node_modules/functional-red-black-tree": {
"version": "1.0.1",
@ -1147,6 +1155,7 @@
"version": "7.1.7",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
"integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -1920,6 +1929,7 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"devOptional": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@ -2174,6 +2184,7 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"devOptional": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@ -2279,14 +2290,6 @@
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
},
"node_modules/number-is-nan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@ -2299,6 +2302,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"devOptional": true,
"dependencies": {
"wrappy": "1"
}
@ -2360,6 +2364,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"devOptional": true,
"engines": {
"node": ">=0.10.0"
}
@ -3043,7 +3048,8 @@
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"devOptional": true
},
"node_modules/y18n": {
"version": "5.0.8",
@ -3217,6 +3223,14 @@
}
}
},
"@grpc/grpc-js": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.6.tgz",
"integrity": "sha512-v7+LQFbqZKmd/Tvf5/j1Xlbq6jXL/4d+gUtm2TNX4QiEC3ELWADmGr2dGlUyLl6aKTuYfsN72vAsO5zmavYkEg==",
"requires": {
"@types/node": ">=12.12.47"
}
},
"@grpc/proto-loader": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.4.tgz",
@ -3433,7 +3447,8 @@
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"devOptional": true
},
"bcrypt-pbkdf": {
"version": "1.0.2",
@ -3447,6 +3462,7 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"devOptional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -3514,10 +3530,6 @@
"wrap-ansi": "^7.0.0"
}
},
"code-point-at": {
"version": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
"color": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz",
@ -3594,7 +3606,8 @@
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"devOptional": true
},
"core-util-is": {
"version": "1.0.2",
@ -3968,7 +3981,8 @@
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"functional-red-black-tree": {
"version": "1.0.1",
@ -3993,6 +4007,7 @@
"version": "7.1.7",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
"integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -4556,6 +4571,7 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"devOptional": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
@ -4771,6 +4787,7 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"devOptional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -4857,10 +4874,6 @@
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
},
"number-is-nan": {
"version": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
},
"oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@ -4870,6 +4883,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"devOptional": true,
"requires": {
"wrappy": "1"
}
@ -4921,7 +4935,8 @@
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"devOptional": true
},
"path-key": {
"version": "3.1.1",
@ -5428,7 +5443,8 @@
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"devOptional": true
},
"y18n": {
"version": "5.0.8",

View File

@ -18,6 +18,7 @@
"url": "https://github.com/democratic-csi/democratic-csi.git"
},
"dependencies": {
"@grpc/grpc-js": "^1.3.6",
"@grpc/proto-loader": "^0.6.0",
"async-mutex": "^0.3.1",
"bunyan": "^1.8.15",

View File

@ -1,6 +1,7 @@
const { CsiBaseDriver } = require("../index");
const { GrpcError, grpc } = require("../../utils/grpc");
const cp = require("child_process");
const semver = require("semver");
/**
* Crude nfs-client driver which simply creates directories to be mounted
@ -59,6 +60,20 @@ class ControllerClientCommonDriver extends CsiBaseDriver {
//"PUBLISH_READONLY",
//"EXPAND_VOLUME",
];
if (semver.satisfies(this.ctx.csiVersion, ">=1.3.0")) {
options.service.controller.capabilities.rpc
.push
//"VOLUME_CONDITION",
//"GET_VOLUME"
();
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.5.0")) {
options.service.controller.capabilities.rpc.push(
"SINGLE_NODE_MULTI_WRITER"
);
}
}
if (!("rpc" in options.service.node.capabilities)) {
@ -70,6 +85,18 @@ class ControllerClientCommonDriver extends CsiBaseDriver {
"GET_VOLUME_STATS",
//"EXPAND_VOLUME"
];
if (semver.satisfies(this.ctx.csiVersion, ">=1.3.0")) {
//options.service.node.capabilities.rpc.push("VOLUME_CONDITION");
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.5.0")) {
options.service.node.capabilities.rpc.push("SINGLE_NODE_MULTI_WRITER");
/**
* This is for volumes that support a mount time gid such as smb or fat
*/
//options.service.node.capabilities.rpc.push("VOLUME_MOUNT_GROUP");
}
}
}
@ -98,6 +125,8 @@ class ControllerClientCommonDriver extends CsiBaseDriver {
![
"UNKNOWN",
"SINGLE_NODE_WRITER",
"SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0
"SINGLE_NODE_MULTI_WRITER", // added in v1.5.0
"SINGLE_NODE_READER_ONLY",
"MULTI_NODE_READER_ONLY",
"MULTI_NODE_SINGLE_WRITER",

View File

@ -89,7 +89,13 @@ class SynologyHttpClient {
switch (method) {
case "GET":
options.qs = data;
let qsData = JSON.parse(JSON.stringify(data));
for (let p in qsData) {
if (Array.isArray(qsData[p])) {
qsData[p] = JSON.stringify(qsData[p]);
}
}
options.qs = qsData;
break;
default:
if (invoke_options.use_form_encoded) {

View File

@ -1,6 +1,7 @@
const { CsiBaseDriver } = require("../index");
const { GrpcError, grpc } = require("../../utils/grpc");
const SynologyHttpClient = require("./http").SynologyHttpClient;
const semver = require("semver");
const sleep = require("../../utils/general").sleep;
/**
@ -63,6 +64,20 @@ class ControllerSynologyDriver extends CsiBaseDriver {
//"PUBLISH_READONLY",
"EXPAND_VOLUME",
];
if (semver.satisfies(this.ctx.csiVersion, ">=1.3.0")) {
options.service.controller.capabilities.rpc
.push
//"VOLUME_CONDITION",
//"GET_VOLUME" (would need to properly handle volume_content_source)
();
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.5.0")) {
options.service.controller.capabilities.rpc.push(
"SINGLE_NODE_MULTI_WRITER"
);
}
}
if (!("rpc" in options.service.node.capabilities)) {
@ -78,6 +93,18 @@ class ControllerSynologyDriver extends CsiBaseDriver {
if (driverResourceType == "volume") {
options.service.node.capabilities.rpc.push("EXPAND_VOLUME");
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.3.0")) {
//options.service.node.capabilities.rpc.push("VOLUME_CONDITION");
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.5.0")) {
options.service.node.capabilities.rpc.push("SINGLE_NODE_MULTI_WRITER");
/**
* This is for volumes that support a mount time gid such as smb or fat
*/
//options.service.node.capabilities.rpc.push("VOLUME_MOUNT_GROUP");
}
}
}
@ -152,6 +179,8 @@ class ControllerSynologyDriver extends CsiBaseDriver {
![
"UNKNOWN",
"SINGLE_NODE_WRITER",
"SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0
"SINGLE_NODE_MULTI_WRITER", // added in v1.5.0
"SINGLE_NODE_READER_ONLY",
"MULTI_NODE_READER_ONLY",
"MULTI_NODE_SINGLE_WRITER",
@ -180,6 +209,8 @@ class ControllerSynologyDriver extends CsiBaseDriver {
![
"UNKNOWN",
"SINGLE_NODE_WRITER",
"SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0
"SINGLE_NODE_MULTI_WRITER", // added in v1.5.0
"SINGLE_NODE_READER_ONLY",
"MULTI_NODE_READER_ONLY",
"MULTI_NODE_SINGLE_WRITER",

View File

@ -90,9 +90,20 @@ class ControllerZfsSshBaseDriver extends CsiBaseDriver {
"CLONE_VOLUME",
//"PUBLISH_READONLY",
"EXPAND_VOLUME",
//"VOLUME_CONDITION", // added in v1.3.0
//"GET_VOLUME", // added in v1.3.0
];
if (semver.satisfies(this.ctx.csiVersion, ">=1.3.0")) {
options.service.controller.capabilities.rpc.push(
//"VOLUME_CONDITION",
"GET_VOLUME"
);
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.5.0")) {
options.service.controller.capabilities.rpc.push(
"SINGLE_NODE_MULTI_WRITER"
);
}
}
if (!("rpc" in options.service.node.capabilities)) {
@ -118,6 +129,18 @@ class ControllerZfsSshBaseDriver extends CsiBaseDriver {
];
break;
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.3.0")) {
//options.service.node.capabilities.rpc.push("VOLUME_CONDITION");
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.5.0")) {
options.service.node.capabilities.rpc.push("SINGLE_NODE_MULTI_WRITER");
/**
* This is for volumes that support a mount time gid such as smb or fat
*/
//options.service.node.capabilities.rpc.push("VOLUME_MOUNT_GROUP"); // in k8s is sent in as the security context fsgroup
}
}
}
@ -219,6 +242,8 @@ class ControllerZfsSshBaseDriver extends CsiBaseDriver {
![
"UNKNOWN",
"SINGLE_NODE_WRITER",
"SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0
"SINGLE_NODE_MULTI_WRITER", // added in v1.5.0
"SINGLE_NODE_READER_ONLY",
"MULTI_NODE_READER_ONLY",
"MULTI_NODE_SINGLE_WRITER",
@ -247,6 +272,8 @@ class ControllerZfsSshBaseDriver extends CsiBaseDriver {
![
"UNKNOWN",
"SINGLE_NODE_WRITER",
"SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0
"SINGLE_NODE_MULTI_WRITER", // added in v1.5.0
"SINGLE_NODE_READER_ONLY",
"MULTI_NODE_READER_ONLY",
"MULTI_NODE_SINGLE_WRITER",

View File

@ -95,9 +95,20 @@ class FreeNASApiDriver extends CsiBaseDriver {
"CLONE_VOLUME",
//"PUBLISH_READONLY",
"EXPAND_VOLUME",
//"VOLUME_CONDITION", // added in v1.3.0
//"GET_VOLUME", // added in v1.3.0
];
if (semver.satisfies(this.ctx.csiVersion, ">=1.3.0")) {
options.service.controller.capabilities.rpc.push(
//"VOLUME_CONDITION",
"GET_VOLUME"
);
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.5.0")) {
options.service.controller.capabilities.rpc.push(
"SINGLE_NODE_MULTI_WRITER"
);
}
}
if (!("rpc" in options.service.node.capabilities)) {
@ -110,7 +121,6 @@ class FreeNASApiDriver extends CsiBaseDriver {
"STAGE_UNSTAGE_VOLUME",
"GET_VOLUME_STATS",
//"EXPAND_VOLUME",
//"VOLUME_CONDITION",
];
break;
case "volume":
@ -119,10 +129,21 @@ class FreeNASApiDriver extends CsiBaseDriver {
"STAGE_UNSTAGE_VOLUME",
"GET_VOLUME_STATS",
"EXPAND_VOLUME",
//"VOLUME_CONDITION",
];
break;
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.3.0")) {
//options.service.node.capabilities.rpc.push("VOLUME_CONDITION");
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.5.0")) {
options.service.node.capabilities.rpc.push("SINGLE_NODE_MULTI_WRITER");
/**
* This is for volumes that support a mount time gid such as smb or fat
*/
//options.service.node.capabilities.rpc.push("VOLUME_MOUNT_GROUP");
}
}
}
@ -1582,6 +1603,7 @@ class FreeNASApiDriver extends CsiBaseDriver {
async removeSnapshotsFromDatatset(datasetName, options = {}) {
// TODO: alter the logic here to not be n+1
// https://jira.ixsystems.com/browse/NAS-111708
const httpClient = await this.getHttpClient();
const httpApiClient = await this.getTrueNASHttpApiClient();
@ -1604,7 +1626,15 @@ class FreeNASApiDriver extends CsiBaseDriver {
throw new Error("unhandled statusCode: " + response.statusCode);
}
/**
* Hypothetically this isn't needed. The middleware is supposed to reload stuff as appropriate.
*
* @param {*} call
* @param {*} datasetName
* @returns
*/
async expandVolume(call, datasetName) {
// TODO: fix me
return;
const driverShareType = this.getDriverShareType();
const sshClient = this.getSshClient();
@ -1844,6 +1874,8 @@ class FreeNASApiDriver extends CsiBaseDriver {
![
"UNKNOWN",
"SINGLE_NODE_WRITER",
"SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0
"SINGLE_NODE_MULTI_WRITER", // added in v1.5.0
"SINGLE_NODE_READER_ONLY",
"MULTI_NODE_READER_ONLY",
"MULTI_NODE_SINGLE_WRITER",
@ -1872,6 +1904,8 @@ class FreeNASApiDriver extends CsiBaseDriver {
![
"UNKNOWN",
"SINGLE_NODE_WRITER",
"SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0
"SINGLE_NODE_MULTI_WRITER", // added in v1.5.0
"SINGLE_NODE_READER_ONLY",
"MULTI_NODE_READER_ONLY",
"MULTI_NODE_SINGLE_WRITER",
@ -2140,6 +2174,7 @@ class FreeNASApiDriver extends CsiBaseDriver {
retention_policy: "NONE",
readonly: "IGNORE",
properties: false,
only_from_scratch: true,
});
let job_id = response;
@ -2155,16 +2190,21 @@ class FreeNASApiDriver extends CsiBaseDriver {
await sleep(3000);
}
job.error = job.error || "";
switch (job.state) {
case "SUCCESS":
break;
case "FAILED":
// TODO: handle scenarios where the dataset
break;
case "ABORTED":
// TODO: handle this
break;
default:
//[EFAULT] Target dataset 'tank/.../clone-test' already exists.
if (!job.error.includes("already exists")) {
throw new GrpcError(
grpc.status.UNKNOWN,
`failed to run replication task (${job.state}): ${job.error}`
);
}
break;
}
@ -2287,6 +2327,7 @@ class FreeNASApiDriver extends CsiBaseDriver {
retention_policy: "NONE",
readonly: "IGNORE",
properties: false,
only_from_scratch: true,
});
let job_id = response;
@ -2302,16 +2343,21 @@ class FreeNASApiDriver extends CsiBaseDriver {
await sleep(3000);
}
job.error = job.error || "";
switch (job.state) {
case "SUCCESS":
break;
case "FAILED":
// TODO: handle scenarios where the dataset
break;
case "ABORTED":
// TODO: handle this
break;
default:
//[EFAULT] Target dataset 'tank/.../clone-test' already exists.
if (!job.error.includes("already exists")) {
throw new GrpcError(
grpc.status.UNKNOWN,
`failed to run replication task (${job.state}): ${job.error}`
);
}
break;
}
} catch (err) {
@ -2442,9 +2488,35 @@ class FreeNASApiDriver extends CsiBaseDriver {
this.options.zfs.hasOwnProperty("datasetPermissionsUser") ||
this.options.zfs.hasOwnProperty("datasetPermissionsGroup")
) {
// TODO: ensure the values are numbers and not strings
setPerms = true;
}
// user
if (this.options.zfs.hasOwnProperty("datasetPermissionsUser")) {
if (
String(this.options.zfs.datasetPermissionsUser).match(/^[0-9]+$/) ==
null
) {
throw new GrpcError(
grpc.status.FAILED_PRECONDITION,
`datasetPermissionsUser must be numeric: ${this.options.zfs.datasetPermissionsUser}`
);
}
perms.uid = Number(this.options.zfs.datasetPermissionsUser);
}
// group
if (this.options.zfs.hasOwnProperty("datasetPermissionsGroup")) {
if (
String(this.options.zfs.datasetPermissionsGroup).match(
/^[0-9]+$/
) == null
) {
throw new GrpcError(
grpc.status.FAILED_PRECONDITION,
`datasetPermissionsGroup must be numeric: ${this.options.zfs.datasetPermissionsGroup}`
);
}
perms.gid = Number(this.options.zfs.datasetPermissionsGroup);
}
@ -2635,6 +2707,7 @@ class FreeNASApiDriver extends CsiBaseDriver {
* @param {*} call
*/
async ControllerExpandVolume(call) {
// TODO: https://jira.ixsystems.com/browse/NAS-111707
const driver = this;
const driverZfsResourceType = this.getDriverZfsResourceType();
const httpApiClient = await this.getTrueNASHttpApiClient();
@ -3160,19 +3233,15 @@ class FreeNASApiDriver extends CsiBaseDriver {
)}`;
response = await httpClient.get(endpoint, {
"extra.snapshots": 1,
"extra.snapshots_properties": JSON.stringify(zfsProperties),
});
if (response.statusCode == 404) {
throw new Error("dataset does not exist");
} else if (response.statusCode == 200) {
for (let snapshot of response.body.snapshots) {
// TODO: alter the logic here to not be n+1
let i_response = await httpApiClient.SnapshotGet(
snapshot.name,
zfsProperties
);
let row = {};
for (let p in i_response) {
row[p] = i_response[p].rawvalue;
for (let p in snapshot.properties) {
row[p] = snapshot.properties[p].rawvalue;
}
rows.push(row);
}
@ -3187,20 +3256,16 @@ class FreeNASApiDriver extends CsiBaseDriver {
)}`;
response = await httpClient.get(endpoint, {
"extra.snapshots": 1,
"extra.snapshots_properties": JSON.stringify(zfsProperties),
});
if (response.statusCode == 404) {
throw new Error("dataset does not exist");
} else if (response.statusCode == 200) {
for (let child of response.body.children) {
for (let snapshot of child.snapshots) {
// TODO: alter the logic here to not be n+1
let i_response = await httpApiClient.SnapshotGet(
snapshot.name,
zfsProperties
);
let row = {};
for (let p in i_response) {
row[p] = i_response[p].rawvalue;
for (let p in snapshot.properties) {
row[p] = snapshot.properties[p].rawvalue;
}
rows.push(row);
}
@ -3266,7 +3331,6 @@ class FreeNASApiDriver extends CsiBaseDriver {
} else if (response.statusCode == 200) {
for (let child of response.body.children) {
for (let grandchild of child.children) {
// TODO: ask for full snapshot properties to be returned in the above endpoint to avoid the n+1 logic here
let i_response = httpApiClient.normalizeProperties(
grandchild,
zfsProperties
@ -3543,6 +3607,7 @@ class FreeNASApiDriver extends CsiBaseDriver {
retention_policy: "NONE",
readonly: "IGNORE",
properties: false,
only_from_scratch: true,
});
let job_id = response;
@ -3555,16 +3620,21 @@ class FreeNASApiDriver extends CsiBaseDriver {
await sleep(3000);
}
job.error = job.error || "";
switch (job.state) {
case "SUCCESS":
break;
case "FAILED":
// TODO: handle scenarios where the dataset
break;
case "ABORTED":
// TODO: handle this
break;
default:
//[EFAULT] Target dataset 'tank/.../clone-test' already exists.
if (!job.error.includes("already exists")) {
throw new GrpcError(
grpc.status.UNKNOWN,
`failed to run replication task (${job.state}): ${job.error}`
);
}
break;
}

View File

@ -286,6 +286,7 @@ class CsiBaseDriver {
const volume_context = call.request.volume_context;
let fs_type;
let mount_flags;
let volume_mount_group;
const node_attach_driver = volume_context.node_attach_driver;
const block_path = staging_target_path + "/block_device";
const bind_mount_flags = [];
@ -305,6 +306,15 @@ class CsiBaseDriver {
mount_flags.push(normalizedSecrets.mount_flags);
}
mount_flags.push("defaults");
if (
semver.satisfies(driver.ctx.csiVersion, ">=1.5.0") &&
driver.options.service.node.capabilities.rpc.includes(
"VOLUME_MOUNT_GROUP"
)
) {
volume_mount_group = capability.mount.volume_mount_group; // in k8s this is derrived from the fsgroup in the pod security context
}
}
if (call.request.volume_context.provisioner_driver == "node-manual") {
@ -832,6 +842,7 @@ class CsiBaseDriver {
}
async NodePublishVolume(call) {
const driver = this;
const mount = new Mount();
const filesystem = new Filesystem();
let result;
@ -841,14 +852,25 @@ class CsiBaseDriver {
const target_path = call.request.target_path;
const capability = call.request.volume_capability;
const access_type = capability.access_type || "mount";
let mount_flags;
let volume_mount_group;
const readonly = call.request.readonly;
const volume_context = call.request.volume_context;
const bind_mount_flags = [];
const node_attach_driver = volume_context.node_attach_driver;
if (access_type == "mount") {
let mount_flags = capability.mount.mount_flags || [];
mount_flags = capability.mount.mount_flags || [];
bind_mount_flags.push(...mount_flags);
if (
semver.satisfies(driver.ctx.csiVersion, ">=1.5.0") &&
driver.options.service.node.capabilities.rpc.includes(
"VOLUME_MOUNT_GROUP"
)
) {
volume_mount_group = capability.mount.volume_mount_group; // in k8s this is derrived from the fsgroup in the pod security context
}
}
bind_mount_flags.push("defaults");

View File

@ -1,5 +1,6 @@
const { CsiBaseDriver } = require("../index");
const { GrpcError, grpc } = require("../../utils/grpc");
const semver = require("semver");
/**
* Driver which only runs the node portion and is meant to be used entirely
@ -58,6 +59,21 @@ class NodeManualDriver extends CsiBaseDriver {
//"PUBLISH_READONLY",
//"EXPAND_VOLUME",
];
if (semver.satisfies(this.ctx.csiVersion, ">=1.3.0")) {
options.service.controller.capabilities.rpc
.push
//"VOLUME_CONDITION",
//"GET_VOLUME"
();
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.5.0")) {
options.service.controller.capabilities.rpc
.push
//"SINGLE_NODE_MULTI_WRITER"
();
}
}
if (!("rpc" in options.service.node.capabilities)) {
@ -69,6 +85,18 @@ class NodeManualDriver extends CsiBaseDriver {
"GET_VOLUME_STATS",
//"EXPAND_VOLUME"
];
if (semver.satisfies(this.ctx.csiVersion, ">=1.3.0")) {
//options.service.node.capabilities.rpc.push("VOLUME_CONDITION");
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.5.0")) {
options.service.node.capabilities.rpc.push("SINGLE_NODE_MULTI_WRITER");
/**
* This is for volumes that support a mount time gid such as smb or fat
*/
//options.service.node.capabilities.rpc.push("VOLUME_MOUNT_GROUP");
}
}
}
@ -122,6 +150,8 @@ class NodeManualDriver extends CsiBaseDriver {
![
"UNKNOWN",
"SINGLE_NODE_WRITER",
"SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0
"SINGLE_NODE_MULTI_WRITER", // added in v1.5.0
"SINGLE_NODE_READER_ONLY",
"MULTI_NODE_READER_ONLY",
"MULTI_NODE_SINGLE_WRITER",
@ -148,6 +178,8 @@ class NodeManualDriver extends CsiBaseDriver {
![
"UNKNOWN",
"SINGLE_NODE_WRITER",
"SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0
"SINGLE_NODE_MULTI_WRITER", // added in v1.5.0
"SINGLE_NODE_READER_ONLY",
"MULTI_NODE_READER_ONLY",
"MULTI_NODE_SINGLE_WRITER",

View File

@ -2,6 +2,7 @@ const fs = require("fs");
const { CsiBaseDriver } = require("../index");
const { GrpcError, grpc } = require("../../utils/grpc");
const { Filesystem } = require("../../utils/filesystem");
const semver = require("semver");
const SshClient = require("../../utils/ssh").SshClient;
const { Zetabyte, ZfsSshProcessManager } = require("../../utils/zfs");
@ -81,6 +82,21 @@ class ZfsLocalEphemeralInlineDriver extends CsiBaseDriver {
//"PUBLISH_READONLY",
//"EXPAND_VOLUME"
];
if (semver.satisfies(this.ctx.csiVersion, ">=1.3.0")) {
options.service.controller.capabilities.rpc
.push
//"VOLUME_CONDITION",
//"GET_VOLUME"
();
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.5.0")) {
options.service.controller.capabilities.rpc
.push
//"SINGLE_NODE_MULTI_WRITER"
();
}
}
if (!("rpc" in options.service.node.capabilities)) {
@ -91,6 +107,18 @@ class ZfsLocalEphemeralInlineDriver extends CsiBaseDriver {
"GET_VOLUME_STATS",
//"EXPAND_VOLUME",
];
if (semver.satisfies(this.ctx.csiVersion, ">=1.3.0")) {
//options.service.node.capabilities.rpc.push("VOLUME_CONDITION");
}
if (semver.satisfies(this.ctx.csiVersion, ">=1.5.0")) {
options.service.node.capabilities.rpc.push("SINGLE_NODE_MULTI_WRITER");
/**
* This is for volumes that support a mount time gid such as smb or fat
*/
//options.service.node.capabilities.rpc.push("VOLUME_MOUNT_GROUP");
}
}
}
@ -167,6 +195,8 @@ class ZfsLocalEphemeralInlineDriver extends CsiBaseDriver {
![
"UNKNOWN",
"SINGLE_NODE_WRITER",
"SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0
"SINGLE_NODE_MULTI_WRITER", // added in v1.5.0
"SINGLE_NODE_READER_ONLY",
].includes(capability.access_mode.mode)
) {
@ -192,6 +222,8 @@ class ZfsLocalEphemeralInlineDriver extends CsiBaseDriver {
![
"UNKNOWN",
"SINGLE_NODE_WRITER",
"SINGLE_NODE_SINGLE_WRITER", // added in v1.5.0
"SINGLE_NODE_MULTI_WRITER", // added in v1.5.0
"SINGLE_NODE_READER_ONLY",
].includes(capability.access_mode.mode)
) {