'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; }