DRAC: Drives conversion from raid to jbod
Added physical drives conversion from RAID to JBOD mode after RAID delete_configuration cleaning step called in iDRAC driver. Change-Id: I59bad3d8969cc8374d1436b91b32a21b38ca8d69 Story: 2006234 Task: 35835
This commit is contained in:
parent
6a054eb692
commit
f772e86580
@ -1190,11 +1190,15 @@ class DracWSManRAID(base.RAIDInterface):
|
|||||||
if not node.driver_internal_info.get('raid_config_job_failure',
|
if not node.driver_internal_info.get('raid_config_job_failure',
|
||||||
False):
|
False):
|
||||||
if 'raid_config_substep' in node.driver_internal_info:
|
if 'raid_config_substep' in node.driver_internal_info:
|
||||||
if node.driver_internal_info['raid_config_substep'] == \
|
substep = node.driver_internal_info['raid_config_substep']
|
||||||
'delete_foreign_config':
|
|
||||||
self._execute_foreign_drives(task, node)
|
if substep == 'delete_foreign_config':
|
||||||
elif node.driver_internal_info['raid_config_substep'] == \
|
foreign_drives = self._execute_foreign_drives(task, node)
|
||||||
'completed':
|
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)
|
self._complete_raid_substep(task, node)
|
||||||
else:
|
else:
|
||||||
self._complete_raid_substep(task, node)
|
self._complete_raid_substep(task, node)
|
||||||
@ -1222,17 +1226,27 @@ class DracWSManRAID(base.RAIDInterface):
|
|||||||
LOG.info(
|
LOG.info(
|
||||||
"No foreign drives detected, so "
|
"No foreign drives detected, so "
|
||||||
"resume %s", "cleaning" if node.clean_step else "deployment")
|
"resume %s", "cleaning" if node.clean_step else "deployment")
|
||||||
self._complete_raid_substep(task, node)
|
return None
|
||||||
else:
|
else:
|
||||||
_commit_to_controllers(
|
return _commit_to_controllers(
|
||||||
node,
|
node,
|
||||||
controllers,
|
controllers,
|
||||||
substep='completed')
|
substep='physical_disk_conversion')
|
||||||
|
|
||||||
def _complete_raid_substep(self, task, node):
|
def _complete_raid_substep(self, task, node):
|
||||||
self._clear_raid_substep(node)
|
self._clear_raid_substep(node)
|
||||||
self._resume(task)
|
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):
|
def _clear_raid_substep(self, node):
|
||||||
driver_internal_info = node.driver_internal_info
|
driver_internal_info = node.driver_internal_info
|
||||||
driver_internal_info.pop('raid_config_substep', None)
|
driver_internal_info.pop('raid_config_substep', None)
|
||||||
|
@ -22,7 +22,6 @@ import mock
|
|||||||
from ironic.common import exception
|
from ironic.common import exception
|
||||||
from ironic.common import states
|
from ironic.common import states
|
||||||
from ironic.conductor import task_manager
|
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 common as drac_common
|
||||||
from ironic.drivers.modules.drac import job as drac_job
|
from ironic.drivers.modules.drac import job as drac_job
|
||||||
from ironic.drivers.modules.drac import raid as drac_raid
|
from ironic.drivers.modules.drac import raid as drac_raid
|
||||||
@ -2021,39 +2020,19 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
|
|||||||
|
|
||||||
@mock.patch.object(drac_common, 'get_drac_client', spec_set=True,
|
@mock.patch.object(drac_common, 'get_drac_client', spec_set=True,
|
||||||
autospec=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,
|
@mock.patch.object(drac_raid, 'clear_foreign_config', spec_set=True,
|
||||||
autospec=True)
|
autospec=True)
|
||||||
@mock.patch.object(drac_raid, 'list_virtual_disks', autospec=True)
|
|
||||||
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
|
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
|
||||||
autospec=True)
|
autospec=True)
|
||||||
def test__execute_cleaning_foreign_drives(self,
|
def test__execute_foreign_drives_with_no_foreign_drives(
|
||||||
mock_validate_job_queue,
|
self, mock_validate_job_queue,
|
||||||
mock_list_virtual_disks,
|
|
||||||
mock_clear_foreign_config,
|
mock_clear_foreign_config,
|
||||||
mock_resume,
|
|
||||||
mock_get_drac_client):
|
mock_get_drac_client):
|
||||||
mock_client = mock.Mock()
|
mock_client = mock.Mock()
|
||||||
mock_get_drac_client.return_value = mock_client
|
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_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 = self.node.driver_internal_info
|
||||||
driver_internal_info['raid_config_parameters'] = raid_config_params
|
driver_internal_info['raid_config_parameters'] = raid_config_params
|
||||||
driver_internal_info['raid_config_substep'] = raid_config_substep
|
driver_internal_info['raid_config_substep'] = raid_config_substep
|
||||||
@ -2068,11 +2047,52 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
|
|||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
return_value = task.driver.raid._execute_foreign_drives(
|
return_value = task.driver.raid._execute_foreign_drives(
|
||||||
task, self.node)
|
task, self.node)
|
||||||
mock_resume.assert_called_once_with(
|
|
||||||
task, 'cleaning', 'continue_node_clean')
|
|
||||||
|
|
||||||
self.assertIsNone(return_value)
|
self.assertIsNone(None, return_value)
|
||||||
self.assertNotIn('raid_config_parameters',
|
|
||||||
self.node.driver_internal_info)
|
@mock.patch.object(drac_common, 'get_drac_client', spec_set=True,
|
||||||
self.assertNotIn('raid_config_substep',
|
autospec=True)
|
||||||
self.node.driver_internal_info)
|
@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)
|
||||||
|
@ -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.
|
Loading…
x
Reference in New Issue
Block a user