Add a real-time option when commit RAID creation/deletion

in python-dracclient.

Change-Id: I3ada0e51235941620c9f27796da9790a182fb0e4
This commit is contained in:
digambar 2019-01-26 06:00:53 -05:00 committed by Digambar
parent b0ab6c8da8
commit 9069b1e416
6 changed files with 160 additions and 19 deletions

View File

@ -468,7 +468,8 @@ class DRACClient(object):
cim_system_creation_class_name='DCIM_ComputerSystem', cim_system_creation_class_name='DCIM_ComputerSystem',
cim_system_name='DCIM:ComputerSystem', cim_system_name='DCIM:ComputerSystem',
reboot=False, reboot=False,
start_time='TIME_NOW'): start_time='TIME_NOW',
realtime=False):
"""Creates a configuration job. """Creates a configuration job.
In CIM (Common Information Model), weak association is used to name an In CIM (Common Information Model), weak association is used to name an
@ -492,6 +493,8 @@ class DRACClient(object):
means execute immediately or None which means means execute immediately or None which means
the job will not execute until the job will not execute until
schedule_job_execution is called schedule_job_execution is called
:param realtime: Indicates if reatime mode should be used.
Valid values are True and False.
:returns: id of the created job :returns: id of the created job
:raises: WSManRequestFailure on request failures :raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response :raises: WSManInvalidResponse when receiving invalid response
@ -508,7 +511,8 @@ class DRACClient(object):
cim_system_creation_class_name=cim_system_creation_class_name, cim_system_creation_class_name=cim_system_creation_class_name,
cim_system_name=cim_system_name, cim_system_name=cim_system_name,
reboot=reboot, reboot=reboot,
start_time=start_time) start_time=start_time,
realtime=realtime)
def create_nic_config_job( def create_nic_config_job(
self, self,
@ -785,7 +789,7 @@ class DRACClient(object):
return self._raid_mgmt.delete_virtual_disk(virtual_disk) return self._raid_mgmt.delete_virtual_disk(virtual_disk)
def commit_pending_raid_changes(self, raid_controller, reboot=False, def commit_pending_raid_changes(self, raid_controller, reboot=False,
start_time='TIME_NOW'): start_time='TIME_NOW', realtime=False):
"""Applies all pending changes on a RAID controller """Applies all pending changes on a RAID controller
...by creating a config job. ...by creating a config job.
@ -798,6 +802,8 @@ class DRACClient(object):
means execute immediately or None which means means execute immediately or None which means
the job will not execute until the job will not execute until
schedule_job_execution is called schedule_job_execution is called
:param realtime: Indicates if reatime mode should be used.
Valid values are True and False.
:returns: id of the created job :returns: id of the created job
:raises: WSManRequestFailure on request failures :raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response :raises: WSManInvalidResponse when receiving invalid response
@ -811,7 +817,8 @@ class DRACClient(object):
cim_name='DCIM:RAIDService', cim_name='DCIM:RAIDService',
target=raid_controller, target=raid_controller,
reboot=reboot, reboot=reboot,
start_time=start_time) start_time=start_time,
realtime=realtime)
def abandon_pending_raid_changes(self, raid_controller): def abandon_pending_raid_changes(self, raid_controller):
"""Deletes all pending changes on a RAID controller """Deletes all pending changes on a RAID controller
@ -830,6 +837,14 @@ class DRACClient(object):
cim_creation_class_name='DCIM_RAIDService', cim_creation_class_name='DCIM_RAIDService',
cim_name='DCIM:RAIDService', target=raid_controller) cim_name='DCIM:RAIDService', target=raid_controller)
def is_realtime_supported(self, raid_controller):
"""Find if controller supports realtime or not
:param raid_controller: ID of RAID controller
:returns: True or False
"""
return self._raid_mgmt.is_realtime_supported(raid_controller)
def list_cpus(self): def list_cpus(self):
"""Returns the list of CPUs """Returns the list of CPUs

View File

@ -101,7 +101,8 @@ class JobManagement(object):
cim_system_creation_class_name='DCIM_ComputerSystem', cim_system_creation_class_name='DCIM_ComputerSystem',
cim_system_name='DCIM:ComputerSystem', cim_system_name='DCIM:ComputerSystem',
reboot=False, reboot=False,
start_time='TIME_NOW'): start_time='TIME_NOW',
realtime=False):
"""Creates a config job """Creates a config job
In CIM (Common Information Model), weak association is used to name an In CIM (Common Information Model), weak association is used to name an
@ -126,6 +127,8 @@ class JobManagement(object):
but will not start execution until but will not start execution until
schedule_job_execution is called with the returned schedule_job_execution is called with the returned
job id. job id.
:param realtime: Indicates if reatime mode should be used.
Valid values are True and False. Default value is False.
:returns: id of the created job :returns: id of the created job
:raises: WSManRequestFailure on request failures :raises: WSManRequestFailure on request failures
:raises: WSManInvalidResponse when receiving invalid response :raises: WSManInvalidResponse when receiving invalid response
@ -141,7 +144,10 @@ class JobManagement(object):
properties = {'Target': target} properties = {'Target': target}
if reboot: if realtime:
properties['RealTime'] = '1'
if not realtime and reboot:
properties['RebootJobType'] = '3' properties['RebootJobType'] = '3'
if start_time is not None: if start_time is not None:

View File

@ -34,6 +34,11 @@ RAID_LEVELS = {
REVERSE_RAID_LEVELS = dict((v, k) for (k, v) in RAID_LEVELS.items()) REVERSE_RAID_LEVELS = dict((v, k) for (k, v) in RAID_LEVELS.items())
RAID_CONTROLLER_IS_REALTIME = {
'1': True,
'0': False
}
DISK_RAID_STATUS = { DISK_RAID_STATUS = {
'0': 'unknown', '0': 'unknown',
'1': 'ready', '1': 'ready',
@ -80,7 +85,8 @@ PhysicalDisk = collections.namedtuple(
RAIDController = collections.namedtuple( RAIDController = collections.namedtuple(
'RAIDController', ['id', 'description', 'manufacturer', 'model', 'RAIDController', ['id', 'description', 'manufacturer', 'model',
'primary_status', 'firmware_version', 'bus']) 'primary_status', 'firmware_version', 'bus',
'supports_realtime'])
VirtualDisk = collections.namedtuple( VirtualDisk = collections.namedtuple(
'VirtualDisk', 'VirtualDisk',
@ -131,7 +137,10 @@ class RAIDManagement(object):
'PrimaryStatus')], 'PrimaryStatus')],
firmware_version=self._get_raid_controller_attr( firmware_version=self._get_raid_controller_attr(
drac_controller, 'ControllerFirmwareVersion'), drac_controller, 'ControllerFirmwareVersion'),
bus=self._get_raid_controller_attr(drac_controller, 'Bus')) bus=self._get_raid_controller_attr(drac_controller, 'Bus'),
supports_realtime=RAID_CONTROLLER_IS_REALTIME[
self._get_raid_controller_attr(
drac_controller, 'RealtimeCapability')])
def _get_raid_controller_attr(self, drac_controller, attr_name): def _get_raid_controller_attr(self, drac_controller, attr_name):
return utils.get_wsman_resource_attr( return utils.get_wsman_resource_attr(
@ -703,3 +712,18 @@ class RAIDManagement(object):
return {'is_reboot_required': is_reboot_required, return {'is_reboot_required': is_reboot_required,
'commit_required_ids': controllers} 'commit_required_ids': controllers}
def is_realtime_supported(self, raid_controller_fqdd):
"""Find if controller supports realtime or not
:param raid_controller_fqdd: ID of RAID controller
:returns: True or False
"""
drac_raid_controllers = self.list_raid_controllers()
realtime_controller = [cnt.id for cnt in drac_raid_controllers
if cnt.supports_realtime]
if raid_controller_fqdd in realtime_controller:
return True
return False

View File

@ -342,7 +342,34 @@ class ClientJobManagementTestCase(base.BaseTest):
job_id = self.drac_client.create_config_job( job_id = self.drac_client.create_config_job(
uris.DCIM_BIOSService, cim_creation_class_name, cim_name, target, uris.DCIM_BIOSService, cim_creation_class_name, cim_name, target,
reboot=True) reboot=True, realtime=False)
mock_invoke.assert_called_once_with(
mock.ANY, uris.DCIM_BIOSService, 'CreateTargetedConfigJob',
expected_selectors, expected_properties,
expected_return_value=utils.RET_CREATED)
self.assertEqual('JID_442507917525', job_id)
@mock.patch.object(dracclient.client.WSManClient, 'invoke', spec_set=True,
autospec=True)
def test_create_config_job_with_realtime(self, mock_invoke):
cim_creation_class_name = 'DCIM_BIOSService'
cim_name = 'DCIM:BIOSService'
target = 'BIOS.Setup.1-1'
expected_selectors = {'CreationClassName': cim_creation_class_name,
'Name': cim_name,
'SystemCreationClassName': 'DCIM_ComputerSystem',
'SystemName': 'DCIM:ComputerSystem'}
expected_properties = {'Target': target,
'ScheduledStartTime': 'TIME_NOW',
'RealTime': '1'}
mock_invoke.return_value = lxml.etree.fromstring(
test_utils.JobInvocations[uris.DCIM_BIOSService][
'CreateTargetedConfigJob']['ok'])
job_id = self.drac_client.create_config_job(
uris.DCIM_BIOSService, cim_creation_class_name, cim_name, target,
reboot=False, realtime=True)
mock_invoke.assert_called_once_with( mock_invoke.assert_called_once_with(
mock.ANY, uris.DCIM_BIOSService, 'CreateTargetedConfigJob', mock.ANY, uris.DCIM_BIOSService, 'CreateTargetedConfigJob',

View File

@ -124,8 +124,8 @@ class ClientRAIDManagementTestCase(base.BaseTest):
model='PERC H710 Mini', model='PERC H710 Mini',
primary_status='ok', primary_status='ok',
firmware_version='21.3.0-0009', firmware_version='21.3.0-0009',
bus='1') bus='1',
supports_realtime=True)
mock_requests.post( mock_requests.post(
'https://1.2.3.4:443/wsman', 'https://1.2.3.4:443/wsman',
text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok']) text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
@ -597,25 +597,28 @@ class ClientRAIDManagementTestCase(base.BaseTest):
'create_config_job', spec_set=True, autospec=True) 'create_config_job', spec_set=True, autospec=True)
def test_commit_pending_raid_changes(self, mock_requests, def test_commit_pending_raid_changes(self, mock_requests,
mock_create_config_job): mock_create_config_job):
self.drac_client.commit_pending_raid_changes('controller') self.drac_client.commit_pending_raid_changes('controller',
realtime=False)
mock_create_config_job.assert_called_once_with( mock_create_config_job.assert_called_once_with(
mock.ANY, resource_uri=uris.DCIM_RAIDService, mock.ANY, resource_uri=uris.DCIM_RAIDService,
cim_creation_class_name='DCIM_RAIDService', cim_creation_class_name='DCIM_RAIDService',
cim_name='DCIM:RAIDService', target='controller', reboot=False, cim_name='DCIM:RAIDService', target='controller', reboot=False,
start_time='TIME_NOW') start_time='TIME_NOW', realtime=False)
@mock.patch.object(dracclient.resources.job.JobManagement, @mock.patch.object(dracclient.resources.job.JobManagement,
'create_config_job', spec_set=True, autospec=True) 'create_config_job', spec_set=True, autospec=True)
def test_commit_pending_raid_changes_with_reboot(self, mock_requests, def test_commit_pending_raid_changes_with_reboot(self, mock_requests,
mock_create_config_job): mock_create_config_job):
self.drac_client.commit_pending_raid_changes('controller', reboot=True) self.drac_client.commit_pending_raid_changes('controller',
reboot=True,
realtime=False)
mock_create_config_job.assert_called_once_with( mock_create_config_job.assert_called_once_with(
mock.ANY, resource_uri=uris.DCIM_RAIDService, mock.ANY, resource_uri=uris.DCIM_RAIDService,
cim_creation_class_name='DCIM_RAIDService', cim_creation_class_name='DCIM_RAIDService',
cim_name='DCIM:RAIDService', target='controller', reboot=True, cim_name='DCIM:RAIDService', target='controller', reboot=True,
start_time='TIME_NOW') start_time='TIME_NOW', realtime=False)
@mock.patch.object(dracclient.resources.job.JobManagement, @mock.patch.object(dracclient.resources.job.JobManagement,
'create_config_job', spec_set=True, autospec=True) 'create_config_job', spec_set=True, autospec=True)
@ -624,13 +627,14 @@ class ClientRAIDManagementTestCase(base.BaseTest):
mock_create_config_job): mock_create_config_job):
timestamp = '20140924140201' timestamp = '20140924140201'
self.drac_client.commit_pending_raid_changes('controller', self.drac_client.commit_pending_raid_changes('controller',
start_time=timestamp) start_time=timestamp,
realtime=False)
mock_create_config_job.assert_called_once_with( mock_create_config_job.assert_called_once_with(
mock.ANY, resource_uri=uris.DCIM_RAIDService, mock.ANY, resource_uri=uris.DCIM_RAIDService,
cim_creation_class_name='DCIM_RAIDService', cim_creation_class_name='DCIM_RAIDService',
cim_name='DCIM:RAIDService', target='controller', reboot=False, cim_name='DCIM:RAIDService', target='controller', reboot=False,
start_time=timestamp) start_time=timestamp, realtime=False)
@mock.patch.object(dracclient.resources.job.JobManagement, @mock.patch.object(dracclient.resources.job.JobManagement,
'create_config_job', spec_set=True, autospec=True) 'create_config_job', spec_set=True, autospec=True)
@ -640,13 +644,31 @@ class ClientRAIDManagementTestCase(base.BaseTest):
timestamp = '20140924140201' timestamp = '20140924140201'
self.drac_client.commit_pending_raid_changes('controller', self.drac_client.commit_pending_raid_changes('controller',
reboot=True, reboot=True,
start_time=timestamp) start_time=timestamp,
realtime=False)
mock_create_config_job.assert_called_once_with( mock_create_config_job.assert_called_once_with(
mock.ANY, resource_uri=uris.DCIM_RAIDService, mock.ANY, resource_uri=uris.DCIM_RAIDService,
cim_creation_class_name='DCIM_RAIDService', cim_creation_class_name='DCIM_RAIDService',
cim_name='DCIM:RAIDService', target='controller', reboot=True, cim_name='DCIM:RAIDService', target='controller', reboot=True,
start_time=timestamp) start_time=timestamp, realtime=False)
@mock.patch.object(dracclient.resources.job.JobManagement,
'create_config_job', spec_set=True, autospec=True)
def test_commit_pending_raid_changes_with_realtime(
self, mock_requests,
mock_create_config_job):
timestamp = '20140924140201'
self.drac_client.commit_pending_raid_changes('controller',
reboot=False,
start_time=timestamp,
realtime=True)
mock_create_config_job.assert_called_once_with(
mock.ANY, resource_uri=uris.DCIM_RAIDService,
cim_creation_class_name='DCIM_RAIDService',
cim_name='DCIM:RAIDService', target='controller', reboot=False,
start_time=timestamp, realtime=True)
@mock.patch.object(dracclient.resources.job.JobManagement, @mock.patch.object(dracclient.resources.job.JobManagement,
'delete_pending_config', spec_set=True, autospec=True) 'delete_pending_config', spec_set=True, autospec=True)
@ -659,6 +681,17 @@ class ClientRAIDManagementTestCase(base.BaseTest):
cim_creation_class_name='DCIM_RAIDService', cim_creation_class_name='DCIM_RAIDService',
cim_name='DCIM:RAIDService', target='controller') cim_name='DCIM:RAIDService', target='controller')
@mock.patch.object(dracclient.resources.job.JobManagement,
'delete_pending_config', spec_set=True, autospec=True)
def test_abandon_pending_raid_changes_realtime(self, mock_requests,
mock_delete_pending_config):
self.drac_client.abandon_pending_raid_changes('controller')
mock_delete_pending_config.assert_called_once_with(
mock.ANY, resource_uri=uris.DCIM_RAIDService,
cim_creation_class_name='DCIM_RAIDService',
cim_name='DCIM:RAIDService', target='controller')
@mock.patch.object(dracclient.client.WSManClient, @mock.patch.object(dracclient.client.WSManClient,
'wait_until_idrac_is_ready', spec_set=True, 'wait_until_idrac_is_ready', spec_set=True,
autospec=True) autospec=True)
@ -1153,3 +1186,37 @@ class ClientRAIDManagementTestCase(base.BaseTest):
results = self.drac_client.change_physical_disk_state(mode) results = self.drac_client.change_physical_disk_state(mode)
self.assertFalse(results["is_reboot_required"]) self.assertFalse(results["is_reboot_required"])
self.assertEqual(len(results["commit_required_ids"]), 0) self.assertEqual(len(results["commit_required_ids"]), 0)
@mock.patch.object(dracclient.client.WSManClient,
'wait_until_idrac_is_ready', spec_set=True,
autospec=True)
def test_is_realtime_supported_with_realtime_controller(
self,
mock_requests,
mock_wait_until_idrac_is_ready):
expected_raid_controller = 'RAID.Integrated.1-1'
mock_requests.post(
'https://1.2.3.4:443/wsman',
text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
self.assertTrue(
self.drac_client.is_realtime_supported(
expected_raid_controller))
@mock.patch.object(dracclient.client.WSManClient,
'wait_until_idrac_is_ready', spec_set=True,
autospec=True)
def test_is_realtime_supported_with_non_realtime_controller(
self,
mock_requests,
mock_wait_until_idrac_is_ready):
expected_raid_controller = 'AHCI.Integrated.1-1'
mock_requests.post(
'https://1.2.3.4:443/wsman',
text=test_utils.RAIDEnumerations[uris.DCIM_ControllerView]['ok'])
self.assertFalse(
self.drac_client.is_realtime_supported(
expected_raid_controller))

View File

@ -43,6 +43,7 @@
<n1:PatrolReadState>0</n1:PatrolReadState> <n1:PatrolReadState>0</n1:PatrolReadState>
<n1:PrimaryStatus>1</n1:PrimaryStatus> <n1:PrimaryStatus>1</n1:PrimaryStatus>
<n1:ProductName>PERC H710 Mini</n1:ProductName> <n1:ProductName>PERC H710 Mini</n1:ProductName>
<n1:RealtimeCapability>1</n1:RealtimeCapability>
<n1:RollupStatus>1</n1:RollupStatus> <n1:RollupStatus>1</n1:RollupStatus>
<n1:SASAddress>5B083FE0D2D0F200</n1:SASAddress> <n1:SASAddress>5B083FE0D2D0F200</n1:SASAddress>
<n1:SecurityStatus>1</n1:SecurityStatus> <n1:SecurityStatus>1</n1:SecurityStatus>
@ -82,6 +83,7 @@
<n1:PatrolReadState>0</n1:PatrolReadState> <n1:PatrolReadState>0</n1:PatrolReadState>
<n1:PrimaryStatus>1</n1:PrimaryStatus> <n1:PrimaryStatus>1</n1:PrimaryStatus>
<n1:ProductName>BOSS-S1</n1:ProductName> <n1:ProductName>BOSS-S1</n1:ProductName>
<n1:RealtimeCapability>0</n1:RealtimeCapability>
<n1:RollupStatus>1</n1:RollupStatus> <n1:RollupStatus>1</n1:RollupStatus>
<n1:SASAddress>5B083FE0D2D0F201</n1:SASAddress> <n1:SASAddress>5B083FE0D2D0F201</n1:SASAddress>
<n1:SecurityStatus>1</n1:SecurityStatus> <n1:SecurityStatus>1</n1:SecurityStatus>