Allow usage of virtual media via System
DMTF now changes their Virtual Media URI to support Systems. Redfish driver now support this resource to boot, so it is needed that Ironic have a way to use it. Closes-Bug: #2039458 Change-Id: I66e8edb847e93f96374072525222f05e7561fb07
This commit is contained in:
parent
2f3448a421
commit
6d046ad7b4
@ -167,10 +167,36 @@ def _test_retry(exception):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@tenacity.retry(retry=tenacity.retry_if_exception(_test_retry),
|
def _has_vmedia_via_systems(system):
|
||||||
stop=tenacity.stop_after_attempt(3),
|
"""Indicates if virtual media is available trough Systems
|
||||||
wait=tenacity.wait_fixed(3),
|
|
||||||
reraise=True)
|
:param system: A redfish System object
|
||||||
|
:return: True if the System has virtual media, else False
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
system.virtual_media
|
||||||
|
return True
|
||||||
|
except sushy.exceptions.MissingAttributeError:
|
||||||
|
return False
|
||||||
|
except AttributeError:
|
||||||
|
# NOTE(wncslln): In case of older versions of sushy are
|
||||||
|
# used.
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _has_vmedia_via_manager(manager):
|
||||||
|
"""Indicates if virtual media is available in the Manager
|
||||||
|
|
||||||
|
:param manager: A redfish System object
|
||||||
|
:return: True if the System has virtual media, else False
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
manager.virtual_media
|
||||||
|
return True
|
||||||
|
except sushy.exceptions.MissingAttributeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _insert_vmedia(task, managers, boot_url, boot_device):
|
def _insert_vmedia(task, managers, boot_url, boot_device):
|
||||||
"""Insert bootable ISO image into virtual CD or DVD
|
"""Insert bootable ISO image into virtual CD or DVD
|
||||||
|
|
||||||
@ -182,9 +208,46 @@ def _insert_vmedia(task, managers, boot_url, boot_device):
|
|||||||
:raises: InvalidParameterValue, if no suitable virtual CD or DVD is
|
:raises: InvalidParameterValue, if no suitable virtual CD or DVD is
|
||||||
found on the node.
|
found on the node.
|
||||||
"""
|
"""
|
||||||
err_msg = None
|
err_msgs = []
|
||||||
|
system = redfish_utils.get_system(task.node)
|
||||||
|
if _has_vmedia_via_systems(system):
|
||||||
|
inserted = _insert_vmedia_in_resource(task, system, boot_url,
|
||||||
|
boot_device, err_msgs)
|
||||||
|
if inserted:
|
||||||
|
return
|
||||||
|
else:
|
||||||
for manager in managers:
|
for manager in managers:
|
||||||
for v_media in manager.virtual_media.get_members():
|
inserted = _insert_vmedia_in_resource(task, manager, boot_url,
|
||||||
|
boot_device, err_msgs)
|
||||||
|
if inserted:
|
||||||
|
return
|
||||||
|
|
||||||
|
if err_msgs:
|
||||||
|
exc_msg = ("All virtual media mount attempts failed. "
|
||||||
|
"Most recent error: ", err_msgs[-1])
|
||||||
|
else:
|
||||||
|
exc_msg = 'No suitable virtual media device found'
|
||||||
|
raise exception.InvalidParameterValue(exc_msg)
|
||||||
|
|
||||||
|
|
||||||
|
@tenacity.retry(retry=tenacity.retry_if_exception(_test_retry),
|
||||||
|
stop=tenacity.stop_after_attempt(3),
|
||||||
|
wait=tenacity.wait_fixed(3),
|
||||||
|
reraise=True)
|
||||||
|
def _insert_vmedia_in_resource(task, resource, boot_url, boot_device,
|
||||||
|
err_msgs):
|
||||||
|
"""Insert virtual media from a given redfish resource (System/Manager)
|
||||||
|
|
||||||
|
:param task: A task from TaskManager.
|
||||||
|
:param resource: A redfish resource either a System or Manager.
|
||||||
|
:param boot_url: URL to a bootable ISO image
|
||||||
|
:param boot_device: sushy boot device e.g. `VIRTUAL_MEDIA_CD`,
|
||||||
|
`VIRTUAL_MEDIA_DVD` or `VIRTUAL_MEDIA_FLOPPY`
|
||||||
|
:param err_msgs: A list that will contain all errors found
|
||||||
|
:raises: InvalidParameterValue, if no suitable virtual CD or DVD is
|
||||||
|
found on the node.
|
||||||
|
"""
|
||||||
|
for v_media in resource.virtual_media.get_members():
|
||||||
if boot_device not in v_media.media_types:
|
if boot_device not in v_media.media_types:
|
||||||
# NOTE(janders): this conditional allows v_media that only
|
# NOTE(janders): this conditional allows v_media that only
|
||||||
# support DVD MediaType and NOT CD to also be used.
|
# support DVD MediaType and NOT CD to also be used.
|
||||||
@ -211,7 +274,7 @@ def _insert_vmedia(task, managers, boot_url, boot_device):
|
|||||||
"%(node)s", {'node': task.node.uuid,
|
"%(node)s", {'node': task.node.uuid,
|
||||||
'boot_url': boot_url,
|
'boot_url': boot_url,
|
||||||
'boot_device': boot_device})
|
'boot_device': boot_device})
|
||||||
return
|
return True
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -229,6 +292,7 @@ def _insert_vmedia(task, managers, boot_url, boot_device):
|
|||||||
"media device, if available",
|
"media device, if available",
|
||||||
{'node': task.node.uuid,
|
{'node': task.node.uuid,
|
||||||
'boot_device': boot_device})
|
'boot_device': boot_device})
|
||||||
|
err_msgs.append(err_msg)
|
||||||
LOG.warning(err_msg)
|
LOG.warning(err_msg)
|
||||||
continue
|
continue
|
||||||
except sushy.exceptions.ServerSideError as e:
|
except sushy.exceptions.ServerSideError as e:
|
||||||
@ -240,13 +304,7 @@ def _insert_vmedia(task, managers, boot_url, boot_device):
|
|||||||
"%(node)s", {'node': task.node.uuid,
|
"%(node)s", {'node': task.node.uuid,
|
||||||
'boot_url': boot_url,
|
'boot_url': boot_url,
|
||||||
'boot_device': boot_device})
|
'boot_device': boot_device})
|
||||||
return
|
return True
|
||||||
if (err_msg is not None):
|
|
||||||
exc_msg = ("All virtual media mount attempts failed. "
|
|
||||||
"Most recent error: ", err_msg)
|
|
||||||
else:
|
|
||||||
exc_msg = 'No suitable virtual media device found'
|
|
||||||
raise exception.InvalidParameterValue(exc_msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _eject_vmedia(task, managers, boot_device=None):
|
def _eject_vmedia(task, managers, boot_device=None):
|
||||||
@ -262,8 +320,38 @@ def _eject_vmedia(task, managers, boot_device=None):
|
|||||||
found on the node.
|
found on the node.
|
||||||
"""
|
"""
|
||||||
found = False
|
found = False
|
||||||
|
system = redfish_utils.get_system(task.node)
|
||||||
|
# NOTE(wncslln): we will attempt to eject virtual media in Systems
|
||||||
|
# and in Managers.
|
||||||
|
if _has_vmedia_via_systems(system):
|
||||||
|
ejected = _eject_vmedia_from_resource(task, resource=system,
|
||||||
|
boot_device=boot_device)
|
||||||
|
if ejected:
|
||||||
|
found = True
|
||||||
|
|
||||||
for manager in managers:
|
for manager in managers:
|
||||||
for v_media in manager.virtual_media.get_members():
|
if _has_vmedia_via_manager(manager):
|
||||||
|
ejected = _eject_vmedia_from_resource(task, resource=manager,
|
||||||
|
boot_device=boot_device)
|
||||||
|
if ejected:
|
||||||
|
found = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
return found
|
||||||
|
|
||||||
|
|
||||||
|
def _eject_vmedia_from_resource(task, resource, boot_device=None):
|
||||||
|
"""Eject virtual media from a given redfish resource (System/Manager)
|
||||||
|
|
||||||
|
:param task: A task from TaskManager.
|
||||||
|
:param resource: A redfish resource either a System or Manager.
|
||||||
|
:param boot_device: sushy boot device e.g. `VIRTUAL_MEDIA_CD`,
|
||||||
|
`VIRTUAL_MEDIA_DVD` or `VIRTUAL_MEDIA_FLOPPY` or `None` to
|
||||||
|
eject everything (default).
|
||||||
|
:return: True if any device was ejected, else False
|
||||||
|
"""
|
||||||
|
found = False
|
||||||
|
for v_media in resource.virtual_media.get_members():
|
||||||
if boot_device and boot_device not in v_media.media_types:
|
if boot_device and boot_device not in v_media.media_types:
|
||||||
# NOTE(iurygregory): this conditional allows v_media that only
|
# NOTE(iurygregory): this conditional allows v_media that only
|
||||||
# support DVD MediaType and NOT CD to also be used.
|
# support DVD MediaType and NOT CD to also be used.
|
||||||
@ -283,7 +371,6 @@ def _eject_vmedia(task, managers, boot_device=None):
|
|||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
inserted = v_media.inserted
|
inserted = v_media.inserted
|
||||||
|
|
||||||
if inserted:
|
if inserted:
|
||||||
v_media.eject_media()
|
v_media.eject_media()
|
||||||
found = True
|
found = True
|
||||||
@ -318,8 +405,8 @@ def eject_vmedia(task, boot_device=None):
|
|||||||
image_utils.cleanup_iso_image(task)
|
image_utils.cleanup_iso_image(task)
|
||||||
|
|
||||||
|
|
||||||
def _has_vmedia_device(managers, boot_device, inserted=None):
|
def _has_vmedia_device(managers, boot_device, inserted=None, system=None):
|
||||||
"""Indicate if device exists at any of the managers
|
"""Indicate if device exists at any of the managers or system
|
||||||
|
|
||||||
:param managers: A list of System managers.
|
:param managers: A list of System managers.
|
||||||
:param boot_device: One or more sushy boot device e.g. `VIRTUAL_MEDIA_CD`,
|
:param boot_device: One or more sushy boot device e.g. `VIRTUAL_MEDIA_CD`,
|
||||||
@ -333,6 +420,15 @@ def _has_vmedia_device(managers, boot_device, inserted=None):
|
|||||||
boot_device = [boot_device]
|
boot_device = [boot_device]
|
||||||
|
|
||||||
for dev in boot_device:
|
for dev in boot_device:
|
||||||
|
if _has_vmedia_via_systems(system):
|
||||||
|
for v_media in system.virtual_media.get_members():
|
||||||
|
if dev not in v_media.media_types:
|
||||||
|
continue
|
||||||
|
if (inserted is not None
|
||||||
|
and bool(v_media.inserted) is not inserted):
|
||||||
|
continue
|
||||||
|
return dev
|
||||||
|
else:
|
||||||
for manager in managers:
|
for manager in managers:
|
||||||
for v_media in manager.virtual_media.get_members():
|
for v_media in manager.virtual_media.get_members():
|
||||||
if dev not in v_media.media_types:
|
if dev not in v_media.media_types:
|
||||||
@ -526,13 +622,14 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||||||
return
|
return
|
||||||
|
|
||||||
d_info = _parse_driver_info(node)
|
d_info = _parse_driver_info(node)
|
||||||
managers = redfish_utils.get_system(task.node).managers
|
system = redfish_utils.get_system(task.node)
|
||||||
|
managers = system.managers
|
||||||
|
|
||||||
self._validate_vendor(task, managers)
|
self._validate_vendor(task, managers)
|
||||||
|
|
||||||
if manager_utils.is_fast_track(task):
|
if manager_utils.is_fast_track(task):
|
||||||
if _has_vmedia_device(managers, sushy.VIRTUAL_MEDIA_CD,
|
if _has_vmedia_device(managers, sushy.VIRTUAL_MEDIA_CD,
|
||||||
inserted=True):
|
inserted=True, system=system):
|
||||||
LOG.debug('Fast track operation for node %s, not inserting '
|
LOG.debug('Fast track operation for node %s, not inserting '
|
||||||
'any devices', node.uuid)
|
'any devices', node.uuid)
|
||||||
return
|
return
|
||||||
@ -570,7 +667,8 @@ class RedfishVirtualMediaBoot(base.BootInterface):
|
|||||||
removable = _has_vmedia_device(
|
removable = _has_vmedia_device(
|
||||||
managers,
|
managers,
|
||||||
# Prefer USB devices since floppies are outdated
|
# Prefer USB devices since floppies are outdated
|
||||||
[sushy.VIRTUAL_MEDIA_USBSTICK, sushy.VIRTUAL_MEDIA_FLOPPY])
|
[sushy.VIRTUAL_MEDIA_USBSTICK, sushy.VIRTUAL_MEDIA_FLOPPY],
|
||||||
|
system=system)
|
||||||
if removable:
|
if removable:
|
||||||
floppy_ref = image_utils.prepare_floppy_image(
|
floppy_ref = image_utils.prepare_floppy_image(
|
||||||
task, params=ramdisk_params)
|
task, params=ramdisk_params)
|
||||||
|
@ -635,7 +635,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
mock__parse_driver_info, mock__insert_vmedia, mock__eject_vmedia,
|
mock__parse_driver_info, mock__insert_vmedia, mock__eject_vmedia,
|
||||||
mock__has_vmedia_device, mock_prepare_deploy_iso,
|
mock__has_vmedia_device, mock_prepare_deploy_iso,
|
||||||
mock_prepare_floppy_image, mock_node_set_boot_device):
|
mock_prepare_floppy_image, mock_node_set_boot_device):
|
||||||
|
system = mock_system.return_value
|
||||||
managers = mock_system.return_value.managers
|
managers = mock_system.return_value.managers
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
@ -658,7 +658,8 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
|
|
||||||
mock__has_vmedia_device.assert_called_once_with(
|
mock__has_vmedia_device.assert_called_once_with(
|
||||||
managers,
|
managers,
|
||||||
[sushy.VIRTUAL_MEDIA_USBSTICK, sushy.VIRTUAL_MEDIA_FLOPPY])
|
[sushy.VIRTUAL_MEDIA_USBSTICK, sushy.VIRTUAL_MEDIA_FLOPPY],
|
||||||
|
system=system)
|
||||||
|
|
||||||
eject_calls = [
|
eject_calls = [
|
||||||
mock.call(task, managers, dev)
|
mock.call(task, managers, dev)
|
||||||
@ -708,7 +709,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
mock__parse_driver_info, mock__insert_vmedia, mock__eject_vmedia,
|
mock__parse_driver_info, mock__insert_vmedia, mock__eject_vmedia,
|
||||||
mock__has_vmedia_device, mock_prepare_deploy_iso,
|
mock__has_vmedia_device, mock_prepare_deploy_iso,
|
||||||
mock_prepare_floppy_image, mock_node_set_boot_device):
|
mock_prepare_floppy_image, mock_node_set_boot_device):
|
||||||
|
system = mock_system.return_value
|
||||||
managers = mock_system.return_value.managers
|
managers = mock_system.return_value.managers
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
@ -731,7 +732,8 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
|
|
||||||
mock__has_vmedia_device.assert_called_once_with(
|
mock__has_vmedia_device.assert_called_once_with(
|
||||||
managers,
|
managers,
|
||||||
[sushy.VIRTUAL_MEDIA_USBSTICK, sushy.VIRTUAL_MEDIA_FLOPPY])
|
[sushy.VIRTUAL_MEDIA_USBSTICK, sushy.VIRTUAL_MEDIA_FLOPPY],
|
||||||
|
system=system)
|
||||||
|
|
||||||
eject_calls = [
|
eject_calls = [
|
||||||
mock.call(task, managers, dev)
|
mock.call(task, managers, dev)
|
||||||
@ -834,7 +836,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
mock__parse_driver_info, mock__insert_vmedia, mock__eject_vmedia,
|
mock__parse_driver_info, mock__insert_vmedia, mock__eject_vmedia,
|
||||||
mock__has_vmedia_device,
|
mock__has_vmedia_device,
|
||||||
mock_prepare_deploy_iso, mock_node_set_boot_device):
|
mock_prepare_deploy_iso, mock_node_set_boot_device):
|
||||||
|
system = mock_system.return_value
|
||||||
managers = mock_system.return_value.managers
|
managers = mock_system.return_value.managers
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
@ -844,7 +846,8 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
task.driver.boot.prepare_ramdisk(task, {})
|
task.driver.boot.prepare_ramdisk(task, {})
|
||||||
|
|
||||||
mock__has_vmedia_device.assert_called_once_with(
|
mock__has_vmedia_device.assert_called_once_with(
|
||||||
managers, sushy.VIRTUAL_MEDIA_CD, inserted=True)
|
managers, sushy.VIRTUAL_MEDIA_CD, inserted=True,
|
||||||
|
system=system)
|
||||||
|
|
||||||
mock_node_power_action.assert_not_called()
|
mock_node_power_action.assert_not_called()
|
||||||
mock__eject_vmedia.assert_not_called()
|
mock__eject_vmedia.assert_not_called()
|
||||||
@ -870,7 +873,7 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
mock__parse_driver_info, mock__insert_vmedia, mock__eject_vmedia,
|
mock__parse_driver_info, mock__insert_vmedia, mock__eject_vmedia,
|
||||||
mock__has_vmedia_device,
|
mock__has_vmedia_device,
|
||||||
mock_prepare_deploy_iso, mock_node_set_boot_device):
|
mock_prepare_deploy_iso, mock_node_set_boot_device):
|
||||||
|
system = mock_system.return_value
|
||||||
managers = mock_system.return_value.managers
|
managers = mock_system.return_value.managers
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
@ -883,7 +886,8 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
task.driver.boot.prepare_ramdisk(task, {})
|
task.driver.boot.prepare_ramdisk(task, {})
|
||||||
|
|
||||||
mock__has_vmedia_device.assert_called_once_with(
|
mock__has_vmedia_device.assert_called_once_with(
|
||||||
managers, sushy.VIRTUAL_MEDIA_CD, inserted=True)
|
managers, sushy.VIRTUAL_MEDIA_CD, inserted=True,
|
||||||
|
system=system)
|
||||||
|
|
||||||
mock_node_power_action.assert_called_once_with(
|
mock_node_power_action.assert_called_once_with(
|
||||||
task, states.POWER_OFF)
|
task, states.POWER_OFF)
|
||||||
@ -1338,10 +1342,13 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
mock__eject_vmedia.assert_has_calls(eject_calls)
|
mock__eject_vmedia.assert_has_calls(eject_calls)
|
||||||
mock_secure_boot.assert_called_once_with(task)
|
mock_secure_boot.assert_called_once_with(task)
|
||||||
|
|
||||||
def test__insert_vmedia_anew(self):
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
|
||||||
|
def test__insert_vmedia_anew(self, mock_sys, mock_vmd_sys):
|
||||||
|
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=True) as task:
|
shared=True) as task:
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
mock_vmedia_cd = mock.MagicMock(
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
inserted=False,
|
inserted=False,
|
||||||
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
@ -1362,8 +1369,10 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
|
|
||||||
self.assertFalse(mock_vmedia_floppy.insert_media.call_count)
|
self.assertFalse(mock_vmedia_floppy.insert_media.call_count)
|
||||||
|
|
||||||
def test__insert_vmedia_anew_dvd(self):
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
|
||||||
|
def test__insert_vmedia_anew_dvd(self, mock_sys, mock_vmd_sys):
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=True) as task:
|
shared=True) as task:
|
||||||
mock_vmedia_dvd = mock.MagicMock(
|
mock_vmedia_dvd = mock.MagicMock(
|
||||||
@ -1382,8 +1391,10 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
'img-url', inserted=True, write_protected=True)
|
'img-url', inserted=True, write_protected=True)
|
||||||
|
|
||||||
@mock.patch('time.sleep', lambda *args, **kwargs: None)
|
@mock.patch('time.sleep', lambda *args, **kwargs: None)
|
||||||
def test__insert_vmedia_anew_dvd_retry(self):
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
|
||||||
|
def test__insert_vmedia_anew_dvd_retry(self, mock_sys, mock_vmd_sys):
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=True) as task:
|
shared=True) as task:
|
||||||
mock_vmedia_dvd_1 = mock.MagicMock(
|
mock_vmedia_dvd_1 = mock.MagicMock(
|
||||||
@ -1409,10 +1420,12 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
|
|
||||||
self.assertEqual(mock_vmedia_dvd_2.insert_media.call_count, 1)
|
self.assertEqual(mock_vmedia_dvd_2.insert_media.call_count, 1)
|
||||||
|
|
||||||
def test__insert_vmedia_already_inserted(self):
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
|
||||||
|
def test__insert_vmedia_already_inserted(self, mock_sys, mock_vmd_sys):
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=True) as task:
|
shared=True) as task:
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
mock_vmedia_cd = mock.MagicMock(
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
inserted=True,
|
inserted=True,
|
||||||
image='img-url',
|
image='img-url',
|
||||||
@ -1428,10 +1441,12 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
self.assertFalse(mock_vmedia_cd.insert_media.call_count)
|
self.assertFalse(mock_vmedia_cd.insert_media.call_count)
|
||||||
|
|
||||||
@mock.patch('time.sleep', lambda *args, **kwargs: None)
|
@mock.patch('time.sleep', lambda *args, **kwargs: None)
|
||||||
def test__insert_vmedia_while_ejecting(self):
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
|
||||||
|
def test__insert_vmedia_while_ejecting(self, mock_sys, mock_vmd_sys):
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=True) as task:
|
shared=True) as task:
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
mock_vmedia_cd = mock.MagicMock(
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
inserted=False,
|
inserted=False,
|
||||||
image='img-url',
|
image='img-url',
|
||||||
@ -1453,8 +1468,10 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
self.assertEqual(mock_vmedia_cd.insert_media.call_count, 2)
|
self.assertEqual(mock_vmedia_cd.insert_media.call_count, 2)
|
||||||
|
|
||||||
@mock.patch('time.sleep', lambda *args, **kwargs: None)
|
@mock.patch('time.sleep', lambda *args, **kwargs: None)
|
||||||
def test__insert_vmedia_bad_device(self):
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
|
||||||
|
def test__insert_vmedia_bad_device(self, mock_sys, mock_vmd_sys):
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=True) as task:
|
shared=True) as task:
|
||||||
mock_vmedia_floppy = mock.MagicMock(
|
mock_vmedia_floppy = mock.MagicMock(
|
||||||
@ -1472,10 +1489,11 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
|
|
||||||
@mock.patch.object(image_utils, 'cleanup_disk_image', autospec=True)
|
@mock.patch.object(image_utils, 'cleanup_disk_image', autospec=True)
|
||||||
@mock.patch.object(image_utils, 'cleanup_iso_image', autospec=True)
|
@mock.patch.object(image_utils, 'cleanup_iso_image', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||||
def test_eject_vmedia_everything(self, mock_redfish_utils,
|
def test_eject_vmedia_everything(self, mock_redfish_utils, mock_vmd_sys,
|
||||||
mock_cleanup_iso, mock_cleanup_disk):
|
mock_cleanup_iso, mock_cleanup_disk):
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=True) as task:
|
shared=True) as task:
|
||||||
mock_vmedia_cd = mock.MagicMock(
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
@ -1507,10 +1525,11 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
|
|
||||||
@mock.patch.object(image_utils, 'cleanup_disk_image', autospec=True)
|
@mock.patch.object(image_utils, 'cleanup_disk_image', autospec=True)
|
||||||
@mock.patch.object(image_utils, 'cleanup_iso_image', autospec=True)
|
@mock.patch.object(image_utils, 'cleanup_iso_image', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||||
def test_eject_vmedia_specific(self, mock_redfish_utils,
|
def test_eject_vmedia_specific(self, mock_redfish_utils, mock_vmd_sys,
|
||||||
mock_cleanup_iso, mock_cleanup_disk):
|
mock_cleanup_iso, mock_cleanup_disk):
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=True) as task:
|
shared=True) as task:
|
||||||
mock_vmedia_cd = mock.MagicMock(
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
@ -1538,14 +1557,16 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
@mock.patch.object(image_utils, 'cleanup_disk_image', autospec=True)
|
@mock.patch.object(image_utils, 'cleanup_disk_image', autospec=True)
|
||||||
@mock.patch.object(image_utils, 'cleanup_iso_image', autospec=True)
|
@mock.patch.object(image_utils, 'cleanup_iso_image', autospec=True)
|
||||||
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
@mock.patch.object(redfish_boot.LOG, 'debug', autospec=True)
|
@mock.patch.object(redfish_boot.LOG, 'debug', autospec=True)
|
||||||
@mock.patch.object(redfish_boot.LOG, 'info', autospec=True)
|
@mock.patch.object(redfish_boot.LOG, 'info', autospec=True)
|
||||||
def test_eject_vmedia_with_dvd_cisco_ucs(self, mock_log_info,
|
def test_eject_vmedia_with_dvd_cisco_ucs(self, mock_log_info,
|
||||||
mock_log_debug,
|
mock_log_debug,
|
||||||
|
mock_vmd_sys,
|
||||||
mock_redfish_utils,
|
mock_redfish_utils,
|
||||||
mock_cleanup_iso,
|
mock_cleanup_iso,
|
||||||
mock_cleanup_disk):
|
mock_cleanup_disk):
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=True) as task:
|
shared=True) as task:
|
||||||
mock_vmedia_dvd_1 = mock.MagicMock(
|
mock_vmedia_dvd_1 = mock.MagicMock(
|
||||||
@ -1573,11 +1594,13 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
mock_cleanup_iso.assert_called_once_with(task)
|
mock_cleanup_iso.assert_called_once_with(task)
|
||||||
mock_cleanup_disk.assert_not_called()
|
mock_cleanup_disk.assert_not_called()
|
||||||
|
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||||
def test_eject_vmedia_not_inserted(self, mock_redfish_utils):
|
def test_eject_vmedia_not_inserted(self, mock_redfish_utils, mock_vmd_sys):
|
||||||
|
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=True) as task:
|
shared=True) as task:
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
mock_vmedia_cd = mock.MagicMock(
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
inserted=False,
|
inserted=False,
|
||||||
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
@ -1598,11 +1621,13 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
self.assertFalse(mock_vmedia_cd.eject_media.call_count)
|
self.assertFalse(mock_vmedia_cd.eject_media.call_count)
|
||||||
self.assertFalse(mock_vmedia_floppy.eject_media.call_count)
|
self.assertFalse(mock_vmedia_floppy.eject_media.call_count)
|
||||||
|
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||||
def test_eject_vmedia_unknown(self, mock_redfish_utils):
|
def test_eject_vmedia_unknown(self, mock_redfish_utils, mock_vmd_sys):
|
||||||
|
|
||||||
with task_manager.acquire(self.context, self.node.uuid,
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
shared=True) as task:
|
shared=True) as task:
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
mock_vmedia_cd = mock.MagicMock(
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
inserted=False,
|
inserted=False,
|
||||||
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
@ -1619,7 +1644,9 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
|
|
||||||
self.assertFalse(mock_vmedia_cd.eject_media.call_count)
|
self.assertFalse(mock_vmedia_cd.eject_media.call_count)
|
||||||
|
|
||||||
def test__has_vmedia_device(self):
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
def test__has_vmedia_device(self, mock_vmd_sys):
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
mock_vmedia_cd = mock.MagicMock(
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
inserted=False,
|
inserted=False,
|
||||||
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
@ -1645,7 +1672,9 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
|
|||||||
redfish_boot._has_vmedia_device(
|
redfish_boot._has_vmedia_device(
|
||||||
[mock_manager], sushy.VIRTUAL_MEDIA_USBSTICK))
|
[mock_manager], sushy.VIRTUAL_MEDIA_USBSTICK))
|
||||||
|
|
||||||
def test__has_vmedia_device_inserted(self):
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
def test__has_vmedia_device_inserted(self, mock_vmd_sys):
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
mock_vmedia_cd = mock.MagicMock(
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
inserted=False,
|
inserted=False,
|
||||||
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
@ -2512,3 +2541,426 @@ class RedfishHTTPBootTestCase(db_base.DbTestCase):
|
|||||||
|
|
||||||
mock_secure_boot.assert_called_once_with(task)
|
mock_secure_boot.assert_called_once_with(task)
|
||||||
mock_cleanup_disk_image.assert_not_called()
|
mock_cleanup_disk_image.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch('oslo_utils.eventletutils.EventletEvent.wait',
|
||||||
|
lambda *args, **kwargs: None)
|
||||||
|
class RedfishVirtualMediaBootViaSystemTestCase(db_base.DbTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(RedfishVirtualMediaBootViaSystemTestCase, self).setUp()
|
||||||
|
self.config(enabled_hardware_types=['redfish'],
|
||||||
|
enabled_power_interfaces=['redfish'],
|
||||||
|
enabled_boot_interfaces=['redfish-virtual-media'],
|
||||||
|
enabled_management_interfaces=['redfish'],
|
||||||
|
enabled_inspect_interfaces=['redfish'],
|
||||||
|
enabled_bios_interfaces=['redfish'])
|
||||||
|
self.node = obj_utils.create_test_node(
|
||||||
|
self.context, driver='redfish', driver_info=INFO_DICT)
|
||||||
|
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
|
||||||
|
def test__insert_vmedia_anew(self, mock_system, mock_vmd_sys):
|
||||||
|
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
mock_vmd_sys.return_value = True
|
||||||
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
|
inserted=False,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
|
mock_vmedia_floppy = mock.MagicMock(
|
||||||
|
inserted=False,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_FLOPPY])
|
||||||
|
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
|
||||||
|
mock_system.return_value.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_cd, mock_vmedia_floppy]
|
||||||
|
|
||||||
|
redfish_boot._insert_vmedia(
|
||||||
|
task, [mock_manager], 'img-url', sushy.VIRTUAL_MEDIA_CD)
|
||||||
|
|
||||||
|
mock_vmedia_cd.insert_media.assert_called_once_with(
|
||||||
|
'img-url', inserted=True, write_protected=True)
|
||||||
|
|
||||||
|
self.assertFalse(mock_vmedia_floppy.insert_media.call_count)
|
||||||
|
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
|
||||||
|
def test__insert_vmedia_anew_dvd(self, mock_system, mock_vmd_sys):
|
||||||
|
mock_vmd_sys.return_value = True
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
mock_vmedia_dvd = mock.MagicMock(
|
||||||
|
inserted=False,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_DVD])
|
||||||
|
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
|
||||||
|
mock_system.return_value.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_dvd]
|
||||||
|
|
||||||
|
redfish_boot._insert_vmedia(
|
||||||
|
task, [mock_manager], 'img-url', sushy.VIRTUAL_MEDIA_CD)
|
||||||
|
|
||||||
|
mock_vmedia_dvd.insert_media.assert_called_once_with(
|
||||||
|
'img-url', inserted=True, write_protected=True)
|
||||||
|
|
||||||
|
@mock.patch('time.sleep', lambda *args, **kwargs: None)
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
|
||||||
|
def test__insert_vmedia_anew_dvd_retry(self, mock_system, mock_vmd_sys):
|
||||||
|
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
mock_vmd_sys.return_value = True
|
||||||
|
mock_vmedia_dvd_1 = mock.MagicMock(
|
||||||
|
inserted=False,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_DVD])
|
||||||
|
|
||||||
|
mock_vmedia_dvd_2 = mock.MagicMock(
|
||||||
|
inserted=False,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_DVD])
|
||||||
|
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
|
||||||
|
def clear_and_raise(*args, **kwargs):
|
||||||
|
mock_vmedia_dvd_1.insert_media.side_effect = None
|
||||||
|
raise sushy.exceptions.BadRequestError(
|
||||||
|
"POST", 'img-url', mock.MagicMock())
|
||||||
|
mock_vmedia_dvd_1.insert_media.side_effect = clear_and_raise
|
||||||
|
mock_system.return_value.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_dvd_1, mock_vmedia_dvd_2]
|
||||||
|
|
||||||
|
redfish_boot._insert_vmedia(
|
||||||
|
task, [mock_manager], 'img-url', sushy.VIRTUAL_MEDIA_CD)
|
||||||
|
|
||||||
|
self.assertEqual(mock_vmedia_dvd_2.insert_media.call_count, 1)
|
||||||
|
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
|
||||||
|
def test__insert_vmedia_already_inserted(self, mock_sys, mock_vmd_sys):
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
mock_vmd_sys.return_value = False
|
||||||
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
|
inserted=True,
|
||||||
|
image='img-url',
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
|
||||||
|
mock_manager.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_cd]
|
||||||
|
|
||||||
|
redfish_boot._insert_vmedia(
|
||||||
|
task, [mock_manager], 'img-url', sushy.VIRTUAL_MEDIA_CD)
|
||||||
|
|
||||||
|
self.assertFalse(mock_vmedia_cd.insert_media.call_count)
|
||||||
|
|
||||||
|
@mock.patch('time.sleep', lambda *args, **kwargs: None)
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
|
||||||
|
def test__insert_vmedia_while_ejecting(self, mock_system, mock_vmd_sys):
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
mock_vmd_sys.return_value = True
|
||||||
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
|
inserted=False,
|
||||||
|
image='img-url',
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_CD],
|
||||||
|
)
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
|
||||||
|
def clear_and_raise(*args, **kwargs):
|
||||||
|
mock_vmedia_cd.insert_media.side_effect = None
|
||||||
|
raise sushy.exceptions.ServerSideError(
|
||||||
|
"POST", 'img-url', mock.MagicMock())
|
||||||
|
mock_vmedia_cd.insert_media.side_effect = clear_and_raise
|
||||||
|
mock_system.return_value.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_cd]
|
||||||
|
|
||||||
|
redfish_boot._insert_vmedia(
|
||||||
|
task, [mock_manager], 'img-url', sushy.VIRTUAL_MEDIA_CD)
|
||||||
|
|
||||||
|
self.assertEqual(mock_vmedia_cd.insert_media.call_count, 2)
|
||||||
|
|
||||||
|
@mock.patch('time.sleep', lambda *args, **kwargs: None)
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
|
||||||
|
def test__insert_vmedia_bad_device(self, mock_sys, mock_vmd_sys):
|
||||||
|
mock_vmd_sys.return_value = True
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
mock_vmedia_floppy = mock.MagicMock(
|
||||||
|
inserted=False,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_FLOPPY])
|
||||||
|
mock_system = mock.MagicMock()
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
|
||||||
|
mock_system.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_floppy]
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exception.InvalidParameterValue,
|
||||||
|
redfish_boot._insert_vmedia,
|
||||||
|
task, [mock_manager], 'img-url', sushy.VIRTUAL_MEDIA_CD)
|
||||||
|
|
||||||
|
@mock.patch.object(image_utils, 'cleanup_disk_image', autospec=True)
|
||||||
|
@mock.patch.object(image_utils, 'cleanup_iso_image', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||||
|
def test_eject_vmedia_everything(self, mock_redfish_utils, mock_vmd_sys,
|
||||||
|
mock_cleanup_iso, mock_cleanup_disk):
|
||||||
|
mock_vmd_sys.return_value = True
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
|
inserted=True,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
|
mock_vmedia_floppy = mock.MagicMock(
|
||||||
|
inserted=True,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_FLOPPY])
|
||||||
|
mock_vmedia_dvd = mock.MagicMock(
|
||||||
|
inserted=True,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_DVD])
|
||||||
|
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
mock_system = mock.MagicMock()
|
||||||
|
|
||||||
|
mock_redfish_utils.get_system.return_value = mock_system
|
||||||
|
mock_system.managers = [
|
||||||
|
mock_manager]
|
||||||
|
|
||||||
|
mock_system.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_cd, mock_vmedia_floppy, mock_vmedia_dvd]
|
||||||
|
|
||||||
|
redfish_boot.eject_vmedia(task)
|
||||||
|
|
||||||
|
mock_vmedia_cd.eject_media.assert_called_once_with()
|
||||||
|
mock_vmedia_floppy.eject_media.assert_called_once_with()
|
||||||
|
mock_vmedia_dvd.eject_media.assert_called_once_with()
|
||||||
|
mock_cleanup_iso.assert_called_once_with(task)
|
||||||
|
mock_cleanup_disk.assert_called_once_with(task,
|
||||||
|
prefix='configdrive')
|
||||||
|
|
||||||
|
@mock.patch.object(image_utils, 'cleanup_disk_image', autospec=True)
|
||||||
|
@mock.patch.object(image_utils, 'cleanup_iso_image', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_manager', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||||
|
def test_eject_vmedia_from_all_resources(self, mock_redfish_utils,
|
||||||
|
mock_vmd_sys, mock_vmd_mg,
|
||||||
|
mock_cleanup_iso,
|
||||||
|
mock_cleanup_disk):
|
||||||
|
mock_vmd_sys.return_value = True
|
||||||
|
mock_vmd_mg.return_value = True
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
|
inserted=True,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
|
mock_vmedia_floppy = mock.MagicMock(
|
||||||
|
inserted=True,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_FLOPPY])
|
||||||
|
mock_vmedia_dvd = mock.MagicMock(
|
||||||
|
inserted=True,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_DVD])
|
||||||
|
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
mock_system = mock.MagicMock()
|
||||||
|
|
||||||
|
mock_redfish_utils.get_system.return_value = mock_system
|
||||||
|
mock_system.managers = [
|
||||||
|
mock_manager]
|
||||||
|
|
||||||
|
mock_system.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_floppy, mock_vmedia_dvd]
|
||||||
|
mock_manager.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_cd]
|
||||||
|
|
||||||
|
redfish_boot.eject_vmedia(task)
|
||||||
|
|
||||||
|
mock_vmedia_cd.eject_media.assert_called_once_with()
|
||||||
|
mock_vmedia_floppy.eject_media.assert_called_once_with()
|
||||||
|
mock_vmedia_dvd.eject_media.assert_called_once_with()
|
||||||
|
mock_cleanup_iso.assert_called_once_with(task)
|
||||||
|
mock_cleanup_disk.assert_called_once_with(task,
|
||||||
|
prefix='configdrive')
|
||||||
|
|
||||||
|
@mock.patch.object(image_utils, 'cleanup_disk_image', autospec=True)
|
||||||
|
@mock.patch.object(image_utils, 'cleanup_iso_image', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||||
|
def test_eject_vmedia_specific(self, mock_redfish_utils, mock_vmd_sys,
|
||||||
|
mock_cleanup_iso, mock_cleanup_disk):
|
||||||
|
mock_vmd_sys.return_value = True
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
|
inserted=True,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
|
mock_vmedia_floppy = mock.MagicMock(
|
||||||
|
inserted=True,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_FLOPPY])
|
||||||
|
|
||||||
|
mock_system = mock.MagicMock()
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
|
||||||
|
mock_redfish_utils.get_system.return_value = mock_system
|
||||||
|
mock_system.managers = [
|
||||||
|
mock_manager]
|
||||||
|
mock_system.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_cd, mock_vmedia_floppy]
|
||||||
|
|
||||||
|
redfish_boot.eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
|
||||||
|
|
||||||
|
mock_vmedia_cd.eject_media.assert_called_once_with()
|
||||||
|
self.assertFalse(mock_vmedia_floppy.eject_media.call_count)
|
||||||
|
mock_cleanup_iso.assert_called_once_with(task)
|
||||||
|
mock_cleanup_disk.assert_not_called()
|
||||||
|
|
||||||
|
@mock.patch.object(image_utils, 'cleanup_disk_image', autospec=True)
|
||||||
|
@mock.patch.object(image_utils, 'cleanup_iso_image', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot.LOG, 'debug', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot.LOG, 'info', autospec=True)
|
||||||
|
def test_eject_vmedia_with_dvd_cisco_ucs(self, mock_log_info,
|
||||||
|
mock_log_debug,
|
||||||
|
mock_vmd_sys,
|
||||||
|
mock_redfish_utils,
|
||||||
|
mock_cleanup_iso,
|
||||||
|
mock_cleanup_disk):
|
||||||
|
mock_vmd_sys.return_value = True
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
mock_vmedia_dvd_1 = mock.MagicMock(
|
||||||
|
inserted=True,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_DVD])
|
||||||
|
mock_vmedia_dvd_2 = mock.MagicMock(
|
||||||
|
inserted=True,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_DVD])
|
||||||
|
|
||||||
|
mock_system = mock.MagicMock()
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
|
||||||
|
mock_redfish_utils.get_system.return_value = mock_system
|
||||||
|
mock_system.managers = [
|
||||||
|
mock_manager]
|
||||||
|
mock_system.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_dvd_1, mock_vmedia_dvd_2]
|
||||||
|
|
||||||
|
redfish_boot.eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD)
|
||||||
|
|
||||||
|
mock_vmedia_dvd_1.eject_media.assert_called_once_with()
|
||||||
|
mock_vmedia_dvd_2.eject_media.assert_called_once_with()
|
||||||
|
|
||||||
|
self.assertEqual(mock_log_info.call_count, 2)
|
||||||
|
self.assertEqual(mock_log_debug.call_count, 3)
|
||||||
|
mock_cleanup_iso.assert_called_once_with(task)
|
||||||
|
mock_cleanup_disk.assert_not_called()
|
||||||
|
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||||
|
def test_eject_vmedia_not_inserted(self, mock_redfish_utils, mock_vmd_sys):
|
||||||
|
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
mock_vmd_sys.return_value = True
|
||||||
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
|
inserted=False,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
|
mock_vmedia_floppy = mock.MagicMock(
|
||||||
|
inserted=False,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_FLOPPY])
|
||||||
|
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
mock_system = mock.MagicMock()
|
||||||
|
|
||||||
|
mock_system.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_cd, mock_vmedia_floppy]
|
||||||
|
|
||||||
|
mock_redfish_utils.get_system.return_value.managers = [
|
||||||
|
mock_manager]
|
||||||
|
|
||||||
|
redfish_boot.eject_vmedia(task)
|
||||||
|
|
||||||
|
self.assertFalse(mock_vmedia_cd.eject_media.call_count)
|
||||||
|
self.assertFalse(mock_vmedia_floppy.eject_media.call_count)
|
||||||
|
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
@mock.patch.object(redfish_boot, 'redfish_utils', autospec=True)
|
||||||
|
def test_eject_vmedia_unknown(self, mock_redfish_utils, mock_vmd_sys):
|
||||||
|
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
mock_vmd_sys.return_value = True
|
||||||
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
|
inserted=False,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
|
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
mock_system = mock.MagicMock()
|
||||||
|
|
||||||
|
mock_system.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_cd]
|
||||||
|
|
||||||
|
mock_redfish_utils.get_system.return_value.managers = [
|
||||||
|
mock_manager]
|
||||||
|
|
||||||
|
redfish_boot.eject_vmedia(task)
|
||||||
|
|
||||||
|
self.assertFalse(mock_vmedia_cd.eject_media.call_count)
|
||||||
|
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
def test__has_vmedia_device(self, mock_vmd_sys):
|
||||||
|
mock_vmd_sys.return_value = True
|
||||||
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
|
inserted=False,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
|
mock_vmedia_floppy = mock.MagicMock(
|
||||||
|
inserted=False,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_FLOPPY])
|
||||||
|
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
|
||||||
|
mock_system = mock.MagicMock()
|
||||||
|
mock_system.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_cd, mock_vmedia_floppy]
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
sushy.VIRTUAL_MEDIA_CD,
|
||||||
|
redfish_boot._has_vmedia_device(
|
||||||
|
[mock_manager], sushy.VIRTUAL_MEDIA_CD,
|
||||||
|
system=mock_system))
|
||||||
|
|
||||||
|
self.assertFalse(
|
||||||
|
redfish_boot._has_vmedia_device(
|
||||||
|
[mock_manager], sushy.VIRTUAL_MEDIA_CD,
|
||||||
|
inserted=True, system=mock_system))
|
||||||
|
|
||||||
|
self.assertFalse(
|
||||||
|
redfish_boot._has_vmedia_device(
|
||||||
|
[mock_manager], sushy.VIRTUAL_MEDIA_USBSTICK,
|
||||||
|
system=mock_system))
|
||||||
|
|
||||||
|
@mock.patch.object(redfish_boot, '_has_vmedia_via_systems', autospec=True)
|
||||||
|
def test__has_vmedia_device_inserted(self, mock_vmd_sys):
|
||||||
|
mock_vmd_sys.return_value = True
|
||||||
|
mock_vmedia_cd = mock.MagicMock(
|
||||||
|
inserted=False,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_CD])
|
||||||
|
mock_vmedia_floppy = mock.MagicMock(
|
||||||
|
inserted=True,
|
||||||
|
media_types=[sushy.VIRTUAL_MEDIA_FLOPPY])
|
||||||
|
|
||||||
|
mock_manager = mock.MagicMock()
|
||||||
|
mock_system = mock.MagicMock()
|
||||||
|
mock_system.virtual_media.get_members.return_value = [
|
||||||
|
mock_vmedia_cd, mock_vmedia_floppy]
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
sushy.VIRTUAL_MEDIA_FLOPPY,
|
||||||
|
redfish_boot._has_vmedia_device(
|
||||||
|
[mock_manager], sushy.VIRTUAL_MEDIA_FLOPPY,
|
||||||
|
inserted=True, system=mock_system))
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
Fixes Redfish virtual media boot on BMCs that only expose the VirtualMedia
|
||||||
|
resource on Systems instead of Managers. For more informations, you can see
|
||||||
|
`bug 2039458 <https://bugs.launchpad.net/sushy/+bug/2039458>`_.
|
@ -46,6 +46,6 @@ psutil>=3.2.2 # BSD
|
|||||||
futurist>=1.2.0 # Apache-2.0
|
futurist>=1.2.0 # Apache-2.0
|
||||||
tooz>=2.7.0 # Apache-2.0
|
tooz>=2.7.0 # Apache-2.0
|
||||||
openstacksdk>=0.48.0 # Apache-2.0
|
openstacksdk>=0.48.0 # Apache-2.0
|
||||||
sushy>=4.7.0
|
sushy>=4.8.0
|
||||||
construct>=2.9.39 # MIT
|
construct>=2.9.39 # MIT
|
||||||
netaddr>=0.9.0 # BSD
|
netaddr>=0.9.0 # BSD
|
||||||
|
Loading…
Reference in New Issue
Block a user