diff options
| author | Arne Wiebalck <Arne.Wiebalck@cern.ch> | 2019-07-26 14:47:15 +0200 |
|---|---|---|
| committer | Arne Wiebalck <Arne.Wiebalck@cern.ch> | 2019-08-16 11:35:07 +0200 |
| commit | 9dca5d76b3a0f2cab2fe6171d844944e065a6741 (patch) | |
| tree | 1ee565dd5f665145215d22b355e4f55d29565fb9 /ironic_python_agent | |
| parent | ef831847e6b07753b4916db79e0d60f34d55724c (diff) | |
| download | ironic-python-agent-9dca5d76b3a0f2cab2fe6171d844944e065a6741.tar.gz | |
Software RAID: Ignore missing component devices or holder disks
With the addition of devices with type 'MD' during
list_all_block_devices (for "empty" devices), partitions on top
of md devices are now returned as well. These don't need deletion,
so skip these during software RAID cleanup.
Story: #2006355
Task: #36121
Change-Id: Idff9b9b0cbe42b57aa315ae07c0b51c35c9ade1e
Diffstat (limited to 'ironic_python_agent')
| -rw-r--r-- | ironic_python_agent/hardware.py | 26 | ||||
| -rw-r--r-- | ironic_python_agent/tests/unit/test_hardware.py | 13 |
2 files changed, 31 insertions, 8 deletions
diff --git a/ironic_python_agent/hardware.py b/ironic_python_agent/hardware.py index 9ed0c5b8..bbaf9ee9 100644 --- a/ironic_python_agent/hardware.py +++ b/ironic_python_agent/hardware.py @@ -127,15 +127,16 @@ def _get_component_devices(raid_device): if not raid_device: return [] - component_devices = [] try: out, _ = utils.execute('mdadm', '--detail', raid_device, use_standard_locale=True) except processutils.ProcessExecutionError as e: msg = ('Could not get component devices of %(dev)s: %(err)s' % {'dev': raid_device, 'err': e}) - raise errors.SoftwareRAIDError(msg) + LOG.warning(msg) + return [] + component_devices = [] lines = out.splitlines() # the first line contains the md device itself for line in lines[1:]: @@ -156,16 +157,16 @@ def get_holder_disks(raid_device): if not raid_device: return [] - holder_disks = [] - try: out, _ = utils.execute('mdadm', '--detail', raid_device, use_standard_locale=True) except processutils.ProcessExecutionError as e: msg = ('Could not get holder disks of %(dev)s: %(err)s' % {'dev': raid_device, 'err': e}) - raise errors.SoftwareRAIDError(msg) + LOG.warning(msg) + return [] + holder_disks = [] lines = out.splitlines() # the first line contains the md device itself for line in lines[1:]: @@ -1549,12 +1550,21 @@ class GenericHardwareManager(HardwareManager): raid_devices = list_all_block_devices(block_type='raid', ignore_raid=False) for raid_device in raid_devices: + component_devices = _get_component_devices(raid_device.name) + if not component_devices: + # A "Software RAID device" without components is usually + # a partition on an md device (as, for instance, created + # by the conductor for the config drive). This will be + # cleaned with the hosting md device. + msg = ("Software RAID cleaning is skipping " + "partition %s" % raid_device.name) + LOG.info(msg) + continue + holder_disks = get_holder_disks(raid_device.name) + LOG.info("Deleting Software RAID device {}".format( raid_device.name)) - - component_devices = _get_component_devices(raid_device.name) LOG.debug('Found component devices %s', component_devices) - holder_disks = get_holder_disks(raid_device.name) LOG.debug('Found holder disks %s', holder_disks) # Remove md devices. diff --git a/ironic_python_agent/tests/unit/test_hardware.py b/ironic_python_agent/tests/unit/test_hardware.py index f540f1f5..49cae296 100644 --- a/ironic_python_agent/tests/unit/test_hardware.py +++ b/ironic_python_agent/tests/unit/test_hardware.py @@ -2955,6 +2955,19 @@ class TestGenericHardwareManager(base.IronicAgentTest): mock.call('wipefs', '-af', '/dev/sda'), mock.call('wipefs', '-af', '/dev/sdb')]) + @mock.patch.object(hardware, '_get_component_devices', autospec=True) + @mock.patch.object(hardware, 'list_all_block_devices', autospec=True) + @mock.patch.object(utils, 'execute', autospec=True) + def test_delete_configuration_partition(self, mocked_execute, mocked_list, + mocked_get_component): + raid_device1_part1 = hardware.BlockDevice('/dev/md0p1', 'RAID-1', + 1073741824, True) + hardware.list_all_block_devices.return_value = [raid_device1_part1] + mocked_get_component.return_value = [] + + self.assertIsNone(self.hardware.delete_configuration(self.node, [])) + mocked_execute.assert_has_calls([]) + @mock.patch.object(utils, 'execute', autospec=True) def test_validate_configuration_valid_raid1(self, mocked_execute): raid_config = { |
