Add LVM based image support to MD scenario
FIXME: Currently matches LVM and partitions. Change-Id: Ie56d8cc7800ca64859c4e9cdf7511fd78b6f3a51
This commit is contained in:
parent
c303bd971b
commit
c95da0a8c3
|
@ -431,6 +431,13 @@ def md_restart(raid_device):
|
|||
"""
|
||||
try:
|
||||
LOG.debug('Restarting software RAID device %s', raid_device)
|
||||
# NOTE(mnasiadka): If the image is LVM based we need to clean
|
||||
# dmsetup devices, because mdadm --stop will fail.
|
||||
dmsetup_stdout, _ = il_utils.execute('dmsetup', 'table',
|
||||
use_standard_locale=True)
|
||||
if 'No devices found' not in dmsetup_stdout:
|
||||
LOG.debug('Deactivating LVM')
|
||||
il_utils.execute('dmsetup', 'remove_all')
|
||||
component_devices = get_component_devices(raid_device)
|
||||
il_utils.execute('mdadm', '--stop', raid_device)
|
||||
il_utils.execute('mdadm', '--assemble', raid_device,
|
||||
|
@ -554,6 +561,7 @@ def list_all_block_devices(block_type='disk',
|
|||
report_json = json.loads(report)
|
||||
except json.decoder.JSONDecodeError as ex:
|
||||
LOG.error("Unable to decode lsblk output, invalid JSON: %s", ex)
|
||||
raise
|
||||
|
||||
context = pyudev.Context()
|
||||
devices_raw = report_json['blockdevices']
|
||||
|
@ -609,11 +617,11 @@ def list_all_block_devices(block_type='disk',
|
|||
{'device_raw': device_raw})
|
||||
elif (devtype == 'md'
|
||||
and (block_type == 'part'
|
||||
or block_type == 'md')):
|
||||
# NOTE(dszumski): Partitions on software RAID devices have type
|
||||
# 'md'. This may also contain RAID devices in a broken state in
|
||||
# rare occasions. See https://review.opendev.org/#/c/670807 for
|
||||
# more detail.
|
||||
or block_type == 'lvm')):
|
||||
# NOTE(dszumski): Partitions and LVM volumes on software RAID
|
||||
# devices have type 'md'. This may also contain RAID devices in
|
||||
# a broken state in rare occasions. See
|
||||
# https://review.opendev.org/#/c/670807 for more detail.
|
||||
LOG.debug(
|
||||
"TYPE detected to contain 'md', signifying a "
|
||||
"RAID partition. Found: %(device_raw)s",
|
||||
|
|
|
@ -201,7 +201,9 @@ RAID_BLK_DEVICE_TEMPLATE = ("""
|
|||
{"kname":"md0", "model":"RAID", "size":1765517033470, "rota":false,
|
||||
"type":"raid1", "serial":null, "uuid":null, "partuuid":null, "wwn":"33"},
|
||||
{"kname":"md1", "model":"RAID", "size":0, "rota":false, "type":"raid1",
|
||||
"serial":null, "uuid":null, "partuuid":null, "wwn":null}
|
||||
"serial":null, "uuid":null, "partuuid":null, "wwn":null},
|
||||
{"kname":"dm-0", "model":"RAID", "size":1765517033470, "rota":false,
|
||||
"type":"md", "uuid":null, "partuuid":null}
|
||||
]
|
||||
}
|
||||
""")
|
||||
|
|
|
@ -1241,9 +1241,9 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
|||
@mock.patch.object(hardware, '_get_device_info', autospec=True)
|
||||
@mock.patch.object(pyudev.Devices, 'from_device_file', autospec=False)
|
||||
@mock.patch.object(il_utils, 'execute', autospec=True)
|
||||
def test_list_all_block_device(self, mocked_execute, mocked_udev,
|
||||
mocked_dev_vendor, mock_listdir,
|
||||
mock_readlink):
|
||||
def test_list_all_block_devices(self, mocked_execute, mocked_udev,
|
||||
mocked_dev_vendor, mock_listdir,
|
||||
mock_readlink):
|
||||
by_path_map = {
|
||||
'/dev/disk/by-path/1:0:0:0': '../../dev/sda',
|
||||
'/dev/disk/by-path/1:0:0:1': '../../dev/sdb',
|
||||
|
@ -5439,6 +5439,66 @@ class TestModuleFunctions(base.IronicAgentTest):
|
|||
@mock.patch.object(hardware, '_get_device_info',
|
||||
lambda x, y, z: 'FooTastic')
|
||||
@mock.patch.object(disk_utils, 'udev_settle', autospec=True)
|
||||
@mock.patch.object(hardware.pyudev.Devices, "from_device_file",
|
||||
autospec=False)
|
||||
def test_list_all_block_devices_success_raid_lvm(self, mocked_fromdevfile,
|
||||
mocked_udev,
|
||||
mocked_readlink,
|
||||
mocked_mpath,
|
||||
mocked_execute):
|
||||
mocked_readlink.return_value = '../../sda'
|
||||
mocked_fromdevfile.return_value = {}
|
||||
mocked_mpath.return_value = True
|
||||
mocked_execute.side_effect = [
|
||||
(hws.RAID_BLK_DEVICE_TEMPLATE, ''),
|
||||
processutils.ProcessExecutionError(
|
||||
stderr=hws.MULTIPATH_INVALID_PATH % '/dev/sda'),
|
||||
processutils.ProcessExecutionError(
|
||||
stderr=hws.MULTIPATH_INVALID_PATH % '/dev/sda1'),
|
||||
processutils.ProcessExecutionError(
|
||||
stderr=hws.MULTIPATH_INVALID_PATH % '/dev/sdb'),
|
||||
processutils.ProcessExecutionError(
|
||||
stderr=hws.MULTIPATH_INVALID_PATH % '/dev/sdb1'),
|
||||
processutils.ProcessExecutionError(
|
||||
stderr=hws.MULTIPATH_INVALID_PATH % '/dev/sda'),
|
||||
processutils.ProcessExecutionError(
|
||||
stderr='the -c option requires a path to check'), # md0p1
|
||||
processutils.ProcessExecutionError(
|
||||
stderr='the -c option requires a path to check'), # md0
|
||||
processutils.ProcessExecutionError(
|
||||
stderr='the -c option requires a path to check'), # md0
|
||||
processutils.ProcessExecutionError(
|
||||
stderr='the -c option requires a path to check'), # md1
|
||||
processutils.ProcessExecutionError(
|
||||
stderr='the -c option requires a path to check'), # dm-0
|
||||
]
|
||||
expected_calls = [
|
||||
mock.call('lsblk', '-bia', '--json',
|
||||
'-oKNAME,MODEL,SIZE,ROTA,TYPE,UUID,PARTUUID',
|
||||
check_exit_code=[0]),
|
||||
mock.call('multipath', '-c', '/dev/sda'),
|
||||
mock.call('multipath', '-c', '/dev/sda1'),
|
||||
mock.call('multipath', '-c', '/dev/sdb'),
|
||||
mock.call('multipath', '-c', '/dev/sdb'),
|
||||
mock.call('multipath', '-c', '/dev/sdb1'),
|
||||
mock.call('multipath', '-c', '/dev/md0p1'),
|
||||
mock.call('multipath', '-c', '/dev/md0'),
|
||||
mock.call('multipath', '-c', '/dev/md0'),
|
||||
mock.call('multipath', '-c', '/dev/md1'),
|
||||
mock.call('multipath', '-c', '/dev/dm-0'),
|
||||
]
|
||||
result = hardware.list_all_block_devices(block_type='lvm',
|
||||
ignore_empty=False)
|
||||
mocked_execute.assert_has_calls(expected_calls)
|
||||
hardware.LOG.error(result[0].__dict__)
|
||||
self.assertEqual(RAID_BLK_DEVICE_TEMPLATE_DEVICES[3:4], result)
|
||||
mocked_udev.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(hardware, 'get_multipath_status', autospec=True)
|
||||
@mock.patch.object(os, 'readlink', autospec=True)
|
||||
@mock.patch.object(hardware, '_get_device_info',
|
||||
lambda x, y, z: 'FooTastic')
|
||||
@mock.patch.object(hardware, '_udev_settle', autospec=True)
|
||||
@mock.patch.object(hardware.pyudev.Devices, "from_device_file",
|
||||
autospec=False)
|
||||
def test_list_all_block_devices_partuuid_success(
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
Add support for LVM based images in MD (software RAID) scenario.
|
Loading…
Reference in New Issue