2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-10-20 14:45:45 +00:00

Repair the asynchronous contracts around ipmi users and extended config

handle_users iterated get_users with async for while the same call is awaited
a few lines below, so listing the users collection, and creating a user,
raised a TypeError about a coroutine having no __aiter__. list_inventory in
the redfish plugin had the mirror of it, awaiting an async generator.

get_extended_bmc_configuration is called with hideadvanced but the ipmi chain
never accepted it, so the extra and extra_advanced resources raised a
TypeError; thread the argument through instead.

A user slot the bmc refuses to describe no longer takes the whole user list
with it: one MegaRAC slot answered Invalid data field for good after an
account was deleted, which broke every user operation.
This commit is contained in:
Markus Hilger
2026-08-13 18:09:18 +02:00
parent 6002b14f52
commit 6e95399528
6 changed files with 23 additions and 12 deletions
+12 -5
View File
@@ -859,9 +859,10 @@ class Command(object):
else:
raise Exception("Unrecognized data format " + repr(fetchdata))
async def get_extended_bmc_configuration(self):
async def get_extended_bmc_configuration(self, hideadvanced=True):
await self.oem_init()
return await self._oem.get_extended_bmc_configuration()
return await self._oem.get_extended_bmc_configuration(
hideadvanced=hideadvanced)
async def get_bmc_configuration(self):
await self.oem_init()
@@ -2037,9 +2038,15 @@ class Command(object):
names = {}
max_ids = await self.get_channel_max_user_count(channel)
for uid in range(1, max_ids + 1):
name = await self.get_user_name(uid=uid)
if await self._oem.is_valid(name):
names[uid] = await self.get_user(uid=uid, channel=channel)
# A single slot that the bmc refuses to describe must not take the
# whole user list with it, as some bmcs leave a slot in a state
# where reading it returns an error rather than an empty name
try:
name = await self.get_user_name(uid=uid)
if await self._oem.is_valid(name):
names[uid] = await self.get_user(uid=uid, channel=channel)
except exc.IpmiException:
continue
return names
async def create_user(self, uid, name, password, channel=None, callback=False,
+1 -1
View File
@@ -455,7 +455,7 @@ class OEMHandler(object):
"""
return False
async def get_extended_bmc_configuration(self):
async def get_extended_bmc_configuration(self, hideadvanced=True):
"""Get extended bmc configuration
In the case of potentially redundant/slow
@@ -1223,10 +1223,12 @@ class OEMHandler(generic.OEMHandler):
return {'height': self._fpc_variant & 0xf, 'slot': 0}
return await super(OEMHandler, self).get_description()
async def get_extended_bmc_configuration(self):
async def get_extended_bmc_configuration(self, hideadvanced=True):
if await self.has_xcc():
return await self.immhandler.get_extended_bmc_configuration()
return await super(OEMHandler, self).get_extended_bmc_configuration()
return await self.immhandler.get_extended_bmc_configuration(
hideadvanced=hideadvanced)
return await super(OEMHandler, self).get_extended_bmc_configuration(
hideadvanced=hideadvanced)
async def get_bmc_configuration(self):
if await self.has_xcc():
@@ -1026,7 +1026,7 @@ class XCCClient(IMMClient):
return {}
return {'height': int(dsc['u-height']), 'slot': int(dsc['slot'])}
async def get_extended_bmc_configuration(self):
async def get_extended_bmc_configuration(self, hideadvanced=True):
immsettings = await self.get_system_configuration(fetchimm=True)
for setting in list(immsettings):
if not setting.startswith('IMM.'):
@@ -808,7 +808,7 @@ class IpmiHandler:
privilege_level=user['privilege_level'])
# A list of users
await self.output.put(msg.ChildCollection('all'))
async for user in self.ipmicmd.get_users():
for user in await self.ipmicmd.get_users():
await self.output.put(msg.ChildCollection(user, candelete=True))
return
# List all users
@@ -881,8 +881,10 @@ class IpmiHandler:
await self.output.put(msg.ConfluentTargetTimeout(self.node))
async def list_inventory(self):
components = []
try:
components = await self.ipmicmd.get_inventory_descriptions()
async for component in self.ipmicmd.get_inventory_descriptions():
components.append(component)
except pygexc.IpmiException:
await self.output.put(msg.ConfluentTargetTimeout(self.node))
return