When ManagedBy attribute is missing from System retry with Managers

On some hardware, ManagedBy attribute is missing from System and
Managers attribute is used instead. This change enables sushy to detect
this condition and retry the request, allowing sushy to support such
hardware.

Change-Id: Ibc81e64b8ac0533024c203ea48003aea764901c3
(cherry picked from commit dccdadec5c)
This commit is contained in:
Jacob Anders
2024-08-15 12:52:09 +10:00
committed by Dmitry Tantsur
parent 285498f1aa
commit 2805e27a86
4 changed files with 214 additions and 3 deletions

View File

@@ -0,0 +1,6 @@
---
fixes:
- |
Adds the ability to retry an attempt to determine a Manager for a System
when ManagedBy attribute is missing but Managers attribute is present.
This resolves issues with certain hardware models such as Huawei 1288H.

View File

@@ -507,9 +507,21 @@ class System(base.ResourceBase):
:raises: MissingAttributeError if '@odata.id' field is missing.
:returns: A list of `Manager` instances
"""
paths = utils.get_sub_resource_path_by(
self, ["Links", "ManagedBy"], is_collection=True)
try:
paths = utils.get_sub_resource_path_by(
self, ["Links", "ManagedBy"], is_collection=True)
except exceptions.MissingAttributeError as exc_orig:
LOG.warning('Unable to find ManagedBy attribute for System %s, '
'retrying with Managers attribute', self.identity)
try:
paths = utils.get_sub_resource_path_by(
self, ["Links", "Managers"], is_collection=True)
except exceptions.MissingAttributeError:
LOG.error('Both ManagedBy and Managers attributes missing for '
'System %s, aborting', self.identity)
# NOTE(janders) last_error may record only Managers and not
# ManagedBy MissingAttributeError with this approach
raise exc_orig
return [manager.Manager(self._conn, path,
redfish_version=self.redfish_version,
registries=self.registries, root=self.root)

View File

@@ -0,0 +1,166 @@
{
"@odata.type": "#ComputerSystem.v1_10_0.ComputerSystem",
"Id": "437XR1138R2",
"Name": "WebFrontEnd483",
"SystemType": "Physical",
"AssetTag": "Chicago-45Z-2381",
"Manufacturer": "Contoso",
"Model": "3500",
"SubModel": "RX",
"SKU": "8675309",
"SerialNumber": "437XR1138R2",
"PartNumber": "224071-J23",
"Description": "Web Front End node",
"UUID": "38947555-7742-3448-3784-823347823834",
"HostName": "web483",
"Status": {
"State": "Enabled",
"Health": "OK",
"HealthRollup": "OK"
},
"HostingRoles": [
"ApplicationServer"
],
"IndicatorLED": "Off",
"PowerState": "On",
"Boot": {
"BootSourceOverrideEnabled": "Once",
"BootSourceOverrideTarget": "Pxe",
"BootSourceOverrideTarget@Redfish.AllowableValues": [
"None",
"Pxe",
"Cd",
"Usb",
"Hdd",
"BiosSetup",
"Utilities",
"Diags",
"SDCard",
"UefiTarget",
"UefiHttp"
],
"BootSourceOverrideMode": "UEFI",
"UefiTargetBootSourceOverride": "/0x31/0x33/0x01/0x01",
"HttpBootUri": "https://Contoso.lan/boot.iso"
},
"BootProgress": {
"LastBootTimeSeconds": 66,
"LastState": "OSRunning",
"LastStateTime": "2017-05-03T23:12:37-05:00",
"OemLastState": "OS foo running."
},
"TrustedModules": [
{
"FirmwareVersion": "1.13b",
"InterfaceType": "TPM1_2",
"Status": {
"State": "Enabled",
"Health": "OK"
}
}
],
"Oem": {
"Contoso": {
"@odata.type": "#Contoso.ComputerSystem",
"Name": "Contoso OEM system",
"ProductionLocation": {
"FacilityName": "PacWest Production Facility",
"Country": "USA"
}
},
"Chipwise": {
"@odata.type": "#Chipwise.ComputerSystem",
"Style": "Executive"
}
},
"BiosVersion": "P79 v1.45 (12/06/2017)",
"ProcessorSummary": {
"Count": 2,
"ProcessorFamily": "Multi-Core Intel(R) Xeon(R) processor 7xxx Series",
"Status": {
"State": "Enabled",
"Health": "OK",
"HealthRollup": "OK"
}
},
"MemorySummary": {
"TotalSystemMemoryGiB": 96,
"TotalSystemPersistentMemoryGiB": 0,
"MemoryMirroring": "None",
"Status": {
"State": "Enabled",
"Health": "OK",
"HealthRollup": "OK"
}
},
"Bios": {
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Bios"
},
"SecureBoot": {
"@odata.id": "/redfish/v1/Systems/437XR1138R2/SecureBoot"
},
"Processors": {
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Processors"
},
"Memory": {
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Memory"
},
"EthernetInterfaces": {
"@odata.id": "/redfish/v1/Systems/437XR1138R2/EthernetInterfaces"
},
"SimpleStorage": {
"@odata.id": "/redfish/v1/Systems/437XR1138R2/SimpleStorage"
},
"LogServices": {
"@odata.id": "/redfish/v1/Systems/437XR1138R2/LogServices"
},
"Links": {
"Chassis": [
{
"@odata.id": "/redfish/v1/Chassis/1U"
}
],
"Managers": [
{
"@odata.id": "/redfish/v1/Managers/BMC"
}
]
},
"Actions": {
"#ComputerSystem.Reset": {
"target": "/redfish/v1/Systems/437XR1138R2/Actions/ComputerSystem.Reset",
"ResetType@Redfish.AllowableValues": [
"On",
"ForceOff",
"GracefulShutdown",
"GracefulRestart",
"ForceRestart",
"Nmi",
"ForceOn",
"PushPowerButton"
],
"@Redfish.OperationApplyTimeSupport": {
"@odata.type": "#Settings.v1_2_0.OperationApplyTimeSupport",
"SupportedValues": [ "Immediate", "AtMaintenanceWindowStart" ],
"MaintenanceWindowStartTime": "2017-05-03T23:12:37-05:00",
"MaintenanceWindowDurationInSeconds": 600,
"MaintenanceWindowResource": {
"@odata.id": "/redfish/v1/Systems/437XR1138R2"
}
}
},
"Oem": {
"#Contoso.Reset": {
"target": "/redfish/v1/Systems/437XR1138R2/Oem/Contoso/Actions/Contoso.Reset"
}
}
},
"@Redfish.MaintenanceWindow": {
"@odata.type": "#Settings.v1_2_0.MaintenanceWindow",
"MaintenanceWindowDurationInSeconds": 1,
"MaintenanceWindowStartTime": "2016-03-07T14:44:30-05:05"
},
"@odata.context": "/redfish/v1/$metadata#ComputerSystem.ComputerSystem",
"@odata.id": "/redfish/v1/Systems/437XR1138R2",
"@Redfish.Copyright": "Copyright 2014-2016 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright."
}

View File

@@ -890,6 +890,33 @@ class SystemTestCase(base.TestCase):
self.assertEqual(
'/redfish/v1/Managers/BMC', actual_managers[0].path)
def test_managers_retry(self):
with open('sushy/tests/unit/json_samples/'
'system_managedby_missing_manager_present.json') as f:
settings_obj = json.load(f)
self.json_doc.update(settings_obj)
self.sys_inst._parse_attributes(self.json_doc)
# | GIVEN |
with open('sushy/tests/unit/json_samples/'
'manager.json') as f:
self.conn.get.return_value.json.return_value = json.load(f)
# | WHEN & THEN |
actual_managers = self.sys_inst.managers
self.assertIsInstance(actual_managers[0], manager.Manager)
self.assertEqual(
'/redfish/v1/Managers/BMC', actual_managers[0].path)
def test_managers_missing_ref(self):
# | GIVEN |
del self.json_doc['Links']['ManagedBy']
# | WHEN & THEN |
with self.assertRaisesRegex(
exceptions.MissingAttributeError, 'attribute Links/ManagedBy'):
self.sys_inst.managers
def test_chassis(self):
# | GIVEN |
with open('sushy/tests/unit/json_samples/'