You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cvm/src/api/types/drive.js

98 lines
2.9 KiB
JavaScript

"use strict";
const Promise = require("bluebird");
const dlayerSource = require("../../packages/dlayer-source");
const treecutter = require("../../packages/treecutter");
const upperSnakeCase = require("../../packages/upper-snake-case");
const types = require("./");
module.exports = function Drive ({ path }) {
return dlayerSource.withSources({
path: path,
blockDevice: async function(_, { $getProperty }) {
if (await $getProperty(this, "interface") === "nvme") {
return null;
} else {
return types.BlockDevice({ path: path });
}
},
allBlockDevices: async function(_, { $getProperty, sources }) {
return Promise.try(async () => {
if (await $getProperty(this, "interface") === "nvme") {
return Promise.try(() => {
return sources.nvmeListNamespaces.load(path);
}).map((namespaceID) => {
return `${path}n${namespaceID}`;
});
} else {
return [ path ];
}
}).then((rootPaths) => {
let queries = rootPaths.map((path) => ({ path: path }));
return sources.lsblk.loadMany(queries);
}).map((blockDeviceTree) => {
return treecutter.map(blockDeviceTree, (device) => types.BlockDevice(device));
}).then((resultArray) => {
// Treecutter always returns an array, regardless of whether the input was an array or not, so we need to flatten it since we will only ever have a single root entry per rootPath query here
return resultArray.flat();
});
},
$sources: {
// lsblk: {
// [dlayerSource.ID]: { path },
// },
smartctlScan: {
[dlayerSource.ID]: path,
interface: "interface"
},
smartctlInfo: {
[dlayerSource.ID]: path,
model: "model",
modelFamily: "modelFamily",
smartAvailable: "smartAvailable",
smartEnabled: "smartEnabled",
serialNumber: "serialNumber",
wwn: "wwn",
firmwareVersion: "firmwareVersion",
size: "size",
rpm: "rpm",
logicalSectorSize: (device) => device.sectorSizes.logical,
physicalSectorSize: (device) => device.sectorSizes.physical,
formFactor: "formFactor",
ataVersion: "ataVersion",
sataVersion: "sataVersion"
},
smartctlAttributes: {
[dlayerSource.ID]: path,
smartAttributes: (attributes) => {
return attributes.map((attribute) => {
return {
... attribute,
type: upperSnakeCase(attribute.type),
updatedWhen: upperSnakeCase(attribute.updatedWhen)
};
});
},
smartHealth: (attributes) => {
let failed = attributes.filter((item) => {
return (item.failingNow === true || item.failedBefore === true);
});
let deteriorating = attributes.filter((item) => {
return (item.type === "preFail" && item.worstValueSeen < 100);
});
if (failed.length > 0) {
return "FAILING";
} else if (deteriorating.length > 0) {
return "DETERIORATING";
} else {
return "HEALTHY";
}
}
}
}
});
};