"use strict"; const Promise = require("bluebird"); const fs = Promise.promisifyAll(require("fs")); const matchValue = require("match-value"); const asyncpipe = require("../../packages/asyncpipe"); const dlayerSource = require("../../packages/dlayer-source"); const All = require("../../packages/graphql-interface/symbols/all"); // FIXME: Move to dlayer-source? const treecutter = require("../../packages/treecutter"); const types = require("./"); module.exports = function BlockDevice({ name, path }) { return dlayerSource.withSources({ // TODO: Eventually make this produce a (filtered) tree instead? mounts: function ({ type }, { $getProperty, $getPropertyPath, sources }) { return Promise.try(() => { return sources.findmnt.load(All); }).then((mountTree) => { return asyncpipe(mountTree, [ (_) => treecutter.flatten(_), (_) => _.map((mount) => types.Mount({ mountpoint: mount.mountpoint })), (_) => Promise.filter(_, async (mount) => { let sourcePath = await $getPropertyPath(mount, "sourceDevice.path"); let sourceName = await $getPropertyPath(mount, "sourceDevice.name"); return ( (sourcePath != null && sourcePath === path) || (sourceName != null && sourceName === name) ); }) ]); }).then((relevantMounts) => { if (type == null) { return relevantMounts; } else { return Promise.filter(relevantMounts, async (mount) => { return (await $getProperty(mount, "type") === type); }); } }); }, $sources: { lsblk: { [dlayerSource.ID]: { name, path }, name: "name", path: (device) => fs.realpathAsync(device.path), type: (device) => matchValue(device.type, { partition: "PARTITION", disk: "DISK", loopDevice: "LOOP_DEVICE" }), size: "size", mountpoint: "mountpoint", // FIXME: Isn't this obsoleted by `mounts`? deviceNumber: "deviceNumber", removable: "removable", readOnly: "readOnly", children: (device) => device.children.map((child) => { return BlockDevice({ name: child.name }); }) } } }); };