diff --git a/README.md b/README.md index f23bfc6..c74e630 100644 --- a/README.md +++ b/README.md @@ -143,9 +143,7 @@ A xapi plugin to get the lsblk output on the host. ### `list_block_devices`: ``` $ xe host-call-plugin host-uuid= plugin=lsblk.py fn=list_block_devices -{ - "blockdevices": [{"kname": "sdb", "name": "sdb", "pkname": "", "mountpoint": "", "ro": "0", "type": "disk", "size": "64424509440"}, {"kname": "sda", "name": "sda", "pkname": "", "mountpoint": "", "ro": "0", "type": "disk", "children": [{"kname": "sda4", "name": "sda4", "pkname": "sda", "mountpoint": "", "ro": "0", "type": "part", "size": "536870912"}, {"kname": "sda2", "name": "sda2", "pkname": "sda", "mountpoint": "", "ro": "0", "type": "part", "size": "19327352832"}, {"kname": "sda5", "name": "sda5", "pkname": "sda", "mountpoint": "/var/log", "ro": "0", "type": "part", "size": "4294967296"}, {"kname": "sda3", "name": "sda3", "pkname": "sda", "mountpoint": "", "ro": "0", "type": "part", "children": [{"kname": "dm-0", "name": "XSLocalEXT--1fad55d2--4f07--8145--c78a--297b173e06b0-1fad55d2--4f07--8145--c78a--297b173e06b0", "pkname": "sda3", "mountpoint": "/run/sr-mount/1fad55d2-4f07-8145-c78a-297b173e06b0", "ro": "0", "type": "lvm", "size": "19847446528"}], "size": "19863158272"}, {"kname": "sda1", "name": "sda1", "pkname": "sda", "mountpoint": "/", "ro": "0", "type": "part", "size": "19327352832"}, {"kname": "sda6", "name": "sda6", "pkname": "sda", "mountpoint": "[SWAP]", "ro": "0", "type": "part", "size": "1073741824"}], "size": "64424509440"}] -} +{"blockdevices": [{"kname": "sda", "name": "sda", "pkname": "", "device-id-paths": ["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429", "/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429"], "mountpoint": "", "ro": "0", "type": "disk", "children": [{"kname": "sda4", "name": "sda4", "pkname": "sda", "device-id-paths": ["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429-part4", "/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429-part4"], "mountpoint": "", "ro": "0", "type": "part", "size": "536870912"}, {"kname": "sda2", "name": "sda2", "pkname": "sda", "device-id-paths": ["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429-part2", "/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429-part2"], "mountpoint": "", "ro": "0", "type": "part", "size": "19327352832"}, {"kname": "sda5", "name": "sda5", "pkname": "sda", "device-id-paths": ["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429-part5", "/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429-part5"], "mountpoint": "/var/log", "ro": "0", "type": "part", "size": "4294967296"}, {"kname": "sda3", "name": "sda3", "pkname": "sda", "device-id-paths": ["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429-part3", "/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429-part3"], "mountpoint": "", "ro": "0", "type": "part", "size": "194883075584"}, {"kname": "sda1", "name": "sda1", "pkname": "sda", "device-id-paths": ["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429-part1", "/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429-part1"], "mountpoint": "/", "ro": "0", "type": "part", "size": "19327352832"}, {"kname": "sda6", "name": "sda6", "pkname": "sda", "device-id-paths": ["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429-part6", "/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429-part6"], "mountpoint": "[SWAP]", "ro": "0", "type": "part", "size": "1073741824"}], "size": "239444426752"}]} ``` - `blockdevices` is a json representation of the blockdevices. - `stdout` is the raw output. diff --git a/SOURCES/etc/xapi.d/plugins/lsblk.py b/SOURCES/etc/xapi.d/plugins/lsblk.py index 169e8e9..4d36b73 100755 --- a/SOURCES/etc/xapi.d/plugins/lsblk.py +++ b/SOURCES/etc/xapi.d/plugins/lsblk.py @@ -8,6 +8,11 @@ from xcpngutils import run_command, error_wrapped +def get_ids_from_device_path(device_path): + result = run_command(["find", "-L", "/dev/disk/by-id", "-samefile", device_path]) + result_output = result["stdout"].decode("utf-8").strip() + return result_output.split("\n") + @error_wrapped def list_block_devices(session, args): result = run_command(["lsblk", "-P", "-b", "-o", "NAME,KNAME,PKNAME,SIZE,TYPE,RO,MOUNTPOINT"]) @@ -20,6 +25,7 @@ def list_block_devices(session, args): output_dict = {key.lower(): output_dict[key].strip('"') for key in output_dict} kname = output_dict["kname"] pkname = output_dict["pkname"] + output_dict["device-id-paths"] = get_ids_from_device_path("/dev/" + kname) if pkname != "": parent = blockdevices[pkname] if "children" not in parent: diff --git a/tests/test_lsblk.py b/tests/test_lsblk.py index 55a0f1c..6960b94 100644 --- a/tests/test_lsblk.py +++ b/tests/test_lsblk.py @@ -8,35 +8,58 @@ @mock.patch('lsblk.run_command', autospec=True) class TestListBlockDevices: def test_lsblk(self, run_command): - run_command.return_value = { - "stdout": b'''NAME="sdb" KNAME="sdb" PKNAME="" SIZE="64424509440" TYPE="disk" RO="0" MOUNTPOINT="" -NAME="sda" KNAME="sda" PKNAME="" SIZE="64424509440" TYPE="disk" RO="0" MOUNTPOINT="" -NAME="sda4" KNAME="sda4" PKNAME="sda" SIZE="536870912" TYPE="part" RO="0" MOUNTPOINT="" -NAME="sda2" KNAME="sda2" PKNAME="sda" SIZE="19327352832" TYPE="part" RO="0" MOUNTPOINT="" -NAME="sda5" KNAME="sda5" PKNAME="sda" SIZE="4294967296" TYPE="part" RO="0" MOUNTPOINT="/var/log" -NAME="sda3" KNAME="sda3" PKNAME="sda" SIZE="19863158272" TYPE="part" RO="0" MOUNTPOINT="" -NAME="XSLocalEXT--1fad55d2--4f07--8145--c78a--297b173e06b0-1fad55d2--4f07--8145--c78a--297b173e06b0" KNAME="dm-0" \ -PKNAME="sda3" SIZE="19847446528" TYPE="lvm" RO="0" MOUNTPOINT="/run/sr-mount/1fad55d2-4f07-8145-c78a-297b173e06b0" -NAME="sda1" KNAME="sda1" PKNAME="sda" SIZE="19327352832" TYPE="part" RO="0" MOUNTPOINT="/" -NAME="sda6" KNAME="sda6" PKNAME="sda" SIZE="1073741824" TYPE="part" RO="0" MOUNTPOINT="[SWAP]"'''} + lsblk_return_value = {"stdout": b'''NAME="sdb" KNAME="sdb" PKNAME="" SIZE="64424509440" TYPE="disk" \ +RO="0" MOUNTPOINT=""\nNAME="sda" KNAME="sda" PKNAME="" SIZE="64424509440" TYPE="disk" RO="0" MOUNTPOINT="" + NAME="sda4" KNAME="sda4" PKNAME="sda" SIZE="536870912" TYPE="part" RO="0" MOUNTPOINT="" + NAME="sda2" KNAME="sda2" PKNAME="sda" SIZE="19327352832" TYPE="part" RO="0" MOUNTPOINT="" + NAME="sda5" KNAME="sda5" PKNAME="sda" SIZE="4294967296" TYPE="part" RO="0" MOUNTPOINT="/var/log" + NAME="sda3" KNAME="sda3" PKNAME="sda" SIZE="19863158272" TYPE="part" RO="0" MOUNTPOINT="" + NAME="XSLocalEXT--1fad55d2--4f07--8145--c78a--297b173e06b0-1fad55d2--4f07--8145--c78a--297b173e06b0" \ +KNAME="dm-0" PKNAME="sda3" SIZE="19847446528" TYPE="lvm" RO="0" \ +MOUNTPOINT="/run/sr-mount/1fad55d2-4f07-8145-c78a-297b173e06b0" + NAME="sda1" KNAME="sda1" PKNAME="sda" SIZE="19327352832" TYPE="part" RO="0" MOUNTPOINT="/" + NAME="sda6" KNAME="sda6" PKNAME="sda" SIZE="1073741824" TYPE="part" RO="0" MOUNTPOINT="[SWAP]"'''} + find_return_value = {"stdout": b'''/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429 +/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429'''} + + def mock_run_command(command): + if command[0] == "lsblk": + assert command == ["lsblk", "-P", "-b", "-o", "NAME,KNAME,PKNAME,SIZE,TYPE,RO,MOUNTPOINT"] + return lsblk_return_value + if command[0] == "find": + return find_return_value + run_command.side_effect = mock_run_command expected = ' \ {"blockdevices": [{"kname": "sdb", "name": "sdb", "pkname": "", "mountpoint": "", "ro": "0", "type": \ -"disk", "size": "64424509440"}, {"kname": "sda", "name": "sda", "pkname": "", "mountpoint": "", "ro": "0", "type": \ -"disk", "children": [{"kname": "sda4", "name": "sda4", "pkname": "sda", "mountpoint": "", "ro": "0", "type": "part", \ -"size": "536870912"}, {"kname": "sda2", "name": "sda2", "pkname": "sda", "mountpoint": "", "ro": "0", "type": "part", \ -"size": "19327352832"}, {"kname": "sda5", "name": "sda5", "pkname": "sda", "mountpoint": "/var/log", "ro": "0", \ -"type": "part", "size": "4294967296"}, {"kname": "sda3", "name": "sda3", "pkname": "sda", "mountpoint": "", "ro": "0", \ -"type": "part", "children": [{"kname": "dm-0", "name": \ +"disk", "size": "64424509440", "device-id-paths": ["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429", \ +"/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429"]}, {"kname": "sda", "name": "sda", "pkname": "", \ +"mountpoint": "", "ro": "0", "type": "disk", \ +"children": [{"kname": "sda4", "name": "sda4", "pkname": "sda", "mountpoint": "", "ro": "0", "type": "part", \ +"size": "536870912", "device-id-paths": ["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429", \ +"/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429"]}, \ +{"kname": "sda2", "name": "sda2", "pkname": "sda", "mountpoint": "", "ro": "0", "type": "part", \ +"size": "19327352832", "device-id-paths": ["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429", \ +"/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429"]}, {"kname": "sda5", "name": "sda5", \ +"pkname": "sda", "mountpoint": "/var/log", "ro": "0", "type": "part", "size": "4294967296", \ +"device-id-paths": ["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429", \ +"/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429"]}, {"kname": "sda3", "name": "sda3", \ +"pkname": "sda", "mountpoint": "", "ro": "0", "type": "part", "children": [{"kname": "dm-0", "name": \ "XSLocalEXT--1fad55d2--4f07--8145--c78a--297b173e06b0-1fad55d2--4f07--8145--c78a--297b173e06b0", "pkname": "sda3", \ -"mountpoint": "/run/sr-mount/1fad55d2-4f07-8145-c78a-297b173e06b0", "ro": "0", "type": "lvm", "size": "19847446528"}], \ -"size": "19863158272"}, {"kname": "sda1", "name": "sda1", "pkname": "sda", "mountpoint": "/", "ro": "0", "type": \ -"part", "size": "19327352832"}, {"kname": "sda6", "name": "sda6", "pkname": "sda", "mountpoint": "[SWAP]", "ro": "0", \ -"type": "part", "size": "1073741824"}], "size": "64424509440"}]}' +"mountpoint": "/run/sr-mount/1fad55d2-4f07-8145-c78a-297b173e06b0", "ro": "0", "type": "lvm", "size": "19847446528", \ +"device-id-paths": ["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429", \ +"/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429"]}], "size": "19863158272", "device-id-paths": \ +["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429", "/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429"]}, \ +{"kname": "sda1", "name": "sda1", "pkname": "sda", "mountpoint": "/", "ro": "0", "type": \ +"part", "size": "19327352832", "device-id-paths": ["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429", \ +"/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429"]}, {"kname": "sda6", "name": "sda6", "pkname": "sda", \ +"mountpoint": "[SWAP]", "ro": "0", "type": "part", "size": "1073741824", "device-id-paths": \ +["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429", \ +"/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429"]}], "size": "64424509440", "device-id-paths": \ +["/dev/disk/by-id/wwn-0x6c81f660e6c1d5002a0a4ad00dacf429", "/dev/disk/by-id/scsi-36c81f660e6c1d5002a0a4ad00dacf429"]}]}' res = list_block_devices(None, None) assert json.loads(res) == json.loads(expected) - run_command.assert_called_once_with(["lsblk", "-P", "-b", "-o", "NAME,KNAME,PKNAME,SIZE,TYPE,RO,MOUNTPOINT"]) def test_lsblk_error(self, run_command): run_command.side_effect = Exception('Error!')