fix drive name normalization (#74)
This commit is contained in:
@@ -118,6 +118,11 @@ local function smartDeviceFor(path)
|
|||||||
return controller ~= nil and "/dev/" .. controller or tostring(path)
|
return controller ~= nil and "/dev/" .. controller or tostring(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function deviceBasename(value)
|
||||||
|
local normalized = tostring(value or ""):gsub("/+$", "")
|
||||||
|
return normalized:match("([^/]+)$") or ""
|
||||||
|
end
|
||||||
|
|
||||||
local function listDirectory(path)
|
local function listDirectory(path)
|
||||||
local entries = noctalia.listDir(path)
|
local entries = noctalia.listDir(path)
|
||||||
return type(entries) == "table" and entries or {}
|
return type(entries) == "table" and entries or {}
|
||||||
@@ -765,8 +770,13 @@ local function normalizeRaw(raw, source)
|
|||||||
|
|
||||||
local disks = {}
|
local disks = {}
|
||||||
for _, block in ipairs(lsblk.blockdevices or {}) do
|
for _, block in ipairs(lsblk.blockdevices or {}) do
|
||||||
local device = tostring(block.path or ("/dev/" .. tostring(block.name or "")))
|
local device = tostring(block.path or "")
|
||||||
local name = tostring(block.name or "")
|
local name = deviceBasename(block.name)
|
||||||
|
if name == "" then name = deviceBasename(block.kname) end
|
||||||
|
if name == "" then name = deviceBasename(device) end
|
||||||
|
if not device:match("^/dev/") and name ~= "" then device = "/dev/" .. name end
|
||||||
|
local kernelName = deviceBasename(block.kname)
|
||||||
|
if kernelName == "" then kernelName = name end
|
||||||
local virtual = name:match("^zram") or name:match("^loop") or name:match("^ram") or name:match("^sr")
|
local virtual = name:match("^zram") or name:match("^loop") or name:match("^ram") or name:match("^sr")
|
||||||
if block.type == "disk" and device:match("^/dev/") and not virtual then
|
if block.type == "disk" and device:match("^/dev/") and not virtual then
|
||||||
local smartDevice = smartDeviceFor(device)
|
local smartDevice = smartDeviceFor(device)
|
||||||
@@ -789,7 +799,7 @@ local function normalizeRaw(raw, source)
|
|||||||
local model = noctalia.string.trim(tostring(block.model or ""))
|
local model = noctalia.string.trim(tostring(block.model or ""))
|
||||||
local namespace = name:match("^nvme%d+(n%d+)$")
|
local namespace = name:match("^nvme%d+(n%d+)$")
|
||||||
local id = serial ~= "" and serial .. (namespace ~= nil and ":" .. namespace or "")
|
local id = serial ~= "" and serial .. (namespace ~= nil and ":" .. namespace or "")
|
||||||
or tostring(block.kname or device)
|
or (kernelName ~= "" and kernelName or device)
|
||||||
local preferences = preferenceFor(id)
|
local preferences = preferenceFor(id)
|
||||||
local removable = block.rm == true or tonumber(block.rm) == 1 or block.hotplug == true or tonumber(block.hotplug) == 1
|
local removable = block.rm == true or tonumber(block.rm) == 1 or block.hotplug == true or tonumber(block.hotplug) == 1
|
||||||
local transport = tostring(block.tran or "unknown")
|
local transport = tostring(block.tran or "unknown")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
id = "gustav0ar/drive-health"
|
id = "gustav0ar/drive-health"
|
||||||
name = "Drive Health"
|
name = "Drive Health"
|
||||||
version = "1.2.0"
|
version = "1.2.1"
|
||||||
plugin_api = 3
|
plugin_api = 3
|
||||||
author = "Drive Health contributors"
|
author = "Drive Health contributors"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ lsblk --nodeps --noheadings --paths --output PATH,TYPE,ROTA >"$devices_tmp"
|
|||||||
{
|
{
|
||||||
printf '{"schema":2,"collector_version":"%s","collection_id":"%s","generated_at_epoch":%s,"lsblk":' \
|
printf '{"schema":2,"collector_version":"%s","collection_id":"%s","generated_at_epoch":%s,"lsblk":' \
|
||||||
"$collector_version" "$collection_id" "$generated_at_epoch"
|
"$collector_version" "$collection_id" "$generated_at_epoch"
|
||||||
lsblk --json --bytes --output \
|
lsblk --json --bytes --paths --output \
|
||||||
NAME,KNAME,PATH,PKNAME,TYPE,TRAN,ROTA,RM,HOTPLUG,SIZE,LOG-SEC,PHY-SEC,MODEL,SERIAL,FSTYPE,FSSIZE,FSUSED,FSAVAIL,MOUNTPOINTS
|
NAME,KNAME,PATH,PKNAME,TYPE,TRAN,ROTA,RM,HOTPLUG,SIZE,LOG-SEC,PHY-SEC,MODEL,SERIAL,FSTYPE,FSSIZE,FSUSED,FSAVAIL,MOUNTPOINTS
|
||||||
printf ',"smart":['
|
printf ',"smart":['
|
||||||
|
|
||||||
|
|||||||
@@ -392,10 +392,10 @@ local normalized, normalizeError = normalizeRaw({
|
|||||||
generated_at_epoch = 1700000000,
|
generated_at_epoch = 1700000000,
|
||||||
lsblk = { blockdevices = {
|
lsblk = { blockdevices = {
|
||||||
{
|
{
|
||||||
name = "nvme9n1", kname = "nvme9n1", path = "/dev/nvme9n1", type = "disk",
|
name = "/dev/nvme9n1", kname = "/dev/nvme9n1", path = "/dev/nvme9n1", type = "disk",
|
||||||
tran = "nvme", rota = false, size = 2000000000, model = "Fixture NVMe", serial = "FIXTURE1",
|
tran = "nvme", rota = false, size = 2000000000, model = "Fixture NVMe", serial = "FIXTURE1",
|
||||||
mountpoints = {}, children = {
|
mountpoints = {}, children = {
|
||||||
{ name = "nvme9n1p1", kname = "nvme9n1p1", path = "/dev/nvme9n1p1", type = "part",
|
{ name = "/dev/nvme9n1p1", kname = "/dev/nvme9n1p1", path = "/dev/nvme9n1p1", type = "part",
|
||||||
mountpoints = { "/mnt/work" }, fsused = 250, fsavail = 750 },
|
mountpoints = { "/mnt/work" }, fsused = 250, fsavail = 750 },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -485,15 +485,17 @@ assert(sleeping.summary.sleeping_count == 1 and sleeping.summary.smart_unavailab
|
|||||||
local namespaces = assert(normalizeRaw({
|
local namespaces = assert(normalizeRaw({
|
||||||
schema = 2, generated_at_epoch = 1700000000,
|
schema = 2, generated_at_epoch = 1700000000,
|
||||||
lsblk = { blockdevices = {
|
lsblk = { blockdevices = {
|
||||||
{ name = "nvme0n1", kname = "nvme0n1", path = "/dev/nvme0n1", type = "disk",
|
{ name = "/dev/nvme0n1", kname = "/dev/nvme0n1", path = "/dev/nvme0n1", type = "disk",
|
||||||
tran = "nvme", rota = false, serial = "SHARED", children = {} },
|
tran = "nvme", rota = false, serial = "SHARED", children = {} },
|
||||||
{ name = "nvme0n2", kname = "nvme0n2", path = "/dev/nvme0n2", type = "disk",
|
{ name = "/dev/nvme0n2", kname = "/dev/nvme0n2", path = "/dev/nvme0n2", type = "disk",
|
||||||
tran = "nvme", rota = false, serial = "SHARED", children = {} },
|
tran = "nvme", rota = false, serial = "SHARED", children = {} },
|
||||||
|
{ name = "/dev/zram0", kname = "/dev/zram0", path = "/dev/zram0", type = "disk",
|
||||||
|
rota = false, serial = "VIRTUAL", children = {} },
|
||||||
} }, smart = {},
|
} }, smart = {},
|
||||||
}, "test"))
|
}, "test"))
|
||||||
assert(namespaces.disks[1].id ~= namespaces.disks[2].id
|
assert(#namespaces.disks == 2, "absolute zram name was not excluded from physical drive inventory")
|
||||||
and namespaces.disks[1].id:match(":n%d+$") and namespaces.disks[2].id:match(":n%d+$"),
|
assert(namespaces.disks[1].id == "SHARED:n1" and namespaces.disks[2].id == "SHARED:n2",
|
||||||
"NVMe namespaces sharing a controller serial did not receive unique IDs")
|
"absolute NVMe names did not receive stable namespace-qualified IDs")
|
||||||
|
|
||||||
local empty = assert(normalizeRaw({
|
local empty = assert(normalizeRaw({
|
||||||
schema = 2, collection_id = " ", generated_at_epoch = 1700000000,
|
schema = 2, collection_id = " ", generated_at_epoch = 1700000000,
|
||||||
|
|||||||
+4
-3
@@ -3,12 +3,13 @@ set -eu
|
|||||||
|
|
||||||
case " $* " in
|
case " $* " in
|
||||||
*" --nodeps "*)
|
*" --nodeps "*)
|
||||||
printf '%s\n' "/dev/sda disk 1" "/dev/nvme0n1 disk 0"
|
printf '%s\n' "/dev/sda disk 1" "/dev/nvme0n1 disk 0" "/dev/zram0 disk 0"
|
||||||
;;
|
;;
|
||||||
*" --json "*)
|
*" --json "*)
|
||||||
printf '%s\n' '{"blockdevices":[' \
|
printf '%s\n' '{"blockdevices":[' \
|
||||||
'{"name":"sda","kname":"sda","path":"/dev/sda","type":"disk","tran":"sata","rota":true,"size":1000000000,"model":"Fixture SATA","serial":"SATA1","mountpoints":[]},' \
|
'{"name":"/dev/sda","kname":"/dev/sda","path":"/dev/sda","type":"disk","tran":"sata","rota":true,"size":1000000000,"model":"Fixture SATA","serial":"SATA1","mountpoints":[]},' \
|
||||||
'{"name":"nvme0n1","kname":"nvme0n1","path":"/dev/nvme0n1","type":"disk","tran":"nvme","rota":false,"size":2000000000,"model":"Fixture NVMe","serial":"NVME1","mountpoints":[]}' \
|
'{"name":"/dev/nvme0n1","kname":"/dev/nvme0n1","path":"/dev/nvme0n1","type":"disk","tran":"nvme","rota":false,"size":2000000000,"model":"Fixture NVMe","serial":"NVME1","mountpoints":[]},' \
|
||||||
|
'{"name":"/dev/zram0","kname":"/dev/zram0","path":"/dev/zram0","type":"disk","rota":false,"size":4294967296,"mountpoints":[]}' \
|
||||||
']}'
|
']}'
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ printf '%s\n' "$payload" | jq -e '
|
|||||||
.schema == 2
|
.schema == 2
|
||||||
and .collector_version == "2.0.0"
|
and .collector_version == "2.0.0"
|
||||||
and (.collection_id | type == "string" and length > 0)
|
and (.collection_id | type == "string" and length > 0)
|
||||||
and (.lsblk.blockdevices | length) == 2
|
and ([.lsblk.blockdevices[].name] | sort) == ["/dev/nvme0n1", "/dev/sda", "/dev/zram0"]
|
||||||
and (.smart | length) == 2
|
and (.smart | length) == 2
|
||||||
and ([.smart[].requested_device] | sort) == ["/dev/nvme0", "/dev/sda"]
|
and ([.smart[].requested_device] | sort) == ["/dev/nvme0", "/dev/sda"]
|
||||||
and (.smart[] | select(.requested_device == "/dev/sda") | .payload.test_standby) == true
|
and (.smart[] | select(.requested_device == "/dev/sda") | .payload.test_standby) == true
|
||||||
|
|||||||
Reference in New Issue
Block a user