2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-08-25 08:06:46 +00:00

Name the firmware categories beyond core, adapters and disks

Firmware for a supply or a fan matched no fragment and so was called
core, and nothing could ever answer for misc.

Only the collections that mean one thing are matched by url.  A Storage
resource is the subsystem, so its firmware is the controller rather than
a drive, and a Processor is a cpu as readily as an accelerator, so that
one is decided by asking the processor what it is.
This commit is contained in:
Markus Hilger
2026-08-15 12:59:04 +02:00
parent 8c884e2ece
commit be1304e560
+46 -7
View File
@@ -1316,28 +1316,67 @@ class Command(object):
# A firmware inventory entry says what it belongs to with RelatedItem, so
# map the collections that turn up there onto the categories confluent asks
# for
# for. Only the collections that mean one thing: a Storage resource is the
# subsystem rather than a drive, and a Processor is a cpu as readily as an
# accelerator, so both are decided further down instead.
_fwcategorybyurl = (
('/Drives/', 'disks'),
('/Storage/', 'disks'),
('/PCIeDevices/', 'adapters'),
('/NetworkAdapters/', 'adapters'),
('/NetworkInterfaces/', 'adapters'),
('/Storage/', 'adapters'),
('/PowerSubsystem/', 'misc'),
('/PowerSupplies/', 'misc'),
('/ThermalSubsystem/', 'misc'),
('/Fans/', 'misc'),
('/Memory/', 'misc'),
)
def _fwcategory(self, fwi):
# The legacy chassis power and thermal documents, which are a whole path
# segment rather than a collection, so they are matched as one. A bare
# substring would also catch a chassis that merely happens to be called
# something like PowerShelf1.
_fwcategorybysegment = (
('Power', 'misc'),
('Thermal', 'misc'),
)
# What a Processor has to say it is before its firmware counts as a card in
# the machine rather than as part of the system
_acceleratortypes = ('GPU', 'FPGA', 'Accelerator', 'DSP')
async def _fwcategory(self, fwi):
"""Which category a firmware inventory entry belongs to.
Returns None when the entry gives nothing to judge by.
"""
related = fwi.get('RelatedItem', [])
for item in related:
url = item.get('@odata.id', '')
related = [x.get('@odata.id', '') for x in fwi.get('RelatedItem', [])]
for url in related:
for frag, category in self._fwcategorybyurl:
if frag in url:
return category
lastsegment = url.rstrip('/').rpartition('/')[2]
for segment, category in self._fwcategorybysegment:
if lastsegment == segment:
return category
if '/Processors/' in url:
return await self._processorcategory(url)
return 'core' if related else None
async def _processorcategory(self, url):
"""A cpu is system firmware, an accelerator is a card in the machine.
The url cannot tell them apart, so the processor is asked. A processor
that will not say counts as a cpu, which is the common case and the
answer this gave before the distinction was drawn.
"""
try:
procinfo = await self._do_web_request(url)
except exc.PyghmiException:
return 'core'
proctype = procinfo.get('ProcessorType', None)
return 'adapters' if proctype in self._acceleratortypes else 'core'
async def get_firmware(self, components=(), category=None):
self._fwnamemap = {}
oem = await self.oem()
@@ -1358,7 +1397,7 @@ class Command(object):
if res[0]]
labels = self._firmware_labels(results)
for res in results:
entries.append((self._fwcategory(res[0]),
entries.append((await self._fwcategory(res[0]),
self._extract_fwinfo(res, labels)))
for fwcategory, res in entries:
if res[0] is None: