2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-10-15 08:12:04 +00:00

Fix OEM asynchronous operation dispatch

This commit is contained in:
Markus Hilger
2026-07-13 00:59:38 +02:00
parent 0165fc9935
commit b5c5f62789
8 changed files with 62 additions and 65 deletions
@@ -493,8 +493,7 @@ class OEMHandler(generic.OEMHandler):
if await self.has_tsm() or await self.has_ami() or await self.has_asrock():
# Thinkserver with TSM
if not self.oem_inventory_info:
async for desc in self._collect_tsm_inventory():
yield desc
await self._collect_tsm_inventory()
for compname in self.oem_inventory_info:
yield compname
elif await self.has_imm():
@@ -767,7 +766,7 @@ class OEMHandler(generic.OEMHandler):
except (AttributeError, KeyError, IndexError):
pass
if await self.has_xcc() and name and name.startswith('PSU '):
self.immhandler.augment_psu_info(fru, name)
await self.immhandler.augment_psu_info(fru, name)
if (await self.has_xcc() and 'memory_type' in fru
and fru['memory_type'] == 'Unknown'):
await self.immhandler.fetch_dimm(name, fru)
@@ -1028,14 +1027,14 @@ class OEMHandler(generic.OEMHandler):
async def add_extra_net_configuration(self, netdata, channel=None):
if await self.has_tsm():
ipv6_addr = await self.ipmicmd.raw_command(
ipv6_addr = (await self.ipmicmd.raw_command(
netfn=0x0c, command=0x02,
data=(0x01, 0xc5, 0x00, 0x00))["data"][1:]
data=(0x01, 0xc5, 0x00, 0x00)))['data'][1:]
if not ipv6_addr:
return
rspdata = await self.ipmicmd.raw_command(
rspdata = (await self.ipmicmd.raw_command(
netfn=0xc, command=0x02,
data=(0x1, 0xc6, 0, 0))['data']
data=(0x1, 0xc6, 0, 0)))['data']
ipv6_prefix_ba = bytearray(rspdata)
ipv6_prefix = ipv6_prefix_ba[1]
+17 -17
View File
@@ -839,7 +839,7 @@ class IMMClient(object):
hwmap[aname] = bdata
self.datacache['lenovo_cached_hwmap'] = (hwmap,
util._monotonic_time())
self.weblogout()
await self.weblogout()
return hwmap
async def get_firmware_inventory(self, bmcver, components, category):
@@ -1434,7 +1434,7 @@ class XCCClient(IMMClient):
if controller != disk.id[0]:
raise pygexc.UnsupportedFunctionality(
'Cannot span arrays across controllers')
raidmap = self._raid_number_map(controller)
raidmap = await self._raid_number_map(controller)
if not raidmap:
raise pygexc.InvalidParameterValue(
'There are no available drives for a new array')
@@ -1487,21 +1487,21 @@ class XCCClient(IMMClient):
# TODO(): adding new volume to existing array would be here
pass
def _make_jbod(self, disk, realcfg):
async def _make_jbod(self, disk, realcfg):
currstatus = self._get_status(disk, realcfg)
if currstatus.lower() == 'jbod':
return
self._make_available(disk, realcfg)
self._set_drive_state(disk, 16)
await self._make_available(disk, realcfg)
await self._set_drive_state(disk, 16)
def _make_global_hotspare(self, disk, realcfg):
async def _make_global_hotspare(self, disk, realcfg):
currstatus = self._get_status(disk, realcfg)
if currstatus.lower() == 'global hot spare':
return
self._make_available(disk, realcfg)
self._set_drive_state(disk, 1)
await self._make_available(disk, realcfg)
await self._set_drive_state(disk, 1)
def _make_available(self, disk, realcfg):
async def _make_available(self, disk, realcfg):
# 8 if jbod, 4 if hotspare.., leave alone if already...
currstatus = self._get_status(disk, realcfg)
newstate = None
@@ -1511,7 +1511,7 @@ class XCCClient(IMMClient):
newstate = 4
elif currstatus.lower() == 'jbod':
newstate = 8
self._set_drive_state(disk, newstate)
await self._set_drive_state(disk, newstate)
def _get_status(self, disk, realcfg):
for cfgdisk in realcfg.disks:
@@ -1536,7 +1536,7 @@ class XCCClient(IMMClient):
wc = await self.wc()
rsp = await wc.grab_json_response(
'/api/function', {'raidlink_ClearRaidConf': '1'})
self.weblogout()
await self.weblogout()
if rsp['return'] != 0:
raise Exception('Unexpected return to clear config: ' + repr(rsp))
@@ -1560,10 +1560,10 @@ class XCCClient(IMMClient):
if rsp.get('return', -1) != 0:
raise Exception(
'Unexpected return to volume deletion: ' + repr(rsp))
self._wait_storage_async()
await self._wait_storage_async()
for disk in cfgspec.disks:
await self._make_available(disk, realcfg)
self.weblogout()
await self.weblogout()
async def apply_storage_configuration(self, cfgspec):
realcfg = await self.get_storage_configuration(False)
@@ -2168,7 +2168,7 @@ class XCCClient(IMMClient):
retry = 3
while not complete and retry > 0:
try:
pgress, status = self.grab_redfish_response_with_status(
pgress, status = await self.grab_redfish_response_with_status(
monitorurl)
except socket.timeout:
pgress = None
@@ -2205,10 +2205,10 @@ class XCCClient(IMMClient):
return 'complete'
return 'pending'
finally:
self.grab_redfish_response_with_status(
await self.grab_redfish_response_with_status(
'/redfish/v1/UpdateService',
{'HttpPushUriTargetsBusy': False}, method='PATCH')
self.grab_redfish_response_with_status(
await self.grab_redfish_response_with_status(
'/redfish/v1/UpdateService',
{'HttpPushUriTargets': []}, method='PATCH')
@@ -2410,7 +2410,7 @@ class XCCClient(IMMClient):
errmsg = repr(rsp) if rsp else wc.lastjsonerror
raise Exception(
'Unexpected result from PCI select: ' + errmsg)
self.set_property('/v2/ibmc/uefi/force-inventory', 1)
await self.set_property('/v2/ibmc/uefi/force-inventory', 1)
else:
await self._refresh_token()
rsp = await wc.grab_json_response(
@@ -671,14 +671,14 @@ class SMMClient(object):
for bayn in range(1, numbays + 1):
if fnmatch.fnmatch('bay{0}_user_cap'.format(bayn),
key.lower()):
self.set_bay_cap(bayn, changeset[key]['value'])
await self.set_bay_cap(bayn, changeset[key]['value'])
if fnmatch.fnmatch(
'bay{0}_user_cap_active'.format(bayn), key.lower()):
self.set_bay_cap_active(bayn, changeset[key]['value'])
await self.set_bay_cap_active(bayn, changeset[key]['value'])
if fnmatch.fnmatch('chassis_user_cap', key.lower()):
self.set_bay_cap(numbays + 1, changeset[key]['value'])
await self.set_bay_cap(numbays + 1, changeset[key]['value'])
if fnmatch.fnmatch('chassis_user_cap_active', key.lower()):
self.set_bay_cap_active(numbays + 1, changeset[key]['value'])
await self.set_bay_cap_active(numbays + 1, changeset[key]['value'])
if fnmatch.fnmatch('fanspeed', key.lower()):
for mode in self.fanmodes:
byteval = mode
@@ -816,10 +816,10 @@ class SMMClient(object):
async def process_fru(self, fru):
smmv1 = self.smm_variant & 0xf0 == 0
# TODO(jjohnson2): can also get EIOM, SMM, and riser data if warranted
snum = bytes(await self.ipmicmd.raw_command(
netfn=0x32, command=0xb0, data=(5, 1))['data'][:])
mnum = bytes(await self.ipmicmd.raw_command(
netfn=0x32, command=0xb0, data=(5, 0))['data'][:])
snum = bytes((await self.ipmicmd.raw_command(
netfn=0x32, command=0xb0, data=(5, 1)))['data'][:])
mnum = bytes((await self.ipmicmd.raw_command(
netfn=0x32, command=0xb0, data=(5, 0)))['data'][:])
if not smmv1:
snum = snum[2:]
mnum = mnum[2:]
@@ -1115,5 +1115,5 @@ class SMMClient(object):
async def wc(self):
if (not self._wc or self._wc.broken
or self._wc.vintage < util._monotonic_time() + 30):
self._wc = await self.get_webclient()
self._wc = self.get_webclient()
return self._wc
+7 -7
View File
@@ -1035,7 +1035,7 @@ class Command(object):
'Address': static_gateway,
}]
if patch:
nicurl = self._get_bmc_nic_url(name)
nicurl = await self._get_bmc_nic_url(name)
await self._do_web_request(nicurl, patch, 'PATCH')
async def set_net_configuration(self, ipv4_address=None, ipv4_configuration=None,
@@ -1458,22 +1458,22 @@ class Command(object):
del self.wc.stdheaders['Authorization']
return
for vmurl in vmurls:
vminfo = self._do_web_request(vmurl, cache=False)
vminfo = await self._do_web_request(vmurl, cache=False)
if vminfo.get('ConnectedVia', None) != 'NotConnected':
continue
inserturl = vminfo.get(
'Actions', {}).get(
'#VirtualMedia.InsertMedia', {}).get('target', None)
if inserturl:
self._do_web_request(inserturl, {'Image': url})
await self._do_web_request(inserturl, {'Image': url})
else:
try:
self._do_web_request(vmurl,
{'Image': url, 'Inserted': True},
'PATCH')
await self._do_web_request(vmurl,
{'Image': url, 'Inserted': True},
'PATCH')
except exc.RedfishError as re:
if re.msgid.endswith(u'PropertyUnknown'):
self._do_web_request(vmurl, {'Image': url}, 'PATCH')
await self._do_web_request(vmurl, {'Image': url}, 'PATCH')
else:
raise
break
@@ -17,8 +17,8 @@ import aiohmi.redfish.oem.generic as generic
class OEMHandler(generic.OEMHandler):
def set_bootdev(self, bootdev, persist=False, uefiboot=None,
fishclient=None):
async def set_bootdev(self, bootdev, persist=False, uefiboot=None,
fishclient=None):
# gleaned from web console, under configuration, system settings,
# hardware, first boot device. iDrac presumes that the standard
# explicitly refers only to physical devices. I think the intent
@@ -26,8 +26,8 @@ class OEMHandler(generic.OEMHandler):
# the 'physical' standard to the vFDD/VCD-DVD seen in the idrac
# web gui
if bootdev not in ('floppy', 'cd'):
return super(OEMHandler, self).set_bootdev(bootdev, persist,
uefiboot, fishclient)
return await super(OEMHandler, self).set_bootdev(bootdev, persist,
uefiboot, fishclient)
payload = {'Attributes': {}}
if persist:
payload['Attributes']['ServerBoot.1.BootOnce'] = 'Disabled'
@@ -37,7 +37,7 @@ class OEMHandler(generic.OEMHandler):
payload['Attributes']['ServerBoot.1.FirstBootDevice'] = 'vFDD'
elif bootdev == 'cd':
payload['Attributes']['ServerBoot.1.FirstBootDevice'] = 'VCD-DVD'
fishclient._do_web_request(
await fishclient._do_web_request(
'/redfish/v1/Managers/iDRAC.Embedded.1/Attributes',
payload, method='PATCH')
return {'bootdev': bootdev}
@@ -186,7 +186,7 @@ class TsmHandler(generic.OEMHandler):
if 'dns_domain'.startswith(key.lower()):
dnschgs['domain_name'] = currval
if 'password_complexity'.startswith(key.lower()):
self._set_pass_complexity(currval, wc)
await self._set_pass_complexity(currval, wc)
if 'password_login_failures'.startswith(key.lower()):
await self._set_pass_lockout(currval, wc)
if dnschgs:
@@ -184,7 +184,7 @@ class OEMHandler(generic.OEMHandler):
try:
self.fwo = await self.fwc.get_fw_options(fetchimm=fetchimm)
except config.Unsupported:
return super(OEMHandler, self).get_system_configuration(
return await super(OEMHandler, self).get_system_configuration(
hideadvanced, fishclient)
except Exception:
raise Exception('%s failed to retrieve UEFI configuration'
@@ -831,7 +831,7 @@ class OEMHandler(generic.OEMHandler):
wc.set_header('X-XSRF-TOKEN', cookie.value)
wc.vintage = util._monotonic_time()
def _make_available(self, disk, realcfg):
async def _make_available(self, disk, realcfg):
# 8 if jbod, 4 if hotspare.., leave alone if already...
currstatus = self._get_status(disk, realcfg)
newstate = None
@@ -841,21 +841,21 @@ class OEMHandler(generic.OEMHandler):
newstate = 4
elif currstatus.lower() == 'jbod':
newstate = 8
self._set_drive_state(disk, newstate)
await self._set_drive_state(disk, newstate)
def _make_jbod(self, disk, realcfg):
async def _make_jbod(self, disk, realcfg):
currstatus = self._get_status(disk, realcfg)
if currstatus.lower() == 'jbod':
return
self._make_available(disk, realcfg)
self._set_drive_state(disk, 16)
await self._make_available(disk, realcfg)
await self._set_drive_state(disk, 16)
def _make_global_hotspare(self, disk, realcfg):
async def _make_global_hotspare(self, disk, realcfg):
currstatus = self._get_status(disk, realcfg)
if currstatus.lower() == 'global hot spare':
return
self._make_available(disk, realcfg)
self._set_drive_state(disk, 1)
await self._make_available(disk, realcfg)
await self._set_drive_state(disk, 1)
def _get_status(self, disk, realcfg):
for cfgdisk in realcfg.disks:
@@ -978,7 +978,7 @@ class OEMHandler(generic.OEMHandler):
pass
async def _create_array(self, pool):
params = self._parse_array_spec(pool)
params = await self._parse_array_spec(pool)
cid = params['controller'].split(',')[0]
cslotno = params['controller'].split(',')[1]
url = '/api/function/raid_conf?params=raidlink_GetDefaultVolProp'
@@ -1443,7 +1443,7 @@ class OEMHandler(generic.OEMHandler):
async def update_firmware_backend(self, filename, data=None, progress=None,
bank=None):
self._refresh_token()
await self._refresh_token()
wc = await self.wc()
rsv = await wc.grab_json_response('/api/providers/fwupdate', json.dumps(
{'UPD_WebReserve': 1}))
@@ -1470,7 +1470,7 @@ class OEMHandler(generic.OEMHandler):
raise Exception('File is larger than supported')
raise Exception('Unexpected result:' + repr(rsp))
uploadstate = rsp['state']
self._refresh_token()
await self._refresh_token()
while uploadstate != 'done':
rsp = await wc.grab_json_response(
'/upload/progress?X-Progress-ID={0}'.format(xid))
@@ -432,7 +432,7 @@ class OEMHandler(generic.OEMHandler):
await self._make_available(disk, realcfg)
self._urlcache.clear()
def _parse_array_spec(self, arrayspec):
async def _parse_array_spec(self, arrayspec):
controller = None
if arrayspec.disks:
for disk in list(arrayspec.disks) + list(arrayspec.hotspares):
@@ -441,7 +441,7 @@ class OEMHandler(generic.OEMHandler):
if controller != disk.id[0]:
raise pygexc.UnsupportedFunctionality(
'Cannot span arrays across controllers')
raidmap = self._raid_number_map(controller)
raidmap = await self._raid_number_map(controller)
if not raidmap:
raise pygexc.InvalidParameterValue(
'No RAID Type supported on this controller')
@@ -511,7 +511,7 @@ class OEMHandler(generic.OEMHandler):
return themap
async def _create_array(self, pool):
params = self._parse_array_spec(pool)
params = await self._parse_array_spec(pool)
cid = params['controller'].split(',')[0]
c_capabilities, code = await self.webclient.grab_json_response_with_status(
f'/redfish/v1/Systems/1/Storage/{cid}/Volumes/Capabilities')
@@ -906,7 +906,7 @@ class OEMHandler(generic.OEMHandler):
cache=False)
rawsettings = rawsettings.get('Attributes', {})
pendingsettings = {}
ret = self._set_redfish_settings(
ret = await self._set_redfish_settings(
changeset, fishclient, currsettings, rawsettings,
pendingsettings, self.lenovobmcattrdeps, reginfo,
'/redfish/v1/Managers/1/Oem/Lenovo/BMCSettings')
@@ -1039,7 +1039,7 @@ class OEMHandler(generic.OEMHandler):
if usbsettings:
await self.apply_usb_configuration(usbsettings)
if bmchangeset:
self._set_xcc3_settings(bmchangeset, self)
await self._set_xcc3_settings(bmchangeset, self)
async def apply_usb_configuration(self, usbsettings):
bmcattribs = {}
@@ -1220,5 +1220,3 @@ class OEMHandler(generic.OEMHandler):
'Name': 'HPM-FPGA Pending',
'build': pendinghpm}
raise pygexc.BypassGenericBehavior()