From 689accce86e647fbf6a452eeedb5e6253f50cab4 Mon Sep 17 00:00:00 2001 From: ankit Date: Fri, 15 Feb 2019 08:06:30 +0000 Subject: [PATCH] Adding changes to support sushy virtual media This commit adds support to use sushy virtual media and if it fails then fall back to protiantutils virtual media. Change-Id: Iff07050e6e1929fb1b6a29379d208e22f82ea641 --- proliantutils/redfish/redfish.py | 8 ++--- .../resources/manager/virtual_media.py | 35 ++++++++++--------- .../resources/manager/test_virtual_media.py | 33 +++++++++++++---- proliantutils/tests/redfish/test_redfish.py | 26 +++++++------- requirements.txt | 2 +- 5 files changed, 62 insertions(+), 42 deletions(-) diff --git a/proliantutils/redfish/redfish.py b/proliantutils/redfish/redfish.py index b92c37fb..8a7346b0 100644 --- a/proliantutils/redfish/redfish.py +++ b/proliantutils/redfish/redfish.py @@ -393,8 +393,8 @@ class RedfishOperations(operations.IloOperations): LOG.debug(self._("Ejecting the media image '%(url)s' from the " "device %(device)s.") % - {'url': vmedia_device.image_url, 'device': device}) - vmedia_device.eject_vmedia() + {'url': vmedia_device.image, 'device': device}) + vmedia_device.eject_media() except sushy.exceptions.SushyError as e: msg = (self._("The Redfish controller failed to eject the virtual" " media device '%(device)s'. Error %(error)s.") % @@ -417,12 +417,12 @@ class RedfishOperations(operations.IloOperations): manager.virtual_media.get_member_device( VIRTUAL_MEDIA_MAP[device])) if vmedia_device.inserted: - vmedia_device.eject_vmedia() + vmedia_device.eject_media() LOG.debug(self._("Inserting the image url '%(url)s' to the " "device %(device)s.") % {'url': url, 'device': device}) - vmedia_device.insert_vmedia(url) + vmedia_device.insert_media(url) except sushy.exceptions.SushyError as e: msg = (self._("The Redfish controller failed to insert the media " "url %(url)s in the virtual media device " diff --git a/proliantutils/redfish/resources/manager/virtual_media.py b/proliantutils/redfish/resources/manager/virtual_media.py index b0edd1c2..721ca159 100644 --- a/proliantutils/redfish/resources/manager/virtual_media.py +++ b/proliantutils/redfish/resources/manager/virtual_media.py @@ -14,8 +14,10 @@ __author__ = 'HPE' +from sushy import exceptions as sushy_exceptions from sushy.resources import base from sushy.resources import common +from sushy.resources.manager import virtual_media from proliantutils import exception from proliantutils import log @@ -40,23 +42,17 @@ class ActionsField(base.CompositeField): '#HpeiLOVirtualMedia.EjectVirtualMedia') -class VirtualMedia(base.ResourceBase): +class VirtualMedia(virtual_media.VirtualMedia): media_types = base.Field('MediaTypes', adapter=_get_media, required=True) """A list of allowed media types for the instance.""" - inserted = base.Field('Inserted', required=True) - """A boolean value which represents vmedia is inserted or not.""" - - image_url = base.Field('Image') - """A string which represents the virtual media image url.""" - - _actions = ActionsField(['Oem', 'Hpe', 'Actions'], required=True) + _hpe_actions = ActionsField(['Oem', 'Hpe', 'Actions'], required=True) def _get_action_element(self, action_type): """Helper method to return the action object.""" - action = eval("self._actions." + action_type + "_vmedia") + action = eval("self._hpe_actions." + action_type + "_vmedia") if not action: if action_type == "insert": @@ -70,24 +66,29 @@ class VirtualMedia(base.ResourceBase): return action - def insert_vmedia(self, url): + def insert_media(self, url): """Inserts Virtual Media to the device :param url: URL to image. :raises: SushyError, on an error from iLO. """ - target_uri = self._get_action_element('insert').target_uri - data = {'Image': url} - self._conn.post(target_uri, data=data) + try: + super(VirtualMedia, self).insert_media(url, write_protected=True) + except sushy_exceptions.SushyError: + target_uri = self._get_action_element('insert').target_uri + data = {'Image': url} + self._conn.post(target_uri, data=data) - def eject_vmedia(self): + def eject_media(self): """Ejects Virtual Media. :raises: SushyError, on an error from iLO. """ - target_uri = self._get_action_element('eject').target_uri - data = {} - self._conn.post(target_uri, data=data) + try: + super(VirtualMedia, self).eject_media() + except sushy_exceptions.SushyError: + target_uri = self._get_action_element('eject').target_uri + self._conn.post(target_uri, data={}) def set_vm_status(self, boot_on_next_reset): """Set the Virtual Media drive status. diff --git a/proliantutils/tests/redfish/resources/manager/test_virtual_media.py b/proliantutils/tests/redfish/resources/manager/test_virtual_media.py index e1310de9..c967c799 100644 --- a/proliantutils/tests/redfish/resources/manager/test_virtual_media.py +++ b/proliantutils/tests/redfish/resources/manager/test_virtual_media.py @@ -17,9 +17,11 @@ __author__ = 'HPE' import json import mock -from sushy import exceptions import testtools +from sushy import exceptions +from sushy.resources.manager import virtual_media as sushy_virt_media + from proliantutils import exception from proliantutils.redfish.resources.manager import constants from proliantutils.redfish.resources.manager import virtual_media @@ -85,7 +87,7 @@ class VirtualMediaTestCase(testtools.TestCase): value.target_uri) def test__get_action_element_missing_insert_action(self): - self.vmedia_inst._actions.insert_vmedia = None + self.vmedia_inst._hpe_actions.insert_vmedia = None self.assertRaisesRegex( exception.MissingAttributeError, 'attribute #HpeiLOVirtualMedia.InsertVirtualMedia', @@ -98,22 +100,39 @@ class VirtualMediaTestCase(testtools.TestCase): value.target_uri) def test__get__action_element_missing_eject_action(self): - self.vmedia_inst._actions.eject_vmedia = None + self.vmedia_inst._hpe_actions.eject_vmedia = None self.assertRaisesRegex( exception.MissingAttributeError, 'attribute #HpeiLOVirtualMedia.EjectVirtualMedia', self.vmedia_inst._get_action_element, 'eject') - def test_insert_vmedia(self): + @mock.patch.object(sushy_virt_media.VirtualMedia, 'insert_media') + def test_insert_media_sushy(self, insert_mock): + insert_mock.return_value = None url = "http://1.2.3.4:5678/xyz.iso" - self.vmedia_inst.insert_vmedia(url) + self.vmedia_inst.insert_media(url) + insert_mock.assert_called_once_with(url, write_protected=True) + + @mock.patch.object(sushy_virt_media.VirtualMedia, 'insert_media') + def test_insert_media(self, insert_mock): + url = "http://1.2.3.4:5678/xyz.iso" + insert_mock.side_effect = exceptions.SushyError + self.vmedia_inst.insert_media(url) self.vmedia_inst._conn.post.assert_called_once_with( "/redfish/v1/Managers/1/VirtualMedia/2/Actions/Oem/Hpe/" "HpeiLOVirtualMedia.InsertVirtualMedia/", data={'Image': url}) - def test_eject_vmedia(self): - self.vmedia_inst.eject_vmedia() + @mock.patch.object(virtual_media.VirtualMedia, 'eject_media') + def test_eject_media_sushy(self, eject_mock): + eject_mock.return_value = None + self.vmedia_inst.eject_media() + self.vmedia_inst.eject_media.assert_called_once() + + @mock.patch.object(sushy_virt_media.VirtualMedia, 'eject_media') + def test_eject_media(self, eject_mock): + eject_mock.side_effect = exceptions.SushyError + self.vmedia_inst.eject_media() self.vmedia_inst._conn.post.assert_called_once_with( "/redfish/v1/Managers/1/VirtualMedia/2/Actions/Oem/Hpe/" "HpeiLOVirtualMedia.EjectVirtualMedia/", diff --git a/proliantutils/tests/redfish/test_redfish.py b/proliantutils/tests/redfish/test_redfish.py index 148af463..9fbf77ad 100644 --- a/proliantutils/tests/redfish/test_redfish.py +++ b/proliantutils/tests/redfish/test_redfish.py @@ -264,7 +264,7 @@ class RedfishOperationsTestCase(testtools.TestCase): return manager_mock, vmedia_collection_json, vmedia_json @mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager') - @mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia') + @mock.patch.object(virtual_media.VirtualMedia, 'eject_media') def test_eject_virtual_media(self, eject_mock, manager_mock): manager_mock.return_value, vmedia_collection_json, vmedia_json = ( self._setup_virtual_media()) @@ -276,7 +276,7 @@ class RedfishOperationsTestCase(testtools.TestCase): eject_mock.assert_called_once_with() @mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager') - @mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia') + @mock.patch.object(virtual_media.VirtualMedia, 'eject_media') def test_eject_virtual_media_invalid_device(self, eject_mock, manager_mock): self.assertRaisesRegex( @@ -289,7 +289,7 @@ class RedfishOperationsTestCase(testtools.TestCase): self.assertFalse(manager_mock.called) @mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager') - @mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia') + @mock.patch.object(virtual_media.VirtualMedia, 'eject_media') def test_eject_virtual_media_not_inserted(self, eject_mock, manager_mock): manager_mock.return_value, vmedia_collection_json, vmedia_json = ( self._setup_virtual_media()) @@ -301,7 +301,7 @@ class RedfishOperationsTestCase(testtools.TestCase): self.assertFalse(eject_mock.called) @mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager') - @mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia') + @mock.patch.object(virtual_media.VirtualMedia, 'eject_media') def test_eject_virtual_media_floppy(self, eject_mock, manager_mock): manager_mock.return_value, vmedia_collection_json, vmedia_json = ( self._setup_virtual_media()) @@ -313,7 +313,7 @@ class RedfishOperationsTestCase(testtools.TestCase): self.assertFalse(eject_mock.called) @mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager') - @mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia') + @mock.patch.object(virtual_media.VirtualMedia, 'eject_media') def test_eject_virtual_media_fail(self, eject_mock, manager_mock): manager_mock.return_value, vmedia_collection_json, vmedia_json = ( self._setup_virtual_media()) @@ -328,8 +328,8 @@ class RedfishOperationsTestCase(testtools.TestCase): 'CDROM') @mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager') - @mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia') - @mock.patch.object(virtual_media.VirtualMedia, 'insert_vmedia') + @mock.patch.object(virtual_media.VirtualMedia, 'eject_media') + @mock.patch.object(virtual_media.VirtualMedia, 'insert_media') def test_insert_virtual_media(self, insert_mock, eject_mock, manager_mock): manager_mock.return_value, vmedia_collection_json, vmedia_json = ( self._setup_virtual_media()) @@ -343,8 +343,8 @@ class RedfishOperationsTestCase(testtools.TestCase): insert_mock.assert_called_once_with(url) @mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager') - @mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia') - @mock.patch.object(virtual_media.VirtualMedia, 'insert_vmedia') + @mock.patch.object(virtual_media.VirtualMedia, 'eject_media') + @mock.patch.object(virtual_media.VirtualMedia, 'insert_media') def test_insert_virtual_media_floppy(self, insert_mock, eject_mock, manager_mock): manager_mock.return_value, vmedia_collection_json, vmedia_json = ( @@ -359,8 +359,8 @@ class RedfishOperationsTestCase(testtools.TestCase): insert_mock.assert_called_once_with(url) @mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager') - @mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia') - @mock.patch.object(virtual_media.VirtualMedia, 'insert_vmedia') + @mock.patch.object(virtual_media.VirtualMedia, 'eject_media') + @mock.patch.object(virtual_media.VirtualMedia, 'insert_media') def test_insert_virtual_media_inserted(self, insert_mock, eject_mock, manager_mock): manager_mock.return_value, vmedia_collection_json, vmedia_json = ( @@ -375,8 +375,8 @@ class RedfishOperationsTestCase(testtools.TestCase): insert_mock.assert_called_once_with(url) @mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager') - @mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia') - @mock.patch.object(virtual_media.VirtualMedia, 'insert_vmedia') + @mock.patch.object(virtual_media.VirtualMedia, 'eject_media') + @mock.patch.object(virtual_media.VirtualMedia, 'insert_media') def test_insert_virtual_media_fail(self, insert_mock, eject_mock, manager_mock): manager_mock.return_value, vmedia_collection_json, vmedia_json = ( diff --git a/requirements.txt b/requirements.txt index a7270170..15ec1401 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,4 +9,4 @@ retrying!=1.3.0,>=1.2.3 # Apache-2.0 pysnmp>=4.2.3,<5.0.0 # BSD # Redfish communication uses the Sushy library -sushy>=1.7.0 +sushy>=1.8.0