2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-09-04 20:17:58 +00:00

Merge pull request #290 from Obihoernchen/fix/report-failures-not-crashes

Let a failed request report itself
This commit is contained in:
Jarrod Johnson
2026-09-02 10:16:16 -04:00
committed by GitHub
3 changed files with 36 additions and 7 deletions
@@ -147,8 +147,12 @@ def _eval_conditional(expression, cfg, setting):
class LenovoFirmwareConfig(object):
def __init__(self, xc, useipmi=True):
if not etree:
raise Exception("python-lxml and python-eficompressor required "
"for this function")
# Not a bare Exception. Confluent has no handler for one, so a
# missing optional dependency showed as "Unexpected Error" and hid
# the message below, which already names what to install.
raise pygexc.UnsupportedFunctionality(
"python-lxml and python-eficompressor required "
"for this function")
if useipmi:
self.connection = xc.ipmicmd
else:
@@ -1797,7 +1797,14 @@ class OEMHandler(object):
errmsg = ','.join(errmsg)
raise exc.RedfishError(errmsg)
except (ValueError, KeyError):
raise exc.PyghmiException(str(url) + ":" + res[0])
# Reached by an html 404 page, or anything else that is not
# the JSON error document. res[0] is bytes there, so building
# the message crashed and the caller saw that TypeError
# instead of the status and the body.
body = res[0]
if isinstance(body, bytes):
body = body.decode('utf-8', errors='replace')
raise exc.PyghmiException('{0}:{1}'.format(url, body))
if payload is None and method is None:
self._urlcache[url] = {
'contents': res[0],
@@ -1150,6 +1150,18 @@ class OEMHandler(generic.OEMHandler):
self.weblogging = False
return self._wc
async def wc_if_available(self):
"""The web client, or None where carrying on without it is meant.
Four inventory reads answer partially when the web interface is out of
reach, and used to say so by checking wc() for None. wc() refuses now,
so they ask here instead.
"""
try:
return await self.wc()
except pygexc.UnsupportedFunctionality:
return None
async def get_webclient(self, login=True):
wc = self.webclient.dupe()
wc.vintage = util._monotonic_time()
@@ -1179,6 +1191,12 @@ class OEMHandler(generic.OEMHandler):
wc.set_header('X-XSRF-TOKEN', cookie.value)
break
return wc
# Falling off the end returned None, which wc() handed to thirty
# call sites that use it unchecked. The status separates firmware
# with no web api, answering 404, from credentials it will not take.
raise pygexc.UnsupportedFunctionality(
'the XCC web interface, which this operation needs beside '
'Redfish, did not accept a login (HTTP {0})'.format(status))
async def grab_redfish_response_with_status(self, url, body=None, method=None):
wc = self.webclient
@@ -1818,7 +1836,7 @@ class OEMHandler(generic.OEMHandler):
if self.updating:
raise pygexc.TemporaryError(
'Cannot read extended inventory during firmware update')
wc = await self.wc()
wc = await self.wc_if_available()
if wc:
adapterdata = await wc.grab_json_response(self.ADP_URL)
if adapterdata:
@@ -1897,7 +1915,7 @@ class OEMHandler(generic.OEMHandler):
# mode 0 is firmware, 1 is hardware
storagedata = self.get_cached_data('lenovo_cached_storage')
if not storagedata:
wc = await self.wc()
wc = await self.wc_if_available()
if wc:
storagedata = await wc.grab_json_response(
'/api/function/raid_alldevices?params=storage_GetAllDisks')
@@ -1926,7 +1944,7 @@ class OEMHandler(generic.OEMHandler):
async def _get_cpu_inventory(self):
procdata = self.get_cached_data('lenovo_cached_proc')
if not procdata:
wc = await self.wc()
wc = await self.wc_if_available()
if wc:
procdata = await wc.grab_json_response(
'/api/dataset/imm_processors')
@@ -1944,7 +1962,7 @@ class OEMHandler(generic.OEMHandler):
async def _get_mem_inventory(self):
memdata = self.get_cached_data('lenovo_cached_memory')
if not memdata:
wc = await self.wc()
wc = await self.wc_if_available()
if wc:
memdata = await wc.grab_json_response(
'/api/dataset/imm_memory')