further truenas 25.10 support
Signed-off-by: Travis Glenn Hansen <travisghansen@yahoo.com>
This commit is contained in:
parent
fc7ec358ab
commit
018de54685
|
|
@ -181,10 +181,7 @@ class FreeNASApiDriver extends CsiBaseDriver {
|
|||
const httpApiClient = await this.getTrueNASHttpApiClient();
|
||||
const apiVersion = httpClient.getApiVersion();
|
||||
const zb = await this.getZetabyte();
|
||||
const truenasVersion = semver.coerce(
|
||||
await httpApiClient.getSystemVersionMajorMinor(),
|
||||
{ loose: true }
|
||||
);
|
||||
const truenasVersion = await httpApiClient.getSystemVersionSemver();
|
||||
|
||||
if (!truenasVersion) {
|
||||
throw new GrpcError(
|
||||
|
|
@ -506,6 +503,40 @@ class FreeNASApiDriver extends CsiBaseDriver {
|
|||
}
|
||||
}
|
||||
|
||||
if (isScale && semver.satisfies(truenasVersion, ">=25.10")) {
|
||||
let topLevelProperties = [
|
||||
"purpose",
|
||||
"name",
|
||||
"path",
|
||||
"enabled",
|
||||
"comment",
|
||||
"readonly",
|
||||
"browsable",
|
||||
"access_based_share_enumeration",
|
||||
"audit",
|
||||
];
|
||||
let disallowedOptions = ["abe"];
|
||||
share.purpose = "LEGACY_SHARE";
|
||||
share.options = {
|
||||
purpose: "LEGACY_SHARE",
|
||||
};
|
||||
for (const key in share) {
|
||||
switch (key) {
|
||||
case "options":
|
||||
// ignore
|
||||
break;
|
||||
default:
|
||||
if (!topLevelProperties.includes(key)) {
|
||||
if (!disallowedOptions.includes(key)) {
|
||||
share.options[key] = share[key];
|
||||
}
|
||||
delete share[key];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (apiVersion) {
|
||||
case 1:
|
||||
endpoint = "/sharing/cifs";
|
||||
|
|
@ -2819,13 +2850,13 @@ class FreeNASApiDriver extends CsiBaseDriver {
|
|||
// set quota
|
||||
if (this.options.zfs.datasetEnableQuotas) {
|
||||
setProps = true;
|
||||
properties.refquota = capacity_bytes;
|
||||
properties.refquota = Number(capacity_bytes);
|
||||
}
|
||||
|
||||
// set reserve
|
||||
if (this.options.zfs.datasetEnableReservation) {
|
||||
setProps = true;
|
||||
properties.refreservation = capacity_bytes;
|
||||
properties.refreservation = Number(capacity_bytes);
|
||||
}
|
||||
|
||||
// quota for dataset and all children
|
||||
|
|
@ -2933,7 +2964,7 @@ class FreeNASApiDriver extends CsiBaseDriver {
|
|||
|
||||
// this should be already set, but when coming from a volume source
|
||||
// it may not match that of the source
|
||||
properties.volsize = capacity_bytes;
|
||||
properties.volsize = Number(capacity_bytes);
|
||||
|
||||
// dedup
|
||||
// on, off, verify
|
||||
|
|
@ -3221,17 +3252,17 @@ class FreeNASApiDriver extends CsiBaseDriver {
|
|||
// set quota
|
||||
if (this.options.zfs.datasetEnableQuotas) {
|
||||
setProps = true;
|
||||
properties.refquota = capacity_bytes;
|
||||
properties.refquota = Number(capacity_bytes);
|
||||
}
|
||||
|
||||
// set reserve
|
||||
if (this.options.zfs.datasetEnableReservation) {
|
||||
setProps = true;
|
||||
properties.refreservation = capacity_bytes;
|
||||
properties.refreservation = Number(capacity_bytes);
|
||||
}
|
||||
break;
|
||||
case "volume":
|
||||
properties.volsize = capacity_bytes;
|
||||
properties.volsize = Number(capacity_bytes);
|
||||
setProps = true;
|
||||
|
||||
// managed automatically for zvols
|
||||
|
|
@ -3532,6 +3563,7 @@ class FreeNASApiDriver extends CsiBaseDriver {
|
|||
const httpClient = await this.getHttpClient();
|
||||
const httpApiClient = await this.getTrueNASHttpApiClient();
|
||||
const zb = await this.getZetabyte();
|
||||
const truenasVersion = await httpApiClient.getSystemVersionSemver();
|
||||
|
||||
let entries = [];
|
||||
let entries_length = 0;
|
||||
|
|
@ -3693,11 +3725,19 @@ class FreeNASApiDriver extends CsiBaseDriver {
|
|||
response = await httpClient.get(endpoint, {
|
||||
"extra.snapshots": 1,
|
||||
"extra.snapshots_properties": JSON.stringify(zfsProperties),
|
||||
//"extra.snapshots_properties": "null",
|
||||
});
|
||||
if (response.statusCode == 404) {
|
||||
throw new Error("dataset does not exist");
|
||||
} else if (response.statusCode == 200) {
|
||||
for (let snapshot of response.body.snapshots) {
|
||||
if (semver.satisfies(truenasVersion, ">=25.10")) {
|
||||
// request the snapshot because fetching properties is broken with the dataset is broken
|
||||
snapshot.properties = await httpApiClient.SnapshotGet(
|
||||
snapshot.id,
|
||||
zfsProperties
|
||||
);
|
||||
}
|
||||
let row = {};
|
||||
for (let p in snapshot.properties) {
|
||||
row[p] = snapshot.properties[p].rawvalue;
|
||||
|
|
@ -3716,12 +3756,20 @@ class FreeNASApiDriver extends CsiBaseDriver {
|
|||
response = await httpClient.get(endpoint, {
|
||||
"extra.snapshots": 1,
|
||||
"extra.snapshots_properties": JSON.stringify(zfsProperties),
|
||||
//"extra.snapshots_properties": "null",
|
||||
});
|
||||
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) {
|
||||
if (semver.satisfies(truenasVersion, ">=25.10")) {
|
||||
// request the snapshot because fetching properties is broken with the dataset is broken
|
||||
snapshot.properties = await httpApiClient.SnapshotGet(
|
||||
snapshot.id,
|
||||
zfsProperties
|
||||
);
|
||||
}
|
||||
let row = {};
|
||||
for (let p in snapshot.properties) {
|
||||
row[p] = snapshot.properties[p].rawvalue;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
const _ = require("lodash");
|
||||
const semver = require("semver");
|
||||
const { sleep, stringify } = require("../../../utils/general");
|
||||
const { Zetabyte } = require("../../../utils/zfs");
|
||||
const { Registry } = require("../../../utils/registry");
|
||||
|
|
@ -183,6 +184,12 @@ class Api {
|
|||
return majorMinor.split(".")[0];
|
||||
}
|
||||
|
||||
async getSystemVersionSemver() {
|
||||
return semver.coerce(await this.getSystemVersionMajorMinor(), {
|
||||
loose: true,
|
||||
});
|
||||
}
|
||||
|
||||
async setVersionInfoCache(versionInfo) {
|
||||
await this.cache.set(FREENAS_SYSTEM_VERSION_CACHE_KEY, versionInfo, {
|
||||
ttl: 60 * 1000,
|
||||
|
|
@ -250,7 +257,7 @@ class Api {
|
|||
let user_properties = {};
|
||||
for (const property in properties) {
|
||||
if (this.getIsUserProperty(property)) {
|
||||
user_properties[property] = properties[property];
|
||||
user_properties[property] = String(properties[property]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +278,15 @@ class Api {
|
|||
getPropertiesKeyValueArray(properties) {
|
||||
let arr = [];
|
||||
for (const property in properties) {
|
||||
arr.push({ key: property, value: properties[property] });
|
||||
let value = properties[property];
|
||||
if (
|
||||
this.getIsUserProperty(property) &&
|
||||
value != null &&
|
||||
value !== undefined
|
||||
) {
|
||||
value = String(value);
|
||||
}
|
||||
arr.push({ key: property, value });
|
||||
}
|
||||
|
||||
return arr;
|
||||
|
|
@ -501,10 +516,17 @@ class Api {
|
|||
|
||||
async SnapshotSet(snapshotName, properties) {
|
||||
const httpClient = await this.getHttpClient(false);
|
||||
const systemVersionSemver = await this.getSystemVersionSemver();
|
||||
|
||||
let response;
|
||||
let endpoint;
|
||||
|
||||
endpoint = `/zfs/snapshot/id/${encodeURIComponent(snapshotName)}`;
|
||||
if (semver.satisfies(systemVersionSemver, ">=25.10")) {
|
||||
endpoint = `/pool/snapshot/id/${encodeURIComponent(snapshotName)}`;
|
||||
} else {
|
||||
endpoint = `/zfs/snapshot/id/${encodeURIComponent(snapshotName)}`;
|
||||
}
|
||||
|
||||
response = await httpClient.put(endpoint, {
|
||||
//...this.getSystemProperties(properties),
|
||||
user_properties_update: this.getPropertiesKeyValueArray(
|
||||
|
|
@ -529,10 +551,17 @@ class Api {
|
|||
*/
|
||||
async SnapshotGet(snapshotName, properties) {
|
||||
const httpClient = await this.getHttpClient(false);
|
||||
const systemVersionSemver = await this.getSystemVersionSemver();
|
||||
|
||||
let response;
|
||||
let endpoint;
|
||||
|
||||
endpoint = `/zfs/snapshot/id/${encodeURIComponent(snapshotName)}`;
|
||||
if (semver.satisfies(systemVersionSemver, ">=25.10")) {
|
||||
endpoint = `/pool/snapshot/id/${encodeURIComponent(snapshotName)}`;
|
||||
} else {
|
||||
endpoint = `/zfs/snapshot/id/${encodeURIComponent(snapshotName)}`;
|
||||
}
|
||||
|
||||
response = await httpClient.get(endpoint);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
|
|
@ -540,7 +569,7 @@ class Api {
|
|||
}
|
||||
|
||||
if (response.statusCode == 404) {
|
||||
throw new Error("dataset does not exist");
|
||||
throw new Error("snapshot does not exist");
|
||||
}
|
||||
|
||||
throw new Error(JSON.stringify(response.body));
|
||||
|
|
@ -549,6 +578,7 @@ class Api {
|
|||
async SnapshotCreate(snapshotName, data = {}) {
|
||||
const httpClient = await this.getHttpClient(false);
|
||||
const zb = await this.getZetabyte();
|
||||
const systemVersionSemver = await this.getSystemVersionSemver();
|
||||
|
||||
let response;
|
||||
let endpoint;
|
||||
|
|
@ -559,7 +589,12 @@ class Api {
|
|||
data.dataset = dataset;
|
||||
data.name = snapshot;
|
||||
|
||||
endpoint = "/zfs/snapshot";
|
||||
if (semver.satisfies(systemVersionSemver, ">=25.10")) {
|
||||
endpoint = "/pool/snapshot";
|
||||
} else {
|
||||
endpoint = "/zfs/snapshot";
|
||||
}
|
||||
|
||||
response = await httpClient.post(endpoint, data);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
|
|
@ -579,11 +614,17 @@ class Api {
|
|||
async SnapshotDelete(snapshotName, data = {}) {
|
||||
const httpClient = await this.getHttpClient(false);
|
||||
const zb = await this.getZetabyte();
|
||||
const systemVersionSemver = await this.getSystemVersionSemver();
|
||||
|
||||
let response;
|
||||
let endpoint;
|
||||
|
||||
endpoint = `/zfs/snapshot/id/${encodeURIComponent(snapshotName)}`;
|
||||
if (semver.satisfies(systemVersionSemver, ">=25.10")) {
|
||||
endpoint = `/pool/snapshot/id/${encodeURIComponent(snapshotName)}`;
|
||||
} else {
|
||||
endpoint = `/zfs/snapshot/id/${encodeURIComponent(snapshotName)}`;
|
||||
}
|
||||
|
||||
response = await httpClient.delete(endpoint, data);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
|
|
@ -607,6 +648,7 @@ class Api {
|
|||
async CloneCreate(snapshotName, datasetName, data = {}) {
|
||||
const httpClient = await this.getHttpClient(false);
|
||||
const zb = await this.getZetabyte();
|
||||
const systemVersionSemver = await this.getSystemVersionSemver();
|
||||
|
||||
let response;
|
||||
let endpoint;
|
||||
|
|
@ -614,7 +656,12 @@ class Api {
|
|||
data.snapshot = snapshotName;
|
||||
data.dataset_dst = datasetName;
|
||||
|
||||
endpoint = "/zfs/snapshot/clone";
|
||||
if (semver.satisfies(systemVersionSemver, ">=25.10")) {
|
||||
endpoint = "/pool/snapshot/clone";
|
||||
} else {
|
||||
endpoint = "/zfs/snapshot/clone";
|
||||
}
|
||||
|
||||
response = await httpClient.post(endpoint, data);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
|
|
|
|||
|
|
@ -269,10 +269,7 @@ class FreeNASSshDriver extends ControllerZfsBaseDriver {
|
|||
const httpApiClient = await this.getTrueNASHttpApiClient();
|
||||
const apiVersion = httpClient.getApiVersion();
|
||||
const zb = await this.getZetabyte();
|
||||
const truenasVersion = semver.coerce(
|
||||
await httpApiClient.getSystemVersionMajorMinor(),
|
||||
{ loose: true }
|
||||
);
|
||||
const truenasVersion = await httpApiClient.getSystemVersionSemver();
|
||||
|
||||
if (!truenasVersion) {
|
||||
throw new GrpcError(
|
||||
|
|
@ -594,6 +591,40 @@ class FreeNASSshDriver extends ControllerZfsBaseDriver {
|
|||
}
|
||||
}
|
||||
|
||||
if (isScale && semver.satisfies(truenasVersion, ">=25.10")) {
|
||||
let topLevelProperties = [
|
||||
"purpose",
|
||||
"name",
|
||||
"path",
|
||||
"enabled",
|
||||
"comment",
|
||||
"readonly",
|
||||
"browsable",
|
||||
"access_based_share_enumeration",
|
||||
"audit",
|
||||
];
|
||||
let disallowedOptions = ["abe"];
|
||||
share.purpose = "LEGACY_SHARE";
|
||||
share.options = {
|
||||
purpose: "LEGACY_SHARE",
|
||||
};
|
||||
for (const key in share) {
|
||||
switch (key) {
|
||||
case "options":
|
||||
// ignore
|
||||
break;
|
||||
default:
|
||||
if (!topLevelProperties.includes(key)) {
|
||||
if (!disallowedOptions.includes(key)) {
|
||||
share.options[key] = share[key];
|
||||
}
|
||||
delete share[key];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (apiVersion) {
|
||||
case 1:
|
||||
endpoint = "/sharing/cifs";
|
||||
|
|
|
|||
Loading…
Reference in New Issue