Redfish: Adding the ability to get pending boot mode

This commit adds new function 'get_pending_boot_mode' to
get pending boot mode for server.
Change-Id: If4f2b5ef9fff1c25b233621004c1a4efa2dd0f64
This commit is contained in:
kesper 2017-05-25 10:16:25 +00:00
parent 41ea204fc5
commit c7c07642e3
10 changed files with 518 additions and 0 deletions

View File

@ -64,6 +64,8 @@ SUPPORTED_REDFISH_METHODS = [
'reset_server',
'press_pwr_btn',
'hold_pwr_btn',
'get_one_time_boot',
'get_pending_boot_mode',
]
LOG = log.get_logger(__name__)

View File

@ -16,6 +16,7 @@ __author__ = 'HPE'
from six.moves.urllib import parse
import sushy
from sushy import utils
from proliantutils import exception
from proliantutils.ilo import operations
@ -48,7 +49,13 @@ DEVICE_COMMON_TO_REDFISH = {
DEVICE_REDFISH_TO_COMMON = {v: k for k, v in DEVICE_COMMON_TO_REDFISH.items()}
BOOT_MODE_MAP = {
sys_cons.BIOS_BOOT_MODE_LEGACY_BIOS: 'LEGACY',
sys_cons.BIOS_BOOT_MODE_UEFI: 'UEFI'
}
BOOT_MODE_MAP_REV = (
utils.revert_dictionary(BOOT_MODE_MAP))
# Assuming only one sushy_system present as part of collection,
# as we are dealing with iLO's here.
PROLIANT_SYSTEM_ID = '1'
@ -248,3 +255,21 @@ class RedfishOperations(operations.IloOperations):
else:
# value returned by RIBCL if one-time boot setting are absent
return 'Normal'
def get_pending_boot_mode(self):
"""Retrieves the pending boot mode of the server.
Gets the boot mode to be set on next reset.
:returns: either LEGACY or UEFI.
:raises: IloError, on an error from iLO.
"""
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
try:
return BOOT_MODE_MAP.get(
sushy_system.bios_settings.pending_settings.boot_mode)
except sushy.exceptions.SushyError as e:
msg = (self._('The pending BIOS Settings was not found. Error'
'%(error)s') %
{'error': str(e)})
LOG.debug(msg)
raise exception.IloError(msg)

View File

@ -0,0 +1,43 @@
# Copyright 2017 Hewlett Packard Enterprise Development LP
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from proliantutils.redfish.resources.system import mappings
from proliantutils.redfish import utils
from sushy.resources import base
class BIOSSettings(base.ResourceBase):
_pending_settings = None
@property
def pending_settings(self):
"""Property to provide reference to bios settings instance
It is calculated once when the first time it is queried. On refresh,
this property gets reset.
"""
if self._pending_settings is None:
self._pending_settings = BIOSPendingSettings(
self._conn, utils.get_subresource_path_by(
self, ["@Redfish.Settings", "SettingsObject"]),
redfish_version=self.redfish_version)
return self._pending_settings
class BIOSPendingSettings(base.ResourceBase):
boot_mode = base.MappedField(["Attributes", "BootMode"],
mappings.GET_BIOS_BOOT_MODE_MAP)

View File

@ -18,3 +18,8 @@
PUSH_POWER_BUTTON_PRESS = 'press'
PUSH_POWER_BUTTON_PRESS_AND_HOLD = 'press and hold'
# BIOS Settings boot mode constants
BIOS_BOOT_MODE_LEGACY_BIOS = 'legacy bios'
BIOS_BOOT_MODE_UEFI = 'uefi'

View File

@ -25,3 +25,12 @@ PUSH_POWER_BUTTON_VALUE_MAP = {
PUSH_POWER_BUTTON_VALUE_MAP_REV = (
utils.revert_dictionary(PUSH_POWER_BUTTON_VALUE_MAP))
# BIOS Settings boot mode mappings
GET_BIOS_BOOT_MODE_MAP = {
'LegacyBios': constants.BIOS_BOOT_MODE_LEGACY_BIOS,
'Uefi': constants.BIOS_BOOT_MODE_UEFI
}
GET_BIOS_BOOT_MODE_MAP_REV = (
utils.revert_dictionary(GET_BIOS_BOOT_MODE_MAP))

View File

@ -19,7 +19,9 @@ from sushy.resources.system import system
from proliantutils import exception
from proliantutils import log
from proliantutils.redfish.resources.system import bios
from proliantutils.redfish.resources.system import mappings
from proliantutils.redfish import utils
LOG = log.get_logger(__name__)
@ -44,8 +46,11 @@ class HPESystem(system.System):
"""
_hpe_actions = HpeActionsField(['Oem', 'Hpe', 'Actions'], required=True)
"""Oem specific system extensibility actions"""
_bios_settings = None
def _get_hpe_push_power_button_action_element(self):
push_action = self._hpe_actions.computer_system_ext_powerbutton
if not push_action:
@ -76,3 +81,17 @@ class HPESystem(system.System):
self._get_hpe_push_power_button_action_element().target_uri)
self._conn.post(target_uri, data={'PushType': value})
@property
def bios_settings(self):
"""Property to provide reference to bios resources instance
It is calculated once when the first time it is queried. On refresh,
this property gets reset.
"""
if self._bios_settings is None:
self._bios_settings = bios.BIOSSettings(
self._conn, utils.get_subresource_path_by(self, 'Bios'),
redfish_version=self.redfish_version)
return self._bios_settings

View File

@ -0,0 +1,307 @@
{
"Default": {
"@Redfish.Settings": {
"@odata.type": "#Settings.v1_0_0.Settings",
"ETag": "C4690603",
"Messages": [
{
"MessageId": "Base.1.0.Success"
},
{
"MessageArgs": [
"NumaGroupSizeOpt"
],
"MessageId": "Base.1.0.PropertyNotWritable",
"RelatedProperties": [
"#/NumaGroupSizeOpt"
]
}
],
"SettingsObject": {
"@odata.id": "/redfish/v1/systems/1/bios/settings/"
},
"Time": "2017-06-10T07:40:44+00:00"
},
"@odata.context": "/redfish/v1/$metadata#Bios.Bios",
"@odata.etag": "W/\"EC55BACC2FF03737379F24EEF1948CE0\"",
"@odata.id": "/redfish/v1/systems/1/bios/",
"@odata.type": "#Bios.v1_0_0.Bios",
"Actions": {
"#Bios.ChangePassword": {
"target": "/redfish/v1/systems/1/bios/settings/Actions/Bios.ChangePasswords/"
},
"#Bios.ResetBios": {
"target": "/redfish/v1/systems/1/bios/settings/Actions/Bios.ResetBios/"
}
},
"AttributeRegistry": "BiosAttributeRegistryU31.v1_1_00",
"Attributes": {
"AcpiHpet": "Enabled",
"AcpiRootBridgePxm": "Enabled",
"AcpiSlit": "Enabled",
"AdjSecPrefetch": "Enabled",
"AdminEmail": "",
"AdminName": "",
"AdminOtherInfo": "",
"AdminPhone": "",
"AdvancedMemProtection": "AdvancedEcc",
"AsrStatus": "Enabled",
"AsrTimeoutMinutes": "Timeout10",
"AssetTagProtection": "Unlocked",
"AutoPowerOn": "RestoreLastState",
"BootMode": "Uefi",
"BootOrderPolicy": "RetryIndefinitely",
"ChannelInterleaving": "Enabled",
"Chipset_TpmFeatureEnableOrDisable": "Disabled",
"Chipset_TpmFeatureType": "Chipset-TpmFeature:NONE",
"CollabPowerControl": "Enabled",
"ConsistentDevNaming": "LomsAndSlots",
"CustomPostMessage": "",
"DaylightSavingsTime": "Disabled",
"DcuIpPrefetcher": "Enabled",
"DcuStreamPrefetcher": "Enabled",
"Dhcpv4": "Enabled",
"DynamicPowerCapping": "Disabled",
"EmbNicAspm": "Disabled",
"EmbNicEnable": "Auto",
"EmbNicLinkSpeed": "Auto",
"EmbNicPCIeOptionROM": "Enabled",
"EmbSas1Aspm": "Disabled",
"EmbSas1LinkSpeed": "Auto",
"EmbSas1PcieOptionROM": "Enabled",
"EmbSata1Enable": "Auto",
"EmbSata1PCIeOptionROM": "Enabled",
"EmbSata2Enable": "Auto",
"EmbSata2PCIeOptionROM": "Enabled",
"EmbVideoConnection": "Auto",
"EmbeddedDiagnostics": "Enabled",
"EmbeddedDiagsMode": "Auto",
"EmbeddedSata": "Ahci",
"EmbeddedSerialPort": "Com2Irq3",
"EmbeddedUefiShell": "Enabled",
"EmsConsole": "Disabled",
"EnabledCoresPerProc": 0,
"EnergyEfficientTurbo": "Enabled",
"EnergyPerfBias": "BalancedPerf",
"EraseUserDefaults": "No",
"ExtendedAmbientTemp": "Disabled",
"ExtendedMemTest": "Disabled",
"F11BootMenu": "Enabled",
"FCScanPolicy": "CardConfig",
"FanFailPolicy": "Shutdown",
"FanInstallReq": "EnableMessaging",
"FlexLom1Aspm": "Disabled",
"FlexLom1LinkSpeed": "Auto",
"FlexLom1PCIeOptionROM": "Enabled",
"HpeScalablePmemBackupState": "Complete",
"HpeScalablePmemConfigurationRestoration": "Disabled",
"HpeScalablePmemFunctionalityEnabled": "Disabled",
"HpeScalablePmemStorageInitialize": "Disabled",
"HttpSupport": "Auto",
"HwPrefetcher": "Enabled",
"IntelDmiLinkFreq": "Auto",
"IntelNicDmaChannels": "Enabled",
"IntelPerfMonitoring": "Disabled",
"IntelProcVtd": "Enabled",
"IntelUpiFreq": "Auto",
"IntelUpiLinkEn": "Auto",
"IntelUpiPowerManagement": "Enabled",
"IntelligentProvisioning": "Enabled",
"InternalSDCardSlot": "Enabled",
"Ipv4Address": "0.0.0.0",
"Ipv4Gateway": "0.0.0.0",
"Ipv4PrimaryDNS": "0.0.0.0",
"Ipv4SecondaryDNS": "0.0.0.0",
"Ipv4SubnetMask": "0.0.0.0",
"Ipv6Address": "::",
"Ipv6ConfigPolicy": "Automatic",
"Ipv6Duid": "Auto",
"Ipv6Gateway": "::",
"Ipv6PrimaryDNS": "::",
"Ipv6SecondaryDNS": "::",
"LocalRemoteThreshold": "Auto",
"MaxMemBusFreqMHz": "Auto",
"MaxPcieSpeed": "PerPortCtrl",
"MemClearWarmReset": "Disabled",
"MemFastTraining": "Enabled",
"MemMirrorMode": "Full",
"MemPatrolScrubbing": "Enabled",
"MemRefreshRate": "Refreshx2",
"MemoryRemap": "NoAction",
"MinProcIdlePkgState": "C6Retention",
"MinProcIdlePower": "C6",
"MixedPowerSupplyReporting": "Enabled",
"NetworkBootRetry": "Enabled",
"NetworkBootRetryCount": 20,
"NicBoot1": "NetworkBoot",
"NicBoot3": "Disabled",
"NicBoot4": "Disabled",
"NodeInterleaving": "Disabled",
"NumaGroupSizeOpt": "Clustered",
"NvDimmNMemInterleaving": "Disabled",
"NvmeOptionRom": "Enabled",
"PciResourcePadding": "Normal",
"PciSlot1Aspm": "Disabled",
"PciSlot1LinkSpeed": "Auto",
"PciSlot1OptionROM": "Enabled",
"PciSlot2Aspm": "Disabled",
"PciSlot2LinkSpeed": "Auto",
"PciSlot2OptionROM": "Enabled",
"PciSlot3Aspm": "Disabled",
"PciSlot3LinkSpeed": "Auto",
"PciSlot3OptionROM": "Enabled",
"PciSlot4Aspm": "Disabled",
"PciSlot4LinkSpeed": "Auto",
"PciSlot4OptionROM": "Enabled",
"PciSlot5Aspm": "Disabled",
"PciSlot5LinkSpeed": "Auto",
"PciSlot5OptionROM": "Enabled",
"PciSlot6Aspm": "Disabled",
"PciSlot6LinkSpeed": "Auto",
"PciSlot6OptionROM": "Enabled",
"PersistentMemAddressRangeScrub": "Enabled",
"PersistentMemBackupPowerPolicy": "WaitForBackupPower",
"PersistentMemScanMem": "Enabled",
"PostBootProgress": "Disabled",
"PostDiscoveryMode": "ForceFullDiscovery",
"PostF1Prompt": "Delayed20Sec",
"PowerButton": "Enabled",
"PowerOnDelay": "NoDelay",
"PowerOnLogo": "Enabled",
"PowerRegulator": "DynamicPowerSavings",
"PreBootNetwork": "Auto",
"PrebootNetworkEnvPolicy": "Auto",
"PrebootNetworkProxy": "",
"ProcAes": "Enabled",
"ProcHyperthreading": "Enabled",
"ProcTurbo": "Enabled",
"ProcVirtualization": "Enabled",
"ProcX2Apic": "Enabled",
"Processor1LogicalNvdimm1SizeGiB": 0,
"Processor1LogicalNvdimm2SizeGiB": 0,
"Processor1ScalablePmemAvailableGiB": 0,
"Processor2LogicalNvdimm1SizeGiB": 0,
"Processor2LogicalNvdimm2SizeGiB": 0,
"Processor2ScalablePmemAvailableGiB": 0,
"Processor3LogicalNvdimm1SizeGiB": 0,
"Processor3LogicalNvdimm2SizeGiB": 0,
"Processor3ScalablePmemAvailableGiB": 0,
"Processor4LogicalNvdimm1SizeGiB": 0,
"Processor4LogicalNvdimm2SizeGiB": 0,
"Processor4ScalablePmemAvailableGiB": 0,
"ProcessorJitterControl": "Disabled",
"ProcessorJitterControlFrequency": 0,
"ProductId": "",
"RedundantPowerSupply": "BalancedMode",
"RemovableFlashBootSeq": "ExternalKeysFirst",
"RestoreDefaults": "No",
"RestoreManufacturingDefaults": "No",
"RomSelection": "CurrentRom",
"SataSecureErase": "Disabled",
"SaveUserDefaults": "No",
"ScalablePmemCapacity": 0,
"SecureBootStatus": "Disabled",
"SerialConsoleBaudRate": "BaudRate115200",
"SerialConsoleEmulation": "Vt100Plus",
"SerialConsolePort": "Auto",
"SerialNumber": "",
"ServerAssetTag": "",
"ServerName": "",
"ServerOtherInfo": "",
"ServerPrimaryOs": "",
"ServiceEmail": "",
"ServiceName": "",
"ServiceOtherInfo": "",
"ServicePhone": "",
"SetupBrowserSelection": "Auto",
"SpannedLogicalNvdimm1AvailableMemoryGiB": 0,
"SpannedLogicalNvdimm1SizeGiB": 0,
"SpannedLogicalNvdimm1StartingDomainId": 0,
"SpannedLogicalNvdimm1StartingDomainSize": 0,
"SpannedLogicalNvdimm2AvailableMemoryGiB": 0,
"SpannedLogicalNvdimm2SizeGiB": 0,
"SpannedLogicalNvdimm2StartingDomainId": 0,
"SpannedLogicalNvdimm2StartingDomainSize": 0,
"Sriov": "Enabled",
"SubNumaClustering": "Disabled",
"ThermalConfig": "OptimalCooling",
"ThermalShutdown": "Enabled",
"TimeFormat": "Utc",
"TimeZone": "Utc0",
"TpmChipId": "None",
"TpmFips": "NotSpecified",
"TpmState": "NotPresent",
"TpmType": "NoTpm",
"UefiOptimizedBoot": "Enabled",
"UefiSerialDebugLevel": "Disabled",
"UefiShellBootOrder": "Disabled",
"UefiShellScriptVerification": "Disabled",
"UefiShellStartup": "Disabled",
"UefiShellStartupLocation": "Auto",
"UefiShellStartupUrl": "",
"UefiShellStartupUrlFromDhcp": "Disabled",
"UncoreFreqScaling": "Auto",
"UpiPrefetcher": "Enabled",
"UrlBootFile": "",
"UrlBootFile2": "",
"UrlBootFile3": "",
"UrlBootFile4": "",
"UsbBoot": "Enabled",
"UsbControl": "UsbEnabled",
"UserDefaultsState": "Disabled",
"UtilityLang": "English",
"VirtualInstallDisk": "Disabled",
"VirtualSerialPort": "Com1Irq4",
"VlanControl": "Disabled",
"VlanId": 0,
"VlanPriority": 0,
"WakeOnLan": "Enabled",
"WorkloadProfile": "GeneralPowerEfficientCompute",
"XptPrefetcher": "Enabled",
"iSCSIPolicy": "SoftwareInitiator"
},
"Id": "bios",
"Name": "BIOS Current Settings",
"Oem": {
"Hpe": {
"@odata.type": "#HpeBiosExt.v2_0_0.HpeBiosExt",
"Links": {
"BaseConfigs": {
"@odata.id": "/redfish/v1/systems/1/bios/baseconfigs/"
},
"Boot": {
"@odata.id": "/redfish/v1/systems/1/bios/boot/"
},
"Mappings": {
"@odata.id": "/redfish/v1/systems/1/bios/mappings/"
},
"ScalablePmem": {
"@odata.id": "/redfish/v1/systems/1/bios/hpescalablepmem/"
},
"TlsConfig": {
"@odata.id": "/redfish/v1/systems/1/bios/tlsconfig/"
},
"iScsi": {
"@odata.id": "/redfish/v1/systems/1/bios/iscsi/"
}
},
"SettingsObject": {
"UnmodifiedETag": "W/\"7F2D028BA2542B2B2B2AF4CFFD358F35\""
}
}
}
},
"BIOS_settings_default": {
"@odata.context": "/redfish/v1/$metadata#Bios.Bios",
"@odata.etag": "W/\"7F2D028BA2542B2B2B2AF4CFFD358F35\"",
"@odata.id": "/redfish/v1/systems/1/bios/settings/",
"@odata.type": "#Bios.v1_0_0.Bios",
"AttributeRegistry": "BiosAttributeRegistryU31.v1_1_00",
"Attributes": {
"BootMode": "Uefi"
},
"Id": "settings",
"Name": "BIOS Current Settings"
}
}

View File

@ -0,0 +1,72 @@
# Copyright 2017 Hewlett Packard Enterprise Development LP
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import mock
import testtools
from proliantutils.redfish.resources.system import bios
class BIOSSettingsTestCase(testtools.TestCase):
def setUp(self):
super(BIOSSettingsTestCase, self).setUp()
self.conn = mock.MagicMock()
with open('proliantutils/tests/redfish/'
'json_samples/bios.json', 'r') as f:
self.conn.get.return_value.json.return_value = (
json.loads(f.read())['Default'])
self.bios_inst = bios.BIOSSettings(
self.conn, '/redfish/v1/Systems/1/bios',
redfish_version='1.0.2')
def test_pending_settings(self):
self.assertIsNone(self.bios_inst._pending_settings)
self.conn.get.return_value.json.reset_mock()
with open('proliantutils/tests/redfish/'
'json_samples/bios.json', 'r') as f:
self.conn.get.return_value.json.return_value = (
json.loads(f.read())['BIOS_settings_default'])
actual_settings = self.bios_inst.pending_settings
self.assertIsInstance(actual_settings,
bios.BIOSPendingSettings)
self.conn.get.return_value.json.assert_called_once_with()
# reset mock
self.conn.get.return_value.json.reset_mock()
self.assertIs(actual_settings,
self.bios_inst.pending_settings)
self.conn.get.return_value.json.assert_not_called()
class BIOSPendingSettingsTestCase(testtools.TestCase):
def setUp(self):
super(BIOSPendingSettingsTestCase, self).setUp()
self.conn = mock.MagicMock()
with open('proliantutils/tests/redfish/'
'json_samples/bios.json', 'r') as f:
self.conn.get.return_value.json.return_value = (
json.loads(f.read())['BIOS_settings_default'])
self.bios_settings_inst = bios.BIOSPendingSettings(
self.conn, '/redfish/v1/Systems/1/bios/settings',
redfish_version='1.0.2')
def test_attributes(self):
self.assertEqual('uefi', self.bios_settings_inst.boot_mode)

View File

@ -19,6 +19,7 @@ import mock
import testtools
from proliantutils import exception
from proliantutils.redfish.resources.system import bios
from proliantutils.redfish.resources.system import constants as sys_cons
from proliantutils.redfish.resources.system import system
@ -62,3 +63,19 @@ class HPESystemTestCase(testtools.TestCase):
def test_push_power_button_invalid_value(self):
self.assertRaises(exception.InvalidInputError,
self.sys_inst.push_power_button, 'invalid-value')
def test_bios_settings(self):
self.assertIsNone(self.sys_inst._bios_settings)
self.conn.get.return_value.json.reset_mock()
with open('proliantutils/tests/redfish/'
'json_samples/bios.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
actual_bios = self.sys_inst.bios_settings
self.assertIsInstance(actual_bios,
bios.BIOSSettings)
self.conn.get.return_value.json.assert_called_once_with()
# reset mock
self.conn.get.return_value.json.reset_mock()
self.assertIs(actual_bios,
self.sys_inst.bios_settings)
self.conn.get.return_value.json.assert_not_called()

View File

@ -175,3 +175,22 @@ class RedfishOperationsTestCase(testtools.TestCase):
get_system_mock.return_value = self.sys_inst
ret = self.rf_client.get_one_time_boot()
self.assertEqual(ret, 'CDROM')
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
def test_get_pending_boot_mode(self, get_system_mock):
for cons_val in redfish.BOOT_MODE_MAP.keys():
(get_system_mock.return_value.bios_settings.
pending_settings.boot_mode) = cons_val
result = self.rf_client.get_pending_boot_mode()
self.assertEqual(redfish.BOOT_MODE_MAP[cons_val], result)
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
def test_get_pending_boot_mode_fail(self, get_system_mock):
bios_settings_mock = mock.PropertyMock(
side_effect=sushy.exceptions.SushyError)
type(get_system_mock.return_value.bios_settings).pending_settings = (
bios_settings_mock)
self.assertRaisesRegex(
exception.IloError,
'The pending BIOS Settings was not found.',
self.rf_client.get_pending_boot_mode)