diff --git a/CHANGELOG.md b/CHANGELOG.md index 864ef4f8..77e5161a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY! This project adheres to [Semantic Versioning](http://semver.org/). +## v6.2.0 - 2018-05-09 + +* Feat(linux): Add unique device path #278 [User Name] + ## v6.1.8 - 2018-04-26 * Chore(ci): Build, test & publish releases for Node.js v10 #273 [Tim Perry] diff --git a/lib/diskutil.js b/lib/diskutil.js index 7f3e3e20..d9e58c83 100644 --- a/lib/diskutil.js +++ b/lib/diskutil.js @@ -106,6 +106,7 @@ const transform = (disk) => { busType: disk.BusProtocol || 'UNKNOWN', busVersion: null, device: disk.DeviceNode, + devicePath: null, raw: disk.DeviceNode && disk.DeviceNode.replace('/disk', '/rdisk'), description: disk.IORegistryEntryName || disk.MediaName, error: null, diff --git a/lib/scripts.json b/lib/scripts.json index f4f8c3c4..1b9ca970 100644 --- a/lib/scripts.json +++ b/lib/scripts.json @@ -1,6 +1,6 @@ { "linux": { - "content": "#!/bin/bash\n\nset -u\nset -e\n\nignore_first_line() {\n tail -n +2\n}\n\nget_uuids() {\n /sbin/blkid -s UUID -o value \"$1\"*\n}\n\nget_mountpoints() {\n grep \"^$1\" /proc/mounts | cut -d ' ' -f 2 | sed 's,\\\\040, ,g' | sed 's,\\\\011,\\t,g' | sed 's,\\\\012,\\\\n,g' | sed 's,\\\\134,\\\\\\\\,g'\n}\n\nDISKS=\"$(lsblk -d --output NAME | ignore_first_line)\"\n\nfor disk in $DISKS; do\n\n # Omit loop devices and CD/DVD drives\n if [[ $disk == loop* ]] || [[ $disk == sr* ]]; then\n continue\n fi\n\n device=\"/dev/$disk\"\n diskinfo=($(lsblk -b -d \"$device\" --output SIZE,RO,RM,MODEL | ignore_first_line))\n\n # Omit drives for which `lsblk` failed, which means they\n # were unplugged right after we got the list of all drives\n if [ -z \"${diskinfo-}\" ]; then\n continue\n fi\n\n size=${diskinfo[0]}\n protected=${diskinfo[1]}\n removable=${diskinfo[2]}\n description=${diskinfo[*]:3}\n mountpoints=\"$(get_mountpoints \"$device\")\"\n\n # If we couldn't get the mount points as `/dev/$disk`,\n # get the disk UUIDs, and check as `/dev/disk/by-uuid/$uuid`\n if [ -z \"$mountpoints\" ]; then\n for uuid in $(get_uuids \"$device\"); do\n mountpoints=\"$mountpoints$(get_mountpoints \"/dev/disk/by-uuid/$uuid\")\"\n done\n fi\n\n # If we couldn't get the description from `lsblk`, see if we can get it\n # from sysfs (e.g. PCI-connected SD cards that appear as `/dev/mmcblk0`)\n if [ -z \"$description\" ]; then\n subdevice=\"$(echo \"$device\" | cut -d '/' -f 3)\"\n if [ -f \"/sys/class/block/$subdevice/device/name\" ]; then\n description=\"$(cat \"/sys/class/block/$subdevice/device/name\")\"\n fi\n fi\n\n echo \"enumerator: lsblk\"\n echo \"busType: UNKNOWN\"\n echo \"busVersion: \\\"0.0\\\"\"\n echo \"device: $device\"\n echo \"raw: $device\"\n echo \"description: \\\"$description\\\"\"\n echo \"error: null\"\n echo \"size: $size\"\n echo \"blockSize: null\"\n echo \"logicalBlockSize: null\"\n\n if [ -z \"$mountpoints\" ]; then\n echo \"mountpoints: []\"\n else\n echo \"mountpoints:\"\n echo \"$mountpoints\" | while read -r mountpoint ; do\n echo \" - path: \\\"$mountpoint\\\"\"\n done\n fi\n\n if [[ \"$protected\" == \"1\" ]]; then\n echo \"isReadOnly: True\"\n else\n echo \"isReadOnly: False\"\n fi\n\n eval \"$(udevadm info \\\n --query=property \\\n --export \\\n --export-prefix=UDEV_ \\\n --name=\"$disk\" \\\n | awk -F= '{gsub(\"\\\\.\",\"_\",$1); print $1 \"=\" $2}')\"\n\n set +u\n\n if [[ \"$removable\" == \"1\" ]] && \\\n [[ \"$UDEV_ID_DRIVE_FLASH_SD\" == \"1\" ]] || \\\n [[ \"$UDEV_ID_DRIVE_MEDIA_FLASH_SD\" == \"1\" ]] || \\\n [[ \"$UDEV_ID_BUS\" == \"usb\" ]]\n then\n echo \"isSystem: False\"\n else\n echo \"isSystem: True\"\n fi\n\n echo \"isVirtual: null\"\n echo \"isRemovable: null\"\n echo \"isCard: null\"\n echo \"isSCSI: null\"\n echo \"isUSB: null\"\n echo \"isUAS: null\"\n\n set -u\n\n # Unset UDEV variables used above to prevent them from\n # being interpreted as properties of another drive\n unset UDEV_ID_DRIVE_FLASH_SD\n unset UDEV_ID_DRIVE_MEDIA_FLASH_SD\n unset UDEV_ID_BUS\n\n echo \"\"\ndone\n", + "content": "#!/bin/bash\n\nset -u\nset -e\n\nignore_first_line() {\n tail -n +2\n}\n\nget_uuids() {\n /sbin/blkid -s UUID -o value \"$1\"*\n}\n\nget_mountpoints() {\n grep \"^$1\" /proc/mounts | cut -d ' ' -f 2 | sed 's,\\\\040, ,g' | sed 's,\\\\011,\\t,g' | sed 's,\\\\012,\\\\n,g' | sed 's,\\\\134,\\\\\\\\,g'\n}\n\nget_path_id() {\n # udevadm test-builtin path_id /sys/block/sda | grep ID_PATH=\n find -L /dev/disk/by-path/ -samefile \"$1\" | cut -c 19-\n}\n\nDISKS=\"$(lsblk -d --output NAME | ignore_first_line)\"\n\nfor disk in $DISKS; do\n\n # Omit loop devices and CD/DVD drives\n if [[ $disk == loop* ]] || [[ $disk == sr* ]]; then\n continue\n fi\n\n device=\"/dev/$disk\"\n diskinfo=($(lsblk -b -d \"$device\" --output SIZE,RO,RM,MODEL | ignore_first_line))\n\n # Omit drives for which `lsblk` failed, which means they\n # were unplugged right after we got the list of all drives\n if [ -z \"${diskinfo-}\" ]; then\n continue\n fi\n\n size=${diskinfo[0]}\n protected=${diskinfo[1]}\n removable=${diskinfo[2]}\n description=${diskinfo[*]:3}\n mountpoints=\"$(get_mountpoints \"$device\")\"\n devicePath=\"$(get_path_id \"$device\")\"\n\n # If we couldn't get the mount points as `/dev/$disk`,\n # get the disk UUIDs, and check as `/dev/disk/by-uuid/$uuid`\n if [ -z \"$mountpoints\" ]; then\n for uuid in $(get_uuids \"$device\"); do\n mountpoints=\"$mountpoints$(get_mountpoints \"/dev/disk/by-uuid/$uuid\")\"\n done\n fi\n\n # If we couldn't get the description from `lsblk`, see if we can get it\n # from sysfs (e.g. PCI-connected SD cards that appear as `/dev/mmcblk0`)\n if [ -z \"$description\" ]; then\n subdevice=\"$(echo \"$device\" | cut -d '/' -f 3)\"\n if [ -f \"/sys/class/block/$subdevice/device/name\" ]; then\n description=\"$(cat \"/sys/class/block/$subdevice/device/name\")\"\n fi\n fi\n\n echo \"enumerator: lsblk\"\n echo \"busType: UNKNOWN\"\n echo \"busVersion: \\\"0.0\\\"\"\n echo \"device: $device\"\n echo \"devicePath: $devicePath\"\n echo \"raw: $device\"\n echo \"description: \\\"$description\\\"\"\n echo \"error: null\"\n echo \"size: $size\"\n echo \"blockSize: null\"\n echo \"logicalBlockSize: null\"\n\n if [ -z \"$mountpoints\" ]; then\n echo \"mountpoints: []\"\n else\n echo \"mountpoints:\"\n echo \"$mountpoints\" | while read -r mountpoint ; do\n echo \" - path: \\\"$mountpoint\\\"\"\n done\n fi\n\n if [[ \"$protected\" == \"1\" ]]; then\n echo \"isReadOnly: True\"\n else\n echo \"isReadOnly: False\"\n fi\n\n eval \"$(udevadm info \\\n --query=property \\\n --export \\\n --export-prefix=UDEV_ \\\n --name=\"$disk\" \\\n | awk -F= '{gsub(\"\\\\.\",\"_\",$1); print $1 \"=\" $2}')\"\n\n set +u\n\n if [[ \"$removable\" == \"1\" ]] && \\\n [[ \"$UDEV_ID_DRIVE_FLASH_SD\" == \"1\" ]] || \\\n [[ \"$UDEV_ID_DRIVE_MEDIA_FLASH_SD\" == \"1\" ]] || \\\n [[ \"$UDEV_ID_BUS\" == \"usb\" ]]\n then\n echo \"isSystem: False\"\n else\n echo \"isSystem: True\"\n fi\n\n echo \"isVirtual: null\"\n echo \"isRemovable: null\"\n echo \"isCard: null\"\n echo \"isSCSI: null\"\n echo \"isUSB: null\"\n echo \"isUAS: null\"\n\n set -u\n\n # Unset UDEV variables used above to prevent them from\n # being interpreted as properties of another drive\n unset UDEV_ID_DRIVE_FLASH_SD\n unset UDEV_ID_DRIVE_MEDIA_FLASH_SD\n unset UDEV_ID_BUS\n\n echo \"\"\ndone\n", "originalFilename": "linux.sh", "type": "text" } diff --git a/package.json b/package.json index 33259993..16810e39 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "drivelist", - "version": "6.1.8", + "version": "6.2.0", "description": "List all connected drives in your computer, in all major operating systems", "main": "lib/drivelist.js", "homepage": "https://github.com/resin-io-modules/drivelist", diff --git a/scripts/linux.sh b/scripts/linux.sh index 90235138..4ca12775 100755 --- a/scripts/linux.sh +++ b/scripts/linux.sh @@ -15,6 +15,11 @@ get_mountpoints() { grep "^$1" /proc/mounts | cut -d ' ' -f 2 | sed 's,\\040, ,g' | sed 's,\\011,\t,g' | sed 's,\\012,\\n,g' | sed 's,\\134,\\\\,g' } +get_path_id() { + # udevadm test-builtin path_id /sys/block/sda | grep ID_PATH= + find -L /dev/disk/by-path/ -samefile "$1" | cut -c 19- +} + DISKS="$(lsblk -d --output NAME | ignore_first_line)" for disk in $DISKS; do @@ -38,6 +43,7 @@ for disk in $DISKS; do removable=${diskinfo[2]} description=${diskinfo[*]:3} mountpoints="$(get_mountpoints "$device")" + devicePath="$(get_path_id "$device")" # If we couldn't get the mount points as `/dev/$disk`, # get the disk UUIDs, and check as `/dev/disk/by-uuid/$uuid` @@ -60,6 +66,7 @@ for disk in $DISKS; do echo "busType: UNKNOWN" echo "busVersion: \"0.0\"" echo "device: $device" + echo "devicePath: $devicePath" echo "raw: $device" echo "description: \"$description\"" echo "error: null" diff --git a/src/device-descriptor.cpp b/src/device-descriptor.cpp index 2daae090..ef0a9b66 100644 --- a/src/device-descriptor.cpp +++ b/src/device-descriptor.cpp @@ -43,6 +43,10 @@ v8::Local PackDriveDescriptor(const DeviceDescriptor *instance) { New("device").ToLocalChecked(), New(instance->device).ToLocalChecked()); + Nan::Set(object, + New("devicePath").ToLocalChecked(), + Nan::Null()); + Nan::Set(object, New("raw").ToLocalChecked(), New(instance->raw).ToLocalChecked()); diff --git a/src/drivelist.hpp b/src/drivelist.hpp index 3ed73b26..dda63742 100644 --- a/src/drivelist.hpp +++ b/src/drivelist.hpp @@ -32,6 +32,7 @@ struct DeviceDescriptor { std::string busType; std::string busVersion; std::string device; + std::string devicePath; std::string raw; std::string description; std::string error; diff --git a/tests/diskutil.spec.js b/tests/diskutil.spec.js index 7e08ac7c..68de0acd 100644 --- a/tests/diskutil.spec.js +++ b/tests/diskutil.spec.js @@ -44,6 +44,7 @@ describe('Drivelist', function() { busType: 'PCI-Express', busVersion: null, device: '/dev/disk1', + devicePath: null, raw: '/dev/rdisk1', description: 'Macintosh HD', error: null,