2
0
mirror of https://opendev.org/x/pyghmi synced 2026-01-11 18:52:33 +00:00

Enhancements for multi-system, multi-manager

Allow OEMs to describe the 'core'
system and manager.

In systems that start manifesting components as
managers and systems in their own right,
allow OEM to indicate which is the 'real' one.

Usually, extra Managers and Systems are something that
has been modeled as such, but from a usual user perspective are not
what they would consider BMCs
and systems.

Change-Id: Ib04e146a7fb0e988dac94c148005e07e2b487b12
This commit is contained in:
Jarrod Johnson
2025-10-08 09:03:36 -04:00
parent e0174b79bc
commit 7b6c703c9f
5 changed files with 75 additions and 47 deletions

View File

@@ -188,43 +188,11 @@ class Command(object):
self._varsensormap = {}
self.powerurl = None
self.sysurl = None
if 'Managers' in overview:
bmcoll = systems = overview['Managers']['@odata.id']
res = self.wc.grab_json_response_with_status(bmcoll)
if res[1] == 401:
raise exc.PyghmiException('Access Denied')
elif res[1] < 200 or res[1] >= 300:
raise exc.PyghmiException(repr(res[0]))
bmcs = res[0]['Members']
if len(bmcs) == 1:
self._varbmcurl = bmcs[0]['@odata.id']
tmpoem = oem.get_oem_handler({}, sysurl, self.wc, self._urlcache, self,
rootinfo=overview)
self._varbmcurl = tmpoem.get_default_mgrurl()
if 'Systems' in overview:
systems = overview['Systems']['@odata.id']
res = self.wc.grab_json_response_with_status(systems)
if res[1] == 401:
raise exc.PyghmiException('Access Denied')
elif res[1] < 200 or res[1] >= 300:
raise exc.PyghmiException(repr(res[0]))
members = res[0]
systems = members['Members']
if sysurl:
for system in systems:
if system['@odata.id'] == sysurl or system['@odata.id'].split('/')[-1] == sysurl:
self.sysurl = system['@odata.id']
break
else:
raise exc.PyghmiException(
'Specified sysurl not found: {0}'.format(sysurl))
else:
if len(systems) > 1:
systems = [x for x in systems if 'DPU' not in x['@odata.id']]
if len(systems) > 1:
raise exc.PyghmiException(
'Multi system manager, sysurl is required parameter')
if len(systems):
self.sysurl = systems[0]['@odata.id']
else:
self.sysurl = None
self.sysurl = tmpoem.get_default_sysurl()
self.powerurl = self.sysinfo.get('Actions', {}).get(
'#ComputerSystem.Reset', {}).get('target', None)

View File

@@ -15,6 +15,6 @@
from pyghmi.redfish.oem.dell import idrac
def get_handler(sysinfo, sysurl, webclient, cache, cmd):
def get_handler(sysinfo, sysurl, webclient, cache, cmd, rootinfo={}):
return idrac.OEMHandler(sysinfo, sysurl, webclient, cache,
gpool=cmd._gpool)

View File

@@ -188,17 +188,66 @@ class OEMHandler(object):
hostnic = None
usegenericsensors = True
def __init__(self, sysinfo, sysurl, webclient, cache, gpool=None):
def __init__(self, sysinfo, sysurl, webclient, cache, gpool=None, rootinfo={}):
self._gpool = gpool
self._varsysinfo = sysinfo
self._varsysurl = sysurl
self._urlcache = cache
self.webclient = webclient
self._hwnamemap = {}
self._rootinfo = rootinfo
if not self._rootinfo:
self._rootinfo = self.webclient.grab_json_response(
'/redfish/v1/')
self._varbmcurl = None
self._varsysurl = sysurl
def get_screenshot(self, outfile):
raise exc.UnsupportedFunctionality(
'Retrieving screenshot is not implemented for this platform')
def get_default_mgrurl(self):
if not self._varbmcurl and 'Managers' in self._rootinfo:
bmcoll = self._rootinfo['Managers']['@odata.id']
res = self.webclient.grab_json_response_with_status(bmcoll)
if res[1] == 401:
raise exc.PyghmiException('Access Denied')
elif res[1] < 200 or res[1] >= 300:
raise exc.PyghmiException(repr(res[0]))
bmcs = res[0]['Members']
if len(bmcs) == 1:
self._varbmcurl = bmcs[0]['@odata.id']
return self._varbmcurl
def get_default_sysurl(self):
if not self._varsysurl and 'Systems' in self._rootinfo:
systems = self._rootinfo['Systems']['@odata.id']
res = self.webclient.grab_json_response_with_status(systems)
if res[1] == 401:
raise exc.PyghmiException('Access Denied')
elif res[1] < 200 or res[1] >= 300:
raise exc.PyghmiException(repr(res[0]))
members = res[0]
systems = members['Members']
if self._varsysurl:
for system in systems:
if system['@odata.id'] == self._varsysurl or system['@odata.id'].split('/')[-1] == self._varsysurl:
self._varsysurl = system['@odata.id']
break
else:
raise exc.PyghmiException(
'Specified sysurl not found: {0}'.format(self._varsysurl))
else:
if len(systems) > 1:
systems = [x for x in systems if 'DPU' not in x['@odata.id']]
if len(systems) > 1:
raise exc.PyghmiException(
'Multi system manager, sysurl is required parameter')
if len(systems):
self._varsysurl = systems[0]['@odata.id']
else:
self._varsysurl = None
return self._varsysurl
def supports_expand(self, url):
# Unfortunately, the state of expand in redfish is pretty dicey,

View File

@@ -18,19 +18,27 @@ from pyghmi.redfish.oem.lenovo import xcc
from pyghmi.redfish.oem.lenovo import xcc3
from pyghmi.redfish.oem.lenovo import smm3
def get_handler(sysinfo, sysurl, webclient, cache, cmd):
def get_handler(sysinfo, sysurl, webclient, cache, cmd, rootinfo={}):
if not sysinfo: # we are before establishing there is one system, and one manager...
systems, status = webclient.grab_json_response_with_status('/redfish/v1/Systems')
if status == 200:
for system in systems.get('Members', []):
if system.get('@odata.id', '').endswith('/1'):
sysurl = system['@odata.id']
sysinfo, status = webclient.grab_json_response_with_status(sysurl)
break
leninf = sysinfo.get('Oem', {}).get('Lenovo', {})
mgrinfo = {}
if leninf:
mgrinf, status = webclient.grab_json_response_with_status('/redfish/v1/Managers/1')
mgrinfo, status = webclient.grab_json_response_with_status('/redfish/v1/Managers/1')
if status != 200:
mgrinfo = {}
if not leninf:
bmcinfo = cmd.bmcinfo
if 'Ami' in bmcinfo.get('Oem', {}):
return tsma.TsmHandler(sysinfo, sysurl, webclient, cache)
elif 'xclarity controller' in mgrinf.get('Model', '').lower():
if mgrinf['Model'].endswith('3'):
elif 'xclarity controller' in mgrinfo.get('Model', '').lower():
if mgrinfo['Model'].endswith('3'):
return xcc3.OEMHandler(sysinfo, sysurl, webclient, cache,
gpool=cmd._gpool)
else:

View File

@@ -22,18 +22,21 @@ OEMMAP = {
}
def get_oem_handler(sysinfo, sysurl, webclient, cache, cmd):
def get_oem_handler(sysinfo, sysurl, webclient, cache, cmd, rootinfo={}):
if rootinfo.get('Vendor', None) in OEMMAP:
return OEMMAP[rootinfo['Vendor']].get_handler(sysinfo, sysurl,
webclient, cache, cmd, rootinfo)
for oem in sysinfo.get('Oem', {}):
if oem in OEMMAP:
return OEMMAP[oem].get_handler(sysinfo, sysurl, webclient, cache,
cmd)
cmd, rootinfo)
for oem in sysinfo.get('Links', {}).get('OEM', []):
if oem in OEMMAP:
return OEMMAP[oem].get_handler(sysinfo, sysurl, webclient, cache,
cmd)
cmd, rootinfo)
bmcinfo = cmd.bmcinfo
for oem in bmcinfo.get('Oem', {}):
if oem in OEMMAP:
return OEMMAP[oem].get_handler(sysinfo, sysurl, webclient, cache,
cmd)
return generic.OEMHandler(sysinfo, sysurl, webclient, cache, cmd._gpool)
cmd, rootinfo)
return generic.OEMHandler(sysinfo, sysurl, webclient, cache, cmd._gpool, rootinfo)