2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-08-03 16:07:00 +00:00

Await NextScale SMM settings operations

The SMM hostname, domain, and NTP helpers looked synchronous even though their web transport is asynchronous. Removing awaits in the Lenovo OEM handler therefore returned unresolved coroutine work instead of completed settings results.

Convert the SMM settings and logout helpers to the asynchronous web interface, validate HTTP status responses, and await each operation from the OEM handler so callers only observe completed results.
This commit is contained in:
Markus Hilger
2026-07-13 16:05:53 +02:00
parent fbbeda6c86
commit 8817ee6deb
2 changed files with 65 additions and 69 deletions
@@ -360,7 +360,7 @@ class OEMHandler(generic.OEMHandler):
srvs.append(ntpres['data'][129:257].rstrip('\x00'))
return srvs
if await self.is_fpc():
return self.smmhandler.get_ntp_servers()
return await self.smmhandler.get_ntp_servers()
if self.has_tsma:
return await self.tsmahandler.get_ntp_servers()
return ()
@@ -375,7 +375,7 @@ class OEMHandler(generic.OEMHandler):
netfn=0x32, command=0xa8, data=(3, 0), timeout=15)
return True
if await self.is_fpc():
self.smmhandler.set_ntp_enabled(enabled)
await self.smmhandler.set_ntp_enabled(enabled)
return True
if self.has_tsma:
await self.tsmahandler.set_ntp_enabled(enabled)
@@ -393,7 +393,7 @@ class OEMHandler(generic.OEMHandler):
if not 0 <= index <= 2:
raise pygexc.InvalidParameterValue(
'SMM supports indexes 0 through 2')
self.smmhandler.set_ntp_server(server, index)
await self.smmhandler.set_ntp_server(server, index)
return True
elif self.has_tsma:
if not (0 <= index <= 1):
@@ -940,7 +940,7 @@ class OEMHandler(generic.OEMHandler):
name += rsp['data'][:]
return name.rstrip('\x00')
elif await self.is_fpc():
return self.smmhandler.get_domain()
return await self.smmhandler.get_domain()
async def set_oem_domain_name(self, name):
if await self.has_tsm():
@@ -959,20 +959,20 @@ class OEMHandler(generic.OEMHandler):
await self._restart_dns()
return
elif await self.is_fpc():
self.smmhandler.set_domain(name)
await self.smmhandler.set_domain(name)
async def set_hostname(self, hostname):
if await self.has_xcc():
return await self.immhandler.set_hostname(hostname)
elif await self.is_fpc():
return self.smmhandler.set_hostname(hostname)
return await self.smmhandler.set_hostname(hostname)
return await super(OEMHandler, self).set_hostname(hostname)
async def get_hostname(self):
if await self.has_xcc():
return await self.immhandler.get_hostname()
elif await self.is_fpc():
return self.smmhandler.get_hostname()
return await self.smmhandler.get_hostname()
return await super(OEMHandler, self).get_hostname()
""" Gets a remote console launcher for a Lenovo ThinkServer.
@@ -887,90 +887,84 @@ class SMMClient(object):
wc.set_header('ST2', wc.st2)
return wc
def set_hostname(self, hostname):
wc = self.wc
wc.request('POST', '/data', 'set=hostname:' + hostname)
rsp = wc.getresponse()
if rsp.status != 200:
raise Exception(rsp.read())
rsp.read()
self.logout()
async def set_hostname(self, hostname):
wc = await self.wc()
rsp, status, _ = await wc.grab_response_with_status('/data', 'set=hostname:' + hostname)
if status != 200:
raise Exception(rsp)
await self.logout()
def get_hostname(self):
currinfo = self.get_netinfo()
self.logout()
async def get_hostname(self):
currinfo = await self.get_netinfo()
await self.logout()
for data in currinfo.find('netConfig').findall('hostname'):
return data.text
def get_netinfo(self):
wc = self.wc
wc.request('POST', '/data', 'get=hostname')
rsp = wc.getresponse()
data = rsp.read()
if rsp.status == 400:
wc.request('POST', '/data?get=hostname', '')
rsp = wc.getresponse()
data = rsp.read()
if rsp.status != 200:
async def get_netinfo(self):
wc = await self.wc()
data, status, _ = await wc.grab_response_with_status('/data', 'get=hostname')
if status == 400:
data, status, _ = await wc.grab_response_with_status('/data?get=hostname', '')
if status != 200:
raise Exception(data)
currinfo = fromstring(data)
return currinfo
def set_domain(self, domain):
wc = self.wc
wc.request('POST', '/data', 'set=dnsDomain:' + domain)
rsp = wc.getresponse()
if rsp.status != 200:
raise Exception(rsp.read())
rsp.read()
self.logout()
async def set_domain(self, domain):
wc = await self.wc()
rsp, status, _ = await wc.grab_response_with_status('/data', 'set=dnsDomain:' + domain)
if status != 200:
raise Exception(rsp)
await self.logout()
def get_domain(self):
currinfo = self.get_netinfo()
self.logout()
async def get_domain(self):
currinfo = await self.get_netinfo()
await self.logout()
for data in currinfo.find('netConfig').findall('dnsDomain'):
return data.text
def get_ntp_enabled(self, variant):
wc = self.wc
wc.request('POST', '/data', 'get=ntpOpMode')
rsp = wc.getresponse()
info = fromstring(rsp.read())
self.logout()
async def get_ntp_enabled(self, variant):
wc = await self.wc()
rsp, status, _ = await wc.grab_response_with_status('/data', 'get=ntpOpMode')
if status != 200:
raise Exception(rsp)
info = fromstring(rsp)
await self.logout()
for data in info.findall('ntpOpMode'):
return data.text == '1'
def set_ntp_enabled(self, enabled):
wc = self.wc
wc.request('POST', '/data', 'set=ntpOpMode:{0}'.format(
async def set_ntp_enabled(self, enabled):
wc = await self.wc()
result, status, _ = await wc.grab_response_with_status('/data', 'set=ntpOpMode:{0}'.format(
1 if enabled else 0))
rsp = wc.getresponse()
result = rsp.read()
if status != 200:
raise Exception(result)
if not isinstance(result, str):
result = result.decode('utf8')
self.logout()
await self.logout()
if '<status>ok</status>' not in result:
raise Exception("Unrecognized result: " + result)
def set_ntp_server(self, server, index):
wc = self.wc
wc.request('POST', '/data', 'set=ntpServer{0}:{1}'.format(
async def set_ntp_server(self, server, index):
wc = await self.wc()
result, status, _ = await wc.grab_response_with_status('/data', 'set=ntpServer{0}:{1}'.format(
index + 1, server))
rsp = wc.getresponse()
result = rsp.read()
if status != 200:
raise Exception(result)
if not isinstance(result, str):
result = result.decode('utf8')
if '<status>ok</status>' not in result:
raise Exception("Unrecognized result: " + result)
self.logout()
await self.logout()
return True
def get_ntp_servers(self):
wc = self.wc
wc.request(
'POST', '/data', 'get=ntpServer1,ntpServer2,ntpServer3')
rsp = wc.getresponse()
result = fromstring(rsp.read())
async def get_ntp_servers(self):
wc = await self.wc()
rsp, status, _ = await wc.grab_response_with_status(
'/data', 'get=ntpServer1,ntpServer2,ntpServer3')
if status != 200:
raise Exception(rsp)
result = fromstring(rsp)
srvs = []
for data in result.findall('ntpServer1'):
srvs.append(data.text)
@@ -978,7 +972,7 @@ class SMMClient(object):
srvs.append(data.text)
for data in result.findall('ntpServer3'):
srvs.append(data.text)
self.logout()
await self.logout()
return srvs
async def update_firmware(self, filename, data=None, progress=None, bank=None):
@@ -1095,12 +1089,14 @@ class SMMClient(object):
b' \x00\xff').decode('utf8'))
return psui
def logout(self):
wc = self.wc
wc.request('POST', '/data/logout', None)
rsp = wc.getresponse()
rsp.read()
async def logout(self):
wc = self._wc
self._wc = None
if wc is None:
return
rsp, status, _ = await wc.grab_response_with_status('/data/logout', None, method='POST')
if status != 200:
raise Exception(rsp)
async def wc(self):
if (not self._wc or (self._wc.vintage