2
0
mirror of https://opendev.org/x/pyghmi synced 2025-08-23 11:30:18 +00:00

Fetch diagnostic data

Implement a function to call into whatever the appropriate method
for a vendor to provide diagnostic/support/service data to send
to their support staff.

Change-Id: I1e1d73ec0133aa413cb3d9d44101e7f22cb1a398
This commit is contained in:
Jarrod Johnson
2018-08-22 15:08:50 -04:00
parent 41ad976be7
commit 2b28ef74be
5 changed files with 80 additions and 0 deletions

View File

@@ -431,6 +431,10 @@ class Command(object):
rsp['data'] = buffer(rsp['data'])
return rsp
def get_diagnostic_data(self, savefile, progress=None):
self.oem_init()
return self._oem.get_diagnostic_data(savefile)
def get_description(self):
"""Get physical attributes for the system, e.g. for GUI use

View File

@@ -85,6 +85,18 @@ class OEMHandler(object):
"""
return ()
def get_diagnostic_data(self, savefile, progress=None):
"""Download diagnostic data about target to a file
This should be a payload that the vendor's support team can use
to do diagnostics.
:param savefile: File object or filename to save to
:param progress: Callback to be informed about progress
:return:
"""
raise exc.UnsupportedFunctionality(
'Do not know how to get diagnostic data for this platform')
def get_sensor_data(self):
"""Get OEM sensor data

View File

@@ -607,6 +607,10 @@ class OEMHandler(generic.OEMHandler):
self._fpc_variant)
return super(OEMHandler, self).get_oem_firmware(bmcver)
def get_diagnostic_data(self, savefile, progress):
if self.has_xcc:
return self.immhandler.get_diagnostic_data(savefile, progress)
def get_oem_capping_enabled(self):
if self.has_tsm:
rsp = self.ipmicmd.xraw_command(netfn=0x3a, command=0x1b,

View File

@@ -738,6 +738,33 @@ class XCCClient(IMMClient):
self._parse_storage_cfgspec(pool)
return True
def get_diagnostic_data(self, savefile, progress=None):
self.wc.grab_json_response('/api/providers/ffdc',
{'Generate_FFDC': 1})
percent = 0
while percent != 100:
ipmisession.Session.pause(3)
result = self.wc.grab_json_response('/api/providers/ffdc',
{'Generate_FFDC_status': 1})
self._refresh_token()
if progress:
progress({'phase': 'generate', 'progress': float(percent)})
percent = result['progress']
while 'FileName' not in result:
result = self.wc.grab_json_response('/api/providers/ffdc',
{'Generate_FFDC_status': 1})
url = '/ffdc/{0}'.format(result['FileName'])
fd = webclient.FileDownloader(self.wc, url, savefile)
fd.start()
while fd.isAlive():
fd.join(1)
if progress and self.wc.get_download_progress():
progress({'phase': 'download',
'progress': 100 * self.wc.get_download_progress()})
self._refresh_token()
if progress:
progress({'phase': 'complete'})
def _parse_array_spec(self, arrayspec):
controller = None
if arrayspec.disks:

View File

@@ -59,6 +59,17 @@ class FileUploader(threading.Thread):
self.formname, otherfields=self.otherfields)
class FileDownloader(threading.Thread):
def __init__(self, webclient, url, savefile):
self.wc = webclient
self.url = url
self.savefile = savefile
super(FileDownloader, self).__init__()
def run(self):
self.wc.download(self.url, self.savefile)
def get_upload_form(filename, data, formname, otherfields):
if not formname:
formname = filename
@@ -154,6 +165,28 @@ class SecureHTTPConnection(httplib.HTTPConnection, object):
rsp.read()
return {}
def download(self, url, file):
"""Download a file to filename or file object
"""
if isinstance(file, str) or isinstance(file, unicode):
file = open(file, 'wb')
webclient = self.dupe()
webclient.request('GET', url)
rsp = webclient.getresponse()
self._currdl = rsp
self._dlfile = file
for chunk in iter(lambda: rsp.read(16384), ''):
file.write(chunk)
self._currdl = None
file.close()
def get_download_progress(self):
if not self._currdl:
return None
return float(self._dlfile.tell()) / float(
self._currdl.getheader('content-length'))
def upload(self, url, filename, data=None, formname=None,
otherfields=()):
"""Upload a file to the url