"use strict"; const Promise = require("bluebird"); const fs = Promise.promisifyAll(require("fs")); const {createDataObject, LocalProperties, ID, Dynamic} = require("../../packages/graphql-interface/data-object"); module.exports = function (types) { return function Mount({ mountpoint }) { return createDataObject({ [LocalProperties]: { mountpoint: mountpoint }, [Dynamic]: { sourceDevice: (_, { resolveDataSource }) => { // FIXME: This code is rather bulky, maybe there should be a first-class way to express "try to create a data object that may fail" return Promise.try(() => { return resolveDataSource("findmnt", mountpoint); }).then((mount) => { if (mount.sourceDevice != null) { return Promise.try(() => { return fs.realpathAsync(mount.sourceDevice); }).then((sourcePath) => { return Promise.try(() => { return resolveDataSource("lsblk", { path: sourcePath }); }).then((lsblkResult) => { if (lsblkResult != null) { return types.BlockDevice({ path: sourcePath }); } else { // This occurs when the `sourceDevice` is a valid device, but it is not a *block* device, eg. like with `/dev/fuse` return null; } }); }); } else { return null; } }); } }, findmnt: { [ID]: mountpoint, id: "id", // FIXME: Aren't we inferring the below somewhere else in the code, using the square brackets? type: (mount) => { if (mount.rootPath === "/") { return "ROOT_MOUNT"; } else { return "SUBMOUNT"; } }, // sourceDevice: (mount) => { // return Promise.try(() => { // if (mount.sourceDevice != null) { // return Promise.try(() => { // return fs.realpathAsync(mount.sourceDevice); // }).then((sourcePath) => { // return types.BlockDevice({ path: sourcePath }); // }); // } else { // return null; // } // }); // }, filesystem: "filesystem", options: "options", label: "label", uuid: "uuid", partitionLabel: "partitionLabel", partitionUUID: "partitionUUID", deviceNumber: "deviceNumber", totalSpace: "totalSpace", freeSpace: "freeSpace", usedSpace: "usedSpace", rootPath: "rootPath", taskID: "taskID", optionalFields: "optionalFields", propagationFlags: "propagationFlags", children: (mount) => { return mount.children.map((child) => { return Mount({ mountpoint: child.mountpoint }); }); } } }); }; };