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/routes/storage-devices.js

98 lines
2.9 KiB
JavaScript

'use strict';
const Promise = require("bluebird");
const lsblk = require("../wrappers/lsblk");
const smartctl = require("../wrappers/smartctl");
const lvm = require("../wrappers/lvm");
const {B} = require("../units/bytes/iec");
/* FIXME: Move this to GraphQL API */
function getSmartStatus(smartData) {
let failed = smartData.filter((item) => {
return (item.failingNow === true || item.failedBefore === true);
});
let deteriorating = smartData.filter((item) => {
return (item.type === "preFail" && item.worstValueSeen < 100);
});
if (failed.length > 0) {
return "failed";
} else if (deteriorating.length > 0) {
return "deteriorating";
} else {
return "healthy";
}
}
function getStorageDevices() {
return Promise.try(() => {
return lsblk();
}).filter((device) => {
return (device.type === "disk");
}).map((device) => {
return Object.assign({}, device, {
path: `/dev/${device.name}`
});
}).map((device) => {
/* FIXME: Check whether we need to iterate through child disks as well, when dealing with eg. RAID arrays */
return Promise.try(() => {
return Promise.all([
smartctl.info({ devicePath: device.path }),
smartctl.attributes({ devicePath: device.path })
]);
}).then(([info, attributes]) => {
return Object.assign({}, device, {
information: info,
smartData: attributes,
smartStatus: getSmartStatus(attributes)
});
});
}).then((blockDevices) => {
console.log(blockDevices);
return blockDevices;
});
}
function sumDriveSizes(drives) {
return drives.reduce((total, device) => {
return total + device.size.toB().amount;
}, 0);
}
function roundUnit(unit) {
return Object.assign(unit, {
amount: Math.round(unit.amount * 100) / 100
});
}
module.exports = function({db}) {
let router = require("express-promise-router")();
router.get("/", (req, res) => {
return Promise.try(() => {
return getStorageDevices();
}).then((devices) => {
/* FIXME: Auto-formatting of total sizes and units */
let fixedDrives = devices.filter((drive) => drive.removable === false);
let removableDrives = devices.filter((drive) => drive.removable === true);
let healthyFixedDrives = fixedDrives.filter((drive) => drive.smartStatus === "healthy");
let deterioratingFixedDrives = fixedDrives.filter((drive) => drive.smartStatus === "deteriorating");
let failingFixedDrives = fixedDrives.filter((drive) => drive.smartStatus === "failing");
res.render("hardware/storage-devices/list", {
devices: devices,
totalFixedStorage: roundUnit(B(sumDriveSizes(fixedDrives)).toTiB()),
totalHealthyFixedStorage: roundUnit(B(sumDriveSizes(healthyFixedDrives)).toTiB()),
totalDeterioratingFixedStorage: roundUnit(B(sumDriveSizes(deterioratingFixedDrives)).toTiB()),
totalFailingFixedStorage: roundUnit(B(sumDriveSizes(failingFixedDrives)).toTiB()),
totalRemovableStorage: roundUnit(B(sumDriveSizes(removableDrives)).toGiB())
});
});
});
return router;
}