summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2020-08-18 14:37:41 +0000
committerGerrit Code Review <review@openstack.org>2020-08-18 14:37:41 +0000
commitc52dd85fce9d22a7fe65da8c0c3634ea0847db79 (patch)
tree2b80a2705a71a96fda5286a34fe92503ae00f498
parenta5ca82e362aba6ef5084918a948a312eb8fb485e (diff)
parenta4f86d8e8b4ae8e6e75c83f396805910b4d6fac5 (diff)
downloadironic-c52dd85fce9d22a7fe65da8c0c3634ea0847db79.tar.gz
Merge "DRAC: Drives conversion from raid to jbod" into stable/train13.0.6
-rw-r--r--ironic/drivers/modules/drac/raid.py30
-rw-r--r--ironic/tests/unit/drivers/modules/drac/test_raid.py86
-rw-r--r--releasenotes/notes/idrac-drives-conversion-raid-to-jbod-de10755d1ec094ea.yaml8
3 files changed, 83 insertions, 41 deletions
diff --git a/ironic/drivers/modules/drac/raid.py b/ironic/drivers/modules/drac/raid.py
index 4a60fd95c..9fc615576 100644
--- a/ironic/drivers/modules/drac/raid.py
+++ b/ironic/drivers/modules/drac/raid.py
@@ -1199,11 +1199,15 @@ class DracWSManRAID(base.RAIDInterface):
if not node.driver_internal_info.get('raid_config_job_failure',
False):
if 'raid_config_substep' in node.driver_internal_info:
- if node.driver_internal_info['raid_config_substep'] == \
- 'delete_foreign_config':
- self._execute_foreign_drives(task, node)
- elif node.driver_internal_info['raid_config_substep'] == \
- 'completed':
+ substep = node.driver_internal_info['raid_config_substep']
+
+ if substep == 'delete_foreign_config':
+ foreign_drives = self._execute_foreign_drives(task, node)
+ if foreign_drives is None:
+ return self._convert_drives(task, node)
+ elif substep == 'physical_disk_conversion':
+ self._convert_drives(task, node)
+ elif substep == 'completed':
self._complete_raid_substep(task, node)
else:
self._complete_raid_substep(task, node)
@@ -1231,17 +1235,27 @@ class DracWSManRAID(base.RAIDInterface):
LOG.info(
"No foreign drives detected, so "
"resume %s", "cleaning" if node.clean_step else "deployment")
- self._complete_raid_substep(task, node)
+ return None
else:
- _commit_to_controllers(
+ return _commit_to_controllers(
node,
controllers,
- substep='completed')
+ substep='physical_disk_conversion')
def _complete_raid_substep(self, task, node):
self._clear_raid_substep(node)
self._resume(task)
+ def _convert_drives(self, task, node):
+ jbod = drac_constants.RaidStatus.jbod
+ drives_results = _change_physical_disk_mode(
+ node, mode=jbod)
+ if drives_results is None:
+ LOG.debug("Controller does not support drives "
+ "conversion on %(node_uuid)s",
+ {'node_uuid': node.uuid})
+ self._complete_raid_substep(task, node)
+
def _clear_raid_substep(self, node):
driver_internal_info = node.driver_internal_info
driver_internal_info.pop('raid_config_substep', None)
diff --git a/ironic/tests/unit/drivers/modules/drac/test_raid.py b/ironic/tests/unit/drivers/modules/drac/test_raid.py
index b5b2d04fb..e2bb465c7 100644
--- a/ironic/tests/unit/drivers/modules/drac/test_raid.py
+++ b/ironic/tests/unit/drivers/modules/drac/test_raid.py
@@ -22,7 +22,6 @@ import mock
from ironic.common import exception
from ironic.common import states
from ironic.conductor import task_manager
-from ironic.conductor import utils as conductor_utils
from ironic.drivers.modules.drac import common as drac_common
from ironic.drivers.modules.drac import job as drac_job
from ironic.drivers.modules.drac import raid as drac_raid
@@ -1981,39 +1980,19 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
@mock.patch.object(drac_common, 'get_drac_client', spec_set=True,
autospec=True)
- @mock.patch.object(conductor_utils, '_notify_conductor_resume_operation',
- autospec=True)
@mock.patch.object(drac_raid, 'clear_foreign_config', spec_set=True,
autospec=True)
- @mock.patch.object(drac_raid, 'list_virtual_disks', autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
- def test__execute_cleaning_foreign_drives(self,
- mock_validate_job_queue,
- mock_list_virtual_disks,
- mock_clear_foreign_config,
- mock_resume,
- mock_get_drac_client):
+ def test__execute_foreign_drives_with_no_foreign_drives(
+ self, mock_validate_job_queue,
+ mock_clear_foreign_config,
+ mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
- virtual_disk_dict = {
- 'id': 'Disk.Virtual.0:RAID.Integrated.1-1',
- 'name': 'disk 0',
- 'description': 'Virtual Disk 0 on Integrated RAID Controller 1',
- 'controller': 'RAID.Integrated.1-1',
- 'raid_level': '1',
- 'size_mb': 571776,
- 'status': 'ok',
- 'raid_status': 'online',
- 'span_depth': 1,
- 'span_length': 2,
- 'pending_operations': None,
- 'physical_disks': []}
- mock_list_virtual_disks.return_value = [
- test_utils.make_virtual_disk(virtual_disk_dict)]
raid_config_params = ['RAID.Integrated.1-1']
- raid_config_substep = ['completed']
+ raid_config_substep = 'clear_foreign_config'
driver_internal_info = self.node.driver_internal_info
driver_internal_info['raid_config_parameters'] = raid_config_params
driver_internal_info['raid_config_substep'] = raid_config_substep
@@ -2028,11 +2007,52 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
shared=False) as task:
return_value = task.driver.raid._execute_foreign_drives(
task, self.node)
- mock_resume.assert_called_once_with(
- task, 'cleaning', 'continue_node_clean')
- self.assertIsNone(return_value)
- self.assertNotIn('raid_config_parameters',
- self.node.driver_internal_info)
- self.assertNotIn('raid_config_substep',
- self.node.driver_internal_info)
+ self.assertIsNone(None, return_value)
+
+ @mock.patch.object(drac_common, 'get_drac_client', spec_set=True,
+ autospec=True)
+ @mock.patch.object(drac_raid, 'clear_foreign_config', spec_set=True,
+ autospec=True)
+ @mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
+ autospec=True)
+ @mock.patch.object(drac_raid, 'commit_config', spec_set=True,
+ autospec=True)
+ def test__execute_foreign_drives_with_foreign_drives(
+ self, mock_commit_config,
+ mock_validate_job_queue,
+ mock_clear_foreign_config,
+ mock_get_drac_client):
+ mock_client = mock.Mock()
+ mock_get_drac_client.return_value = mock_client
+
+ raid_config_params = ['RAID.Integrated.1-1']
+ raid_config_substep = 'clear_foreign_config'
+ driver_internal_info = self.node.driver_internal_info
+ driver_internal_info['raid_config_parameters'] = raid_config_params
+ driver_internal_info['raid_config_substep'] = raid_config_substep
+ self.node.driver_internal_info = driver_internal_info
+ self.node.save()
+ mock_clear_foreign_config.return_value = {
+ 'is_reboot_required': constants.RebootRequired.optional,
+ 'is_commit_required': True
+ }
+ mock_commit_config.return_value = '42'
+
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ return_value = task.driver.raid._execute_foreign_drives(
+ task, self.node)
+
+ self.assertEqual(states.CLEANWAIT, return_value)
+
+ self.assertEqual(['42'],
+ self.node.driver_internal_info['raid_config_job_ids'])
+ self.assertEqual('physical_disk_conversion',
+ self.node.driver_internal_info['raid_config_substep'])
+ self.assertEqual(
+ ['RAID.Integrated.1-1'],
+ self.node.driver_internal_info['raid_config_parameters'])
+ mock_commit_config.assert_called_once_with(
+ self.node, raid_controller='RAID.Integrated.1-1', reboot=False,
+ realtime=True)
diff --git a/releasenotes/notes/idrac-drives-conversion-raid-to-jbod-de10755d1ec094ea.yaml b/releasenotes/notes/idrac-drives-conversion-raid-to-jbod-de10755d1ec094ea.yaml
new file mode 100644
index 000000000..868721518
--- /dev/null
+++ b/releasenotes/notes/idrac-drives-conversion-raid-to-jbod-de10755d1ec094ea.yaml
@@ -0,0 +1,8 @@
+---
+fixes:
+ - |
+ Hardware type ``idrac`` converts physical drives from
+ ``RAID`` to ``JBOD`` mode after RAID ``delete_configuration``
+ cleaning step through raid interface. This ensures that the
+ individual disks freed by deleting the virtual disks
+ are visible to the OS. \ No newline at end of file