diff --git a/src/packages/sysquery-block-devices/index.js b/src/packages/sysquery-block-devices/index.js index 7143195..4bc590d 100644 --- a/src/packages/sysquery-block-devices/index.js +++ b/src/packages/sysquery-block-devices/index.js @@ -4,6 +4,7 @@ const DataLoader = require("dataloader"); const fs = require("fs").promises; const matchValue = require("match-value"); const memoizee = require("memoizee"); +const { InvalidObject } = require("dlayer"); const unreachable = require("@joepie91/unreachable")("@sysquery/block-devices"); const dlayerSource = require("../dlayer-source"); @@ -13,6 +14,7 @@ const mapFromSource = require("../map-from-source"); const treeMapAsync = require("../tree-map-async"); const treeFind = require("../tree-find"); + function makePredicate({ path, name }) { if (path != null) { return (device) => device.path === path; @@ -36,6 +38,7 @@ module.exports = { }); return { + // FIXME: This is probably broken; {path,name} selectors are always unique keys! lsblk: new DataLoader(async function (selectors) { let blockDeviceTree = await lsblkOnce(); @@ -50,46 +53,47 @@ module.exports = { }; }, types: { - "sysquery.blockDevices.BlockDevice": function ({ name, path }) { - return { - ... dlayerSource("lsblk", { - [dlayerSource.ID]: { name, path }, - name: "name", - path: (device) => fs.realpath(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, { $make }) => device.children.map((child) => { - return $make("sysquery.blockDevices.BlockDevice", { name: child.name }); + "sysquery.blockDevices.BlockDevice": async function ({ name, path }, { lsblk }) { + let entry = await lsblk.load({ name, path }); + + if (entry != null) { + return { + ... dlayerSource("lsblk", { + [dlayerSource.ID]: { name, path }, + name: "name", + path: (device) => fs.realpath(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, { $make }) => device.children.map((child) => { + return $make("sysquery.blockDevices.BlockDevice", { name: child.name }); + }) }) - }) - }; + }; + } else { + return InvalidObject; + } } }, extensions: { "sysquery.mounts.Mount": { - sourceDevice: async function (_, { lsblk, $make, $getProperty }) { + sourceDevice: async function (_, { $make, $getProperty }) { let sourceDevicePath = await $getProperty(this, "sourceDevicePath"); if (sourceDevicePath == null) { // This occurs when the mount is not backed by a device, eg. an sshfs FUSE mount return null; } else { - let realSourcePath = await fs.realpath(sourceDevicePath); - - if (await lsblk.load({ path: realSourcePath }) != null) { - return $make("sysquery.blockDevices.BlockDevice", { path: realSourcePath }); - } else { - // This occurs when the `sourceDevice` is a valid device, but it is not a *block* device, eg. `/dev/fuse` - return null; - } + return $make("sysquery.blockDevices.BlockDevice", { + path: await fs.realpath(sourceDevicePath) + }); } } }