From cb362a6ce1b403b4ea176e0c7c28230070a5ec69 Mon Sep 17 00:00:00 2001 From: paresh-sao Date: Tue, 9 Jan 2018 11:13:42 +0000 Subject: [PATCH] Redfish: Changed 'update_persistent_boot' to set 'UefiTarget' boot device. Also removed 'mac' from 'set_one_time_boot' Adds modification in 'update_persistent_boot' to set 'UefiTarget' as boot device, without using 'mac'. Also removed 'mac' from 'set_one_time_boot' and 'update_persistent_boot' Change-Id: If47f68d25d2e3a3a1b58606c415c53b108e90cc1 --- proliantutils/redfish/redfish.py | 10 ++-- .../redfish/resources/system/system.py | 34 ++++++----- .../tests/redfish/json_samples/system.json | 60 ++++++++++++++++++- .../redfish/resources/system/test_system.py | 45 +++++++------- proliantutils/tests/redfish/test_redfish.py | 4 +- 5 files changed, 105 insertions(+), 48 deletions(-) diff --git a/proliantutils/redfish/redfish.py b/proliantutils/redfish/redfish.py index 5769dd56..2d1d94b8 100644 --- a/proliantutils/redfish/redfish.py +++ b/proliantutils/redfish/redfish.py @@ -538,11 +538,10 @@ class RedfishOperations(operations.IloOperations): LOG.debug(msg) raise exception.IloError(msg) - def update_persistent_boot(self, devices=[], mac=None): + def update_persistent_boot(self, devices=[]): """Changes the persistent boot device order for the host :param devices: ordered list of boot devices - :param mac: intiator mac address, mandatory for iSCSI uefi boot :raises: IloError, on an error from iLO. :raises: IloInvalidInputError, if the given input is not valid. """ @@ -557,7 +556,7 @@ class RedfishOperations(operations.IloOperations): try: sushy_system.update_persistent_boot( - devices, persistent=True, mac=mac) + devices, persistent=True) except sushy.exceptions.SushyError as e: msg = (self._('The Redfish controller failed to update ' 'persistent boot device %(devices)s.' @@ -566,11 +565,10 @@ class RedfishOperations(operations.IloOperations): LOG.debug(msg) raise exception.IloError(msg) - def set_one_time_boot(self, device, mac=None): + def set_one_time_boot(self, device): """Configures a single boot from a specific device. :param device: Device to be set as a one time boot device - :param mac: intiator mac address, optional parameter :raises: IloError, on an error from iLO. :raises: IloInvalidInputError, if the given input is not valid. """ @@ -584,7 +582,7 @@ class RedfishOperations(operations.IloOperations): try: sushy_system.update_persistent_boot( - [device], persistent=False, mac=mac) + [device], persistent=False) except sushy.exceptions.SushyError as e: msg = (self._('The Redfish controller failed to set ' 'one time boot device %(device)s. ' diff --git a/proliantutils/redfish/resources/system/system.py b/proliantutils/redfish/resources/system/system.py index e453e731..c98a8fba 100644 --- a/proliantutils/redfish/resources/system/system.py +++ b/proliantutils/redfish/resources/system/system.py @@ -67,7 +67,10 @@ class HPESystem(system.System): model = base.Field(['Model']) rom_version = base.Field(['Oem', 'Hpe', 'Bios', 'Current', 'VersionString']) - + uefi_target_override_devices = (base.Field([ + 'Boot', + 'UefiTargetBootSourceOverride@Redfish.AllowableValues'], + adapter=list)) supported_boot_mode = base.MappedField( ['Oem', 'Hpe', 'Bios', 'UefiClass'], mappings.SUPPORTED_BOOT_MODE, default=constants.SUPPORTED_LEGACY_BIOS_ONLY) @@ -133,8 +136,7 @@ class HPESystem(system.System): return self._bios_settings - def update_persistent_boot(self, devices=[], persistent=False, - mac=None): + def update_persistent_boot(self, devices=[], persistent=False): """Changes the persistent boot device order in BIOS boot mode for host Note: It uses first boot device from the devices and ignores rest. @@ -142,26 +144,30 @@ class HPESystem(system.System): :param devices: ordered list of boot devices :param persistent: Boolean flag to indicate if the device to be set as a persistent boot device - :param mac: intiator mac address, mandotory for iSCSI uefi boot :raises: IloError, on an error from iLO. :raises: IloInvalidInputError, if the given input is not valid. """ device = PERSISTENT_BOOT_DEVICE_MAP.get(devices[0].upper()) - if device == sushy.BOOT_SOURCE_TARGET_UEFI_TARGET: - if not mac: - msg = ('Mac is needed for uefi iscsi boot') - raise exception.IloInvalidInputError(msg) - try: - uefi_boot_string = (self.bios_settings.boot_settings. - get_uefi_boot_string(mac)) - except sushy.exceptions.SushyError: - msg = ('The BIOS Boot Settings was not found.') + uefi_devices = self.uefi_target_override_devices + iscsi_device = None + for uefi_device in uefi_devices: + if uefi_device is not None and 'iSCSI' in uefi_device: + iscsi_device = uefi_device + break + + if iscsi_device is None: + msg = 'No UEFI iSCSI bootable device found on system.' + raise exception.IloError(msg) + + except sushy.exceptions.SushyError as e: + msg = ('Unable to get uefi target override devices. ' + 'Error %s') % (str(e)) raise exception.IloError(msg) uefi_boot_settings = { - 'Boot': {'UefiTargetBootSourceOverride': uefi_boot_string} + 'Boot': {'UefiTargetBootSourceOverride': iscsi_device} } self._conn.patch(self.path, data=uefi_boot_settings) elif device is None: diff --git a/proliantutils/tests/redfish/json_samples/system.json b/proliantutils/tests/redfish/json_samples/system.json index 8801c469..e4d703c6 100644 --- a/proliantutils/tests/redfish/json_samples/system.json +++ b/proliantutils/tests/redfish/json_samples/system.json @@ -423,5 +423,63 @@ "SKU": " ", "SystemType": "Physical", "UUID": "00000000-0000-0000-0000-000000000000" - } + }, + + "System_op_for_update_persistent_boot_uefi_target": { + "@odata.context": "/redfish/v1/$metadata#Systems/Members/$entity", + "@odata.etag": "W/\"0E79655D\"", + "@odata.id": "/redfish/v1/Systems/1/", + "@odata.type": "#ComputerSystem.v1_2_0.ComputerSystem", + "Actions": { + "#ComputerSystem.Reset": { + "ResetType@Redfish.AllowableValues": [ + "On", + "ForceOff", + "ForceRestart", + "Nmi", + "PushPowerButton" + ], + "target": "/redfish/v1/Systems/1/Actions/ComputerSystem.Reset/" + } + }, + "HostName": "", + "Id": "1", + "IndicatorLED": "Off", + "Manufacturer": "HPE", + "Name": "Computer System", + "PowerState": "On", + "Boot": { + "BootSourceOverrideEnabled": "Once", + "BootSourceOverrideMode": "UEFI", + "BootSourceOverrideTarget": "Cd", + "BootSourceOverrideTarget@Redfish.AllowableValues": [ + "None", + "Cd", + "Hdd", + "Usb", + "SDCard", + "Utilities", + "Diags", + "BiosSetup", + "Pxe", + "UefiShell", + "UefiHttp", + "UefiTarget" + ], + "UefiTargetBootSourceOverride": "None", + "UefiTargetBootSourceOverride@Redfish.AllowableValues": [ + "HD(1,GPT,4029CE09-5C2D-464D-9C2D-EC6E607F06A1,0x800,0x100000)/\\EFI\\redhat\\shim.efi", + "HD(1,GPT,4029CE09-5C2D-464D-9C2D-EC6E607F06A1,0x800,0x100000)/\\EFI\\ubuntu\\shimx64.efi", + "HD(1,GPT,7F14DF43-6600-420A-9950-C028836F6A5D,0x800,0x64000)/\\EFI\\centos\\shim.efi", + "PciRoot(0x0)/Pci(0x17,0x0)/Sata(0x3,0x0,0x0)", + "PciRoot(0x3)/Pci(0x0,0x0)/Pci(0x0,0x0)/Scsi(0x0,0x0)", + "PciRoot(0x0)/Pci(0x1C,0x0)/Pci(0x0,0x0)/MAC(98F2B3EEF886,0x0)/IPv4(172.17.1.32)/iSCSI(iqn.2001-04.com.paresh.boot:volume.bin,0x1,0x0,None,None,None,TCP)" + ] + + }, + "SerialNumber": " ", + "SKU": " ", + "SystemType": "Physical", + "UUID": "00000000-0000-0000-0000-000000000000" + } } diff --git a/proliantutils/tests/redfish/resources/system/test_system.py b/proliantutils/tests/redfish/resources/system/test_system.py index ea39e781..55f9d77a 100644 --- a/proliantutils/tests/redfish/resources/system/test_system.py +++ b/proliantutils/tests/redfish/resources/system/test_system.py @@ -146,18 +146,14 @@ class HPESystemTestCase(testtools.TestCase): def test_update_persistent_boot_uefi_target(self): with open('proliantutils/tests/redfish/' - 'json_samples/bios.json', 'r') as f: - bios_mock = json.loads(f.read()) - with open('proliantutils/tests/redfish/' - 'json_samples/bios_boot.json', 'r') as f: - bios_boot_mock = json.loads(f.read()) - self.conn.get.return_value.json.reset() - self.conn.get.return_value.json.side_effect = ( - [bios_mock['Default'], bios_boot_mock['Default']]) - self.sys_inst.update_persistent_boot(['ISCSI'], persistent=True, - mac='C4346BB7EF30') + 'json_samples/system.json', 'r') as f: + system_json = (json.loads(f.read())[ + 'System_op_for_update_persistent_boot_uefi_target']) + self.sys_inst.uefi_target_override_devices = (system_json[ + 'Boot']['UefiTargetBootSourceOverride@Redfish.AllowableValues']) + self.sys_inst.update_persistent_boot(['ISCSI'], persistent=True) uefi_boot_settings = { - 'Boot': {'UefiTargetBootSourceOverride': 'NIC.LOM.1.1.iSCSI'} + 'Boot': {'UefiTargetBootSourceOverride': 'PciRoot(0x0)/Pci(0x1C,0x0)/Pci(0x0,0x0)/MAC(98F2B3EEF886,0x0)/IPv4(172.17.1.32)/iSCSI(iqn.2001-04.com.paresh.boot:volume.bin,0x1,0x0,None,None,None,TCP)'} # noqa } calls = [mock.call('/redfish/v1/Systems/1', data=uefi_boot_settings), @@ -167,22 +163,21 @@ class HPESystemTestCase(testtools.TestCase): 'BootSourceOverrideEnabled': 'Continuous'}})] self.sys_inst._conn.patch.assert_has_calls(calls) - def test_update_persistent_boot_uefi_target_without_mac(self): - self.assertRaisesRegex( - exception.IloInvalidInputError, - 'Mac is needed for uefi iscsi boot', - self.sys_inst.update_persistent_boot, ['ISCSI'], True, None) - - def test_update_persistent_boot_uefi_target_fail(self): - with open('proliantutils/tests/redfish/' - 'json_samples/bios.json', 'r') as f: - bios_mock = json.loads(f.read()) - self.conn.get.return_value.json.side_effect = ( - [bios_mock['Default'], sushy.exceptions.SushyError]) + def test_update_persistent_boot_uefi_no_iscsi_device(self): self.assertRaisesRegex( exception.IloError, - 'The BIOS Boot Settings was not found.', - self.sys_inst.update_persistent_boot, ['ISCSI'], True, '12345678') + 'No UEFI iSCSI bootable device found on system.', + self.sys_inst.update_persistent_boot, ['ISCSI'], True) + + def test_update_persistent_boot_uefi_target_fail(self): + update_mock = mock.PropertyMock( + side_effect=sushy.exceptions.SushyError) + type(self.sys_inst).uefi_target_override_devices = update_mock + self.assertRaisesRegex( + exception.IloError, + 'Unable to get uefi target override devices.', + self.sys_inst.update_persistent_boot, ['ISCSI'], True) + del type(self.sys_inst).uefi_target_override_devices def test_pci_devices(self): pci_dev_return_value = None diff --git a/proliantutils/tests/redfish/test_redfish.py b/proliantutils/tests/redfish/test_redfish.py index 017dbe2f..bc45e90a 100644 --- a/proliantutils/tests/redfish/test_redfish.py +++ b/proliantutils/tests/redfish/test_redfish.py @@ -545,7 +545,7 @@ class RedfishOperationsTestCase(testtools.TestCase): def test_update_persistent_boot(self, get_system_mock): self.rf_client.update_persistent_boot(['NETWORK']) (get_system_mock.return_value.update_persistent_boot. - assert_called_once_with(['NETWORK'], mac=None, persistent=True)) + assert_called_once_with(['NETWORK'], persistent=True)) def test_update_persistent_boot_invalid_input(self): self.assertRaisesRegex( @@ -568,7 +568,7 @@ class RedfishOperationsTestCase(testtools.TestCase): def test_set_one_time_boot(self, get_system_mock): self.rf_client.set_one_time_boot('CDROM') (get_system_mock.return_value.update_persistent_boot. - assert_called_once_with(['CDROM'], mac=None, persistent=False)) + assert_called_once_with(['CDROM'], persistent=False)) def test_set_one_time_boot_invalid_input(self): self.assertRaisesRegex(