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

90 lines
2.6 KiB
JavaScript

"use strict";
const Promise = require("bluebird");
const {createDataObject, LocalProperties, ID} = require("../../graphql/data-object");
const upperSnakeCase = require("../../upper-snake-case");
const linearizeTree = require("../../linearize-tree");
const deviceNameFromPath = require("../../device-name-from-path");
module.exports = function (types) {
return function Drive({ path }) {
return createDataObject({
[LocalProperties]: {
path: path,
blockDevice: () => {
return types.BlockDevice({ path: path });
},
/* FIXME: allBlockDevices, for representing every single block device that's hosted on this physical drive, linearly. Need to figure out how that works with representation of mdraid arrays, LVM volumes, etc. */
},
lsblk: {
[ID]: deviceNameFromPath(path),
allBlockDevices: function (rootDevice, { type }, context) {
let devices = linearizeTree([rootDevice])
.map((device) => types.BlockDevice({ name: device.name }));
if (type != null) {
return Promise.filter(devices, (device) => {
return Promise.try(() => {
return device.type({}, context);
}).then((deviceType) => {
return (deviceType === type);
});
});
} else {
return devices;
}
}
},
smartctlScan: {
[ID]: path,
interface: "interface"
},
smartctlInfo: {
[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: {
[ID]: path,
smartAttributes: (attributes) => {
return attributes.map((attribute) => {
return Object.assign({}, 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";
}
}
}
});
};
};