DRAC: Drives conversion from JBOD to RAID

Added physical drives conversion from JBOD to RAID
mode before RAID create_configuration cleaning step called
in iDRAC driver.

Change-Id: Ie6d1a9314d1543b73889f6d419541e75b7e06c89
Story: #2006479
Task: #36422
This commit is contained in:
Rachit7194 2019-08-28 11:57:34 -04:00
parent a2ae57c457
commit 8e3f682e29
8 changed files with 388 additions and 50 deletions

View File

@ -7,7 +7,7 @@
proliantutils>=2.9.1
pysnmp>=4.3.0,<5.0.0
python-scciclient>=0.8.0
python-dracclient>=3.0.0,<4.0.0
python-dracclient>=3.1.0,<4.0.0
python-xclarityclient>=0.1.6
# The Redfish hardware type uses the Sushy library

View File

@ -28,7 +28,13 @@ opts = [
help=_('Maximum amount of time (in seconds) to wait for '
'the boot device configuration job to transition '
'to the correct state to allow a reboot or power '
'on to complete.'))
'on to complete.')),
cfg.IntOpt('config_job_max_retries',
default=240,
min=1,
help=_('Maximum number of retries for '
'the configuration job to complete '
'successfully.'))
]

View File

@ -17,21 +17,23 @@ DRAC Lifecycle job specific methods
from oslo_log import log as logging
from oslo_utils import importutils
import retrying
from ironic.common import exception
from ironic.common.i18n import _
from ironic.conf import CONF
from ironic.drivers.modules.drac import common as drac_common
drac_exceptions = importutils.try_import('dracclient.exceptions')
LOG = logging.getLogger(__name__)
WAIT_CLOCK = 5
def validate_job_queue(node, name_prefix=None):
"""Validates the job queue on the node.
It raises an exception if an unfinished configuration job exists.
:param node: an ironic node object.
:param name_prefix: A name prefix for jobs to validate.
:raises: DracOperationError on an error from python-dracclient.
@ -86,3 +88,27 @@ def list_unfinished_jobs(node):
{'node_uuid': node.uuid,
'error': exc})
raise exception.DracOperationError(error=exc)
@retrying.retry(
retry_on_exception=lambda e: isinstance(e, exception.DracOperationError),
stop_max_attempt_number=CONF.drac.config_job_max_retries,
wait_fixed=WAIT_CLOCK * 1000)
def wait_for_job_completion(node,
retries=CONF.drac.config_job_max_retries):
"""Wait for job to complete
It will wait for the job to complete for 20 minutes and raises timeout
if job never complete within given interval of time.
:param node: an ironic node object.
:param retries: no of retries to make conductor wait.
:raises: DracOperationError on exception raised from python-dracclient
or a timeout while waiting for job completion.
"""
if not list_unfinished_jobs(node):
return
err_msg = _(
'There are unfinished jobs in the job '
'queue on node %(node_uuid)r ') % {'node_uuid': node.uuid}
LOG.warning(err_msg)
raise exception.DracOperationError(error=err_msg)

View File

@ -15,6 +15,7 @@
DRAC RAID specific methods
"""
from collections import defaultdict
import math
from futurist import periodics
@ -309,6 +310,43 @@ def clear_foreign_config(node, raid_controller):
raise exception.DracOperationError(error=exc)
def change_physical_disk_state(node, mode=None,
controllers_to_physical_disk_ids=None):
"""Convert disks RAID status
This method converts the requested physical disks from
RAID to JBOD or vice versa. It does this by only converting the
disks that are not already in the correct state.
:param node: an ironic node object.
:param mode: the mode to change the disks either to RAID or JBOD.
:param controllers_to_physical_disk_ids: Dictionary of controllers and
corresponding disk ids to convert to the requested mode.
:return: a dictionary containing:
- conversion_results, a dictionary that maps controller ids
to the conversion results for that controller.
The conversion results are a dict that contains:
- The is_commit_required key with the value always set to
True indicating that a config job must be created to
complete disk conversion.
- The is_reboot_required key with a RebootRequired
enumerated value indicating whether the server must be
rebooted to complete disk conversion.
:raises: DRACOperationError on an error from python-dracclient.
"""
try:
drac_job.validate_job_queue(node)
client = drac_common.get_drac_client(node)
return client.change_physical_disk_state(
mode, controllers_to_physical_disk_ids)
except drac_exceptions.BaseClientException as exc:
LOG.error('DRAC driver failed to change physical drives '
'to %(mode)s mode for node %(node_uuid)s. '
'Reason: %(error)s.',
{'mode': mode, 'node_uuid': node.uuid, 'error': exc})
raise exception.DracOperationError(error=exc)
def commit_config(node, raid_controller, reboot=False, realtime=False):
"""Apply all pending changes on a RAID controller.
@ -338,6 +376,33 @@ def commit_config(node, raid_controller, reboot=False, realtime=False):
raise exception.DracOperationError(error=exc)
def _change_physical_disk_mode(node, mode=None,
controllers_to_physical_disk_ids=None):
"""Physical drives conversion from RAID to JBOD or vice-versa.
:param node: an ironic node object.
:param mode: the mode to change the disks either to RAID or JBOD.
:param controllers_to_physical_disk_ids: Dictionary of controllers and
corresponding disk ids to convert to the requested mode.
:returns: states.CLEANWAIT if deletion is in progress asynchronously
or None if it is completed.
"""
change_disk_state = change_physical_disk_state(
node, mode, controllers_to_physical_disk_ids)
controllers = list()
conversion_results = change_disk_state['conversion_results']
for controller_id, result in conversion_results.items():
controller = {'raid_controller': controller_id,
'is_reboot_required': result['is_reboot_required'],
'is_commit_required': result['is_commit_required']}
controllers.append(controller)
return _commit_to_controllers(
node,
controllers, substep='completed')
def abandon_config(node, raid_controller):
"""Deletes all pending changes on a RAID controller.
@ -833,18 +898,18 @@ def _commit_to_controllers(node, controllers, substep="completed"):
else:
for controller in controllers:
mix_controller = controller['raid_controller']
reboot = True if controller == controllers[-1] else False
reboot = (controller == controllers[-1])
job_details = _create_config_job(
node, controller=mix_controller,
reboot=reboot, realtime=False,
raid_config_job_ids=raid_config_job_ids,
raid_config_parameters=raid_config_parameters)
driver_internal_info['raid_config_job_ids'] = job_details[
'raid_config_job_ids']
driver_internal_info['raid_config_job_ids'].extend(job_details[
'raid_config_job_ids'])
driver_internal_info['raid_config_parameters'] = job_details[
'raid_config_parameters']
driver_internal_info['raid_config_parameters'].extend(job_details[
'raid_config_parameters'])
node.driver_internal_info = driver_internal_info
@ -940,6 +1005,7 @@ class DracWSManRAID(base.RAIDInterface):
node = task.node
logical_disks = node.target_raid_config['logical_disks']
for disk in logical_disks:
if disk['size_gb'] == 'MAX' and 'physical_disks' not in disk:
raise exception.InvalidParameterValue(
@ -969,6 +1035,36 @@ class DracWSManRAID(base.RAIDInterface):
logical_disks_to_create = _filter_logical_disks(
logical_disks, create_root_volume, create_nonroot_volumes)
controllers_to_physical_disk_ids = defaultdict(list)
for logical_disk in logical_disks_to_create:
# Not applicable to JBOD logical disks.
if logical_disk['raid_level'] == 'JBOD':
continue
for physical_disk_name in logical_disk['physical_disks']:
controllers_to_physical_disk_ids[
logical_disk['controller']].append(
physical_disk_name)
if logical_disks_to_create:
LOG.debug(
"Converting physical disks configured to back RAID "
"logical disks to RAID mode for node %(node_uuid)s ",
{"node_uuid": node.uuid})
raid = drac_constants.RaidStatus.raid
_change_physical_disk_mode(
node, raid, controllers_to_physical_disk_ids)
LOG.debug("Waiting for physical disk conversion to complete "
"for node %(node_uuid)s. ", {"node_uuid": node.uuid})
drac_job.wait_for_job_completion(node)
LOG.info(
"Completed converting physical disks configured to back RAID "
"logical disks to RAID mode for node %(node_uuid)s",
{'node_uuid': node.uuid})
controllers = list()
for logical_disk in logical_disks_to_create:
controller = dict()
controller_cap = create_virtual_disk(

View File

@ -284,6 +284,66 @@ class DracManageVirtualDisksTestCase(test_utils.BaseDracTest):
exception.DracOperationError, drac_raid.clear_foreign_config,
self.node, 'RAID.Integrated.1-1')
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
def test_change_physical_disk_state(self,
mock_validate_job_queue,
mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
controllers_to_physical_disk_ids = {'RAID.Integrated.1-1': [
'Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1',
'Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1']}
expected_change_disk_state = {
'is_reboot_required': True,
'conversion_results': {
'RAID.Integrated.1-1': {'is_reboot_required': 'optional',
'is_commit_required': True}},
'commit_required_ids': ['RAID.Integrated.1-1']}
mode = constants.RaidStatus.raid
mock_client.change_physical_disk_state.return_value = \
expected_change_disk_state
actual_change_disk_state = drac_raid.change_physical_disk_state(
self.node,
mode=mode,
controllers_to_physical_disk_ids=controllers_to_physical_disk_ids)
mock_validate_job_queue.assert_called_once_with(self.node)
mock_client.change_physical_disk_state.assert_called_once_with(
mode, controllers_to_physical_disk_ids)
self.assertEqual(expected_change_disk_state, actual_change_disk_state)
@mock.patch.object(drac_raid, 'change_physical_disk_state', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'commit_config', spec_set=True,
autospec=True)
def test__change_physical_disk_mode(self,
mock_commit_config,
mock_change_physical_disk_state,
mock_get_drac_client):
mock_commit_config.return_value = '42'
mock_change_physical_disk_state.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'conversion_results': {
'RAID.Integrated.1-1': {
'is_reboot_required': constants.RebootRequired.optional,
'is_commit_required': True}},
'commit_required_ids': ['RAID.Integrated.1-1']}
actual_change_disk_state = drac_raid._change_physical_disk_mode(
self.node, mode=constants.RaidStatus.raid)
self.assertEqual(['42'],
self.node.driver_internal_info['raid_config_job_ids'])
self.assertEqual('completed',
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)
self.assertEqual(states.DEPLOYWAIT, actual_change_disk_state)
def test_commit_config(self, mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
@ -746,12 +806,17 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
@mock.patch.object(drac_raid, 'list_physical_disks', autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'change_physical_disk_state', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'wait_for_job_completion', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'commit_config', spec_set=True,
autospec=True)
def _test_create_configuration(
self, expected_state, mock_commit_config, mock_validate_job_queue,
mock_list_physical_disks, mock__reset_raid_config,
mock_get_drac_client):
self, expected_state, mock_commit_config,
mock_wait_for_job_completion, mock_change_physical_disk_state,
mock_validate_job_queue, mock_list_physical_disks,
mock__reset_raid_config, mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
physical_disks = self._generate_physical_disks()
@ -772,6 +837,13 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
mock__reset_raid_config.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'is_commit_required': True}
mock_change_physical_disk_state.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'conversion_results': {
'RAID.Integrated.1-1': {'is_reboot_required': 'optional',
'is_commit_required': True}},
'commit_required_ids': ['RAID.Integrated.1-1']}
mock_commit_config.side_effect = ['42', '12']
mock_client.create_virtual_disk.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'is_commit_required': True}
@ -787,13 +859,17 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
'Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1'],
'1', 51200, None, 2, 1)
mock_commit_config.assert_called_once_with(
mock_commit_config.assert_called_with(
task.node, raid_controller='RAID.Integrated.1-1', reboot=False,
realtime=True)
self.assertEqual(expected_state, return_value)
self.assertEqual(2, mock_commit_config.call_count)
self.assertEqual(1, mock_client.create_virtual_disk.call_count)
self.assertEqual(1, mock_change_physical_disk_state.call_count)
self.node.refresh()
self.assertEqual(['42'],
self.assertEqual(['42', '12'],
self.node.driver_internal_info['raid_config_job_ids'])
def test_create_configuration_in_clean(self):
@ -809,16 +885,27 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
@mock.patch.object(drac_raid, 'list_physical_disks', autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'change_physical_disk_state', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'wait_for_job_completion', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'commit_config', spec_set=True,
autospec=True)
def test_create_configuration_no_change(
self, mock_commit_config, mock_validate_job_queue,
mock_list_physical_disks,
mock_get_drac_client):
self, mock_commit_config, mock_wait_for_job_completion,
mock_change_physical_disk_state, mock_validate_job_queue,
mock_list_physical_disks, mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
physical_disks = self._generate_physical_disks()
mock_list_physical_disks.return_value = physical_disks
mock_change_physical_disk_state.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'conversion_results': {
'RAID.Integrated.1-1': {'is_reboot_required': 'optional',
'is_commit_required': True}},
'commit_required_ids': ['RAID.Integrated.1-1']}
mock_commit_config.return_value = '42'
mock_client.create_virtual_disk.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'is_commit_required': True}
@ -842,6 +929,10 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
@mock.patch.object(drac_raid, '_reset_raid_config', autospec=True)
@mock.patch.object(drac_raid, 'list_virtual_disks', autospec=True)
@mock.patch.object(drac_raid, 'list_physical_disks', autospec=True)
@mock.patch.object(drac_raid, 'change_physical_disk_state', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'wait_for_job_completion', 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,
@ -849,6 +940,8 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
def test_create_configuration_delete_existing(
self, mock_commit_config,
mock_validate_job_queue,
mock_wait_for_job_completion,
mock_change_physical_disk_state,
mock_list_physical_disks,
mock_list_virtual_disks,
mock__reset_raid_config,
@ -871,12 +964,19 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
raid_controller = test_utils.make_raid_controller(
raid_controller_dict)
mock_list_physical_disks.return_value = physical_disks
mock_commit_config.return_value = '42'
mock_commit_config.side_effect = ['42', '12']
mock_client.list_raid_controllers.return_value = [raid_controller]
mock__reset_raid_config.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'is_commit_required': True}
mock_change_physical_disk_state.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'conversion_results': {
'RAID.Integrated.1-1': {'is_reboot_required': 'optional',
'is_commit_required': True}},
'commit_required_ids': ['RAID.Integrated.1-1']}
mock_client.create_virtual_disk.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'is_commit_required': True
@ -892,15 +992,15 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
['Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1',
'Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1'],
'1', 51200, None, 2, 1)
mock_commit_config.assert_called_once_with(
mock_commit_config.assert_called_with(
task.node, raid_controller='RAID.Integrated.1-1',
realtime=True, reboot=False)
self.assertEqual(1, mock_commit_config.call_count)
self.assertEqual(2, mock_commit_config.call_count)
self.assertEqual(states.DEPLOYWAIT, return_value)
self.node.refresh()
self.assertEqual(['42'],
self.assertEqual(['42', '12'],
self.node.driver_internal_info['raid_config_job_ids'])
@mock.patch.object(drac_common, 'get_drac_client', spec_set=True,
@ -908,10 +1008,15 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
@mock.patch.object(drac_raid, 'list_physical_disks', autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'change_physical_disk_state', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'wait_for_job_completion', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'commit_config', spec_set=True,
autospec=True)
def test_create_configuration_with_nested_raid_level(
self, mock_commit_config, mock_validate_job_queue,
self, mock_commit_config, mock_wait_for_job_completion,
mock_change_physical_disk_state, mock_validate_job_queue,
mock_list_physical_disks, mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
@ -929,7 +1034,13 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
physical_disks = self._generate_physical_disks()
mock_list_physical_disks.return_value = physical_disks
mock_commit_config.return_value = '42'
mock_commit_config.side_effect = ['42', '12']
mock_change_physical_disk_state.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'conversion_results': {
'RAID.Integrated.1-1': {'is_reboot_required': 'optional',
'is_commit_required': True}},
'commit_required_ids': ['RAID.Integrated.1-1']}
mock_client.create_virtual_disk.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'is_commit_required': True}
@ -951,12 +1062,16 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
'5+0', 102400, None, 3, 2)
# Commits to the controller
mock_commit_config.assert_called_once_with(
mock_commit_config.assert_called_with(
mock.ANY, raid_controller='RAID.Integrated.1-1', reboot=False,
realtime=True)
self.assertEqual(2, mock_commit_config.call_count)
self.assertEqual(1, mock_client.create_virtual_disk.call_count)
self.assertEqual(1, mock_change_physical_disk_state.call_count)
self.node.refresh()
self.assertEqual(['42'],
self.assertEqual(['42', '12'],
self.node.driver_internal_info['raid_config_job_ids'])
@mock.patch.object(drac_common, 'get_drac_client', spec_set=True,
@ -964,12 +1079,16 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
@mock.patch.object(drac_raid, 'list_physical_disks', autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'change_physical_disk_state', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'wait_for_job_completion', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'commit_config', spec_set=True,
autospec=True)
def test_create_configuration_with_nested_raid_10(
self, mock_commit_config,
mock_validate_job_queue, mock_list_physical_disks,
mock_get_drac_client):
self, mock_commit_config, mock_wait_for_job_completion,
mock_change_physical_disk_state, mock_validate_job_queue,
mock_list_physical_disks, mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
@ -986,7 +1105,13 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
physical_disks = self._generate_physical_disks()
mock_list_physical_disks.return_value = physical_disks
mock_commit_config.return_value = '42'
mock_commit_config.side_effect = ['42', '12']
mock_change_physical_disk_state.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'conversion_results': {
'RAID.Integrated.1-1': {'is_reboot_required': 'optional',
'is_commit_required': True}},
'commit_required_ids': ['RAID.Integrated.1-1']}
mock_client.create_virtual_disk.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'is_commit_required': True}
@ -1006,12 +1131,16 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
'1+0', 102400, None, None, None)
# Commits to the controller
mock_commit_config.assert_called_once_with(
mock_commit_config.assert_called_with(
mock.ANY, raid_controller='RAID.Integrated.1-1', reboot=False,
realtime=True)
self.assertEqual(2, mock_commit_config.call_count)
self.assertEqual(1, mock_client.create_virtual_disk.call_count)
self.assertEqual(1, mock_change_physical_disk_state.call_count)
self.node.refresh()
self.assertEqual(['42'],
self.assertEqual(['42', '12'],
self.node.driver_internal_info['raid_config_job_ids'])
@mock.patch.object(drac_common, 'get_drac_client', spec_set=True,
@ -1019,10 +1148,15 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
@mock.patch.object(drac_raid, 'list_physical_disks', autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'change_physical_disk_state', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'wait_for_job_completion', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'commit_config', spec_set=True,
autospec=True)
def test_create_configuration_with_multiple_controllers(
self, mock_commit_config, mock_validate_job_queue,
self, mock_commit_config, mock_wait_for_job_completion,
mock_change_physical_disk_state, mock_validate_job_queue,
mock_list_physical_disks, mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
@ -1032,7 +1166,15 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
physical_disks = self._generate_physical_disks()
mock_list_physical_disks.return_value = physical_disks
mock_commit_config.side_effect = ['42', '12', '13']
mock_commit_config.side_effect = ['42', '12', '13', '14']
mock_change_physical_disk_state.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'conversion_results': {
'RAID.Integrated.1-1': {'is_reboot_required': 'optional',
'is_commit_required': True}},
'commit_required_ids': ['RAID.Integrated.1-1']}
mock_client.create_virtual_disk.side_effect = [{
'is_reboot_required': constants.RebootRequired.true,
'is_commit_required': True
@ -1079,7 +1221,7 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
any_order=True)
self.node.refresh()
self.assertEqual(['42', '12', '13'],
self.assertEqual(['42', '12', '13', '14'],
self.node.driver_internal_info['raid_config_job_ids'])
@mock.patch.object(drac_common, 'get_drac_client', spec_set=True,
@ -1087,10 +1229,15 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
@mock.patch.object(drac_raid, 'list_physical_disks', autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'change_physical_disk_state', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'wait_for_job_completion', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'commit_config', spec_set=True,
autospec=True)
def test_create_configuration_with_backing_physical_disks(
self, mock_commit_config, mock_validate_job_queue,
self, mock_commit_config, mock_wait_for_job_completion,
mock_change_physical_disk_state, mock_validate_job_queue,
mock_list_physical_disks, mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
@ -1107,7 +1254,14 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
physical_disks = self._generate_physical_disks()
mock_list_physical_disks.return_value = physical_disks
mock_commit_config.side_effect = ['42', '12', '13']
mock_commit_config.side_effect = ['42', '12']
mock_change_physical_disk_state.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'conversion_results': {
'RAID.Integrated.1-1': {'is_reboot_required': 'optional',
'is_commit_required': True}},
'commit_required_ids': ['RAID.Integrated.1-1']}
mock_client.create_virtual_disk.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'is_commit_required': True
@ -1144,7 +1298,7 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
reboot=False, realtime=True)
self.node.refresh()
self.assertEqual(['42'],
self.assertEqual(['42', '12'],
self.node.driver_internal_info['raid_config_job_ids'])
@mock.patch.object(drac_common, 'get_drac_client', spec_set=True,
@ -1152,12 +1306,16 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
@mock.patch.object(drac_raid, 'list_physical_disks', autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'change_physical_disk_state', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'wait_for_job_completion', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'commit_config', spec_set=True,
autospec=True)
def test_create_configuration_with_predefined_number_of_phyisical_disks(
self, mock_commit_config, mock_validate_job_queue,
self, mock_commit_config, mock_wait_for_job_completion,
mock_change_physical_disk_state, mock_validate_job_queue,
mock_list_physical_disks, mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
@ -1172,6 +1330,12 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
physical_disks = self._generate_physical_disks()
mock_list_physical_disks.return_value = physical_disks
mock_commit_config.side_effect = ['42', '12']
mock_change_physical_disk_state.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'conversion_results': {
'RAID.Integrated.1-1': {'is_reboot_required': 'optional',
'is_commit_required': True}},
'commit_required_ids': ['RAID.Integrated.1-1']}
mock_client.create_virtual_disk.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'is_commit_required': True
@ -1204,7 +1368,7 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
reboot=False, realtime=True)
self.node.refresh()
self.assertEqual(['42'],
self.assertEqual(['42', '12'],
self.node.driver_internal_info['raid_config_job_ids'])
@mock.patch.object(drac_common, 'get_drac_client', spec_set=True,
@ -1212,10 +1376,15 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
@mock.patch.object(drac_raid, 'list_physical_disks', autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'change_physical_disk_state', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'wait_for_job_completion', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'commit_config', spec_set=True,
autospec=True)
def test_create_configuration_with_max_size(
self, mock_commit_config, mock_validate_job_queue,
self, mock_commit_config, mock_wait_for_job_completion,
mock_change_physical_disk_state, mock_validate_job_queue,
mock_list_physical_disks, mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
@ -1237,7 +1406,13 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
physical_disks = self._generate_physical_disks()
mock_list_physical_disks.return_value = physical_disks
mock_commit_config.side_effect = ['42', '12', '13']
mock_commit_config.side_effect = ['42', '12']
mock_change_physical_disk_state.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'conversion_results': {
'RAID.Integrated.1-1': {'is_reboot_required': 'optional',
'is_commit_required': True}},
'commit_required_ids': ['RAID.Integrated.1-1']}
mock_client.create_virtual_disk.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'is_commit_required': True
@ -1275,7 +1450,7 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
realtime=True)
self.node.refresh()
self.assertEqual(['42'],
self.assertEqual(['42', '12'],
self.node.driver_internal_info['raid_config_job_ids'])
@mock.patch.object(drac_common, 'get_drac_client', spec_set=True,
@ -1312,10 +1487,15 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
@mock.patch.object(drac_raid, 'list_physical_disks', autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'change_physical_disk_state', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'wait_for_job_completion', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'commit_config', spec_set=True,
autospec=True)
def test_create_configuration_with_share_physical_disks(
self, mock_commit_config, mock_validate_job_queue,
self, mock_commit_config, mock_wait_for_job_completion,
mock_change_physical_disk_state, mock_validate_job_queue,
mock_list_physical_disks, mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
@ -1332,6 +1512,12 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
mock_list_physical_disks.return_value = physical_disks
mock_commit_config.side_effect = ['42', '12']
mock_change_physical_disk_state.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'conversion_results': {
'RAID.Integrated.1-1': {'is_reboot_required': 'optional',
'is_commit_required': True}},
'commit_required_ids': ['RAID.Integrated.1-1']}
mock_client.create_virtual_disk.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'is_commit_required': True
@ -1363,7 +1549,7 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
realtime=True)
self.node.refresh()
self.assertEqual(['42'],
self.assertEqual(['42', '12'],
self.node.driver_internal_info['raid_config_job_ids'])
@mock.patch.object(drac_common, 'get_drac_client', spec_set=True,
@ -1420,12 +1606,16 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
@mock.patch.object(drac_raid, 'list_physical_disks', autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'change_physical_disk_state', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'wait_for_job_completion', spec_set=True,
autospec=True)
@mock.patch.object(drac_raid, 'commit_config', spec_set=True,
autospec=True)
def test_create_configuration_with_max_size_and_share_physical_disks(
self, mock_commit_config, mock_validate_job_queue,
mock_list_physical_disks,
mock_get_drac_client):
self, mock_commit_config, mock_wait_for_job_completion,
mock_change_physical_disk_state, mock_validate_job_queue,
mock_list_physical_disks, mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
@ -1445,7 +1635,13 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
physical_disks = self._generate_physical_disks()
mock_list_physical_disks.return_value = physical_disks
mock_commit_config.return_value = '42'
mock_commit_config.side_effect = ['42', '12']
mock_change_physical_disk_state.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'conversion_results': {
'RAID.Integrated.1-1': {'is_reboot_required': 'optional',
'is_commit_required': True}},
'commit_required_ids': ['RAID.Integrated.1-1']}
mock_client.create_virtual_disk.return_value = {
'is_reboot_required': constants.RebootRequired.optional,
'is_commit_required': True
@ -1478,7 +1674,7 @@ class DracRaidInterfaceTestCase(test_utils.BaseDracTest):
realtime=True)
self.node.refresh()
self.assertEqual(['42'],
self.assertEqual(['42', '12'],
self.node.driver_internal_info['raid_config_job_ids'])
@mock.patch.object(drac_common, 'get_drac_client', spec_set=True,

View File

@ -31,7 +31,8 @@ DRACCLIENT_CONSTANTS_MOD_SPEC = (
'POWER_OFF',
'POWER_ON',
'REBOOT',
'RebootRequired'
'RebootRequired',
'RaidStatus'
)
DRACCLIENT_CONSTANTS_REBOOT_REQUIRED_MOD_SPEC = (
@ -40,6 +41,10 @@ DRACCLIENT_CONSTANTS_REBOOT_REQUIRED_MOD_SPEC = (
'false'
)
DRACCLIENT_CONSTANTS_RAID_STATUS_MOD_SPEC = (
'jbod',
'raid'
)
# proliantutils
PROLIANTUTILS_SPEC = (

View File

@ -95,6 +95,10 @@ if not dracclient:
true=mock.sentinel.true,
optional=mock.sentinel.optional,
false=mock.sentinel.false)
dracclient.constants.RaidStatus = mock.MagicMock(
spec_set=mock_specs.DRACCLIENT_CONSTANTS_RAID_STATUS_MOD_SPEC,
jbod=mock.sentinel.jbod,
raid=mock.sentinel.raid)
sys.modules['dracclient'] = dracclient
sys.modules['dracclient.client'] = dracclient.client

View File

@ -0,0 +1,5 @@
---
features:
- |
Hardware type ``idrac`` converts physical drives from
``JBOD`` to ``RAID`` mode before building RAID on them.