mirror of
https://opendev.org/x/pyghmi
synced 2025-09-17 23:38:21 +00:00
Implement upload_media for Lenovo
Implement the Lenovo OEM mechanism for media upload under redfish command object. Change-Id: I47f7b8ba5751741a1c6fb322366b18a9120f7db3
This commit is contained in:
@@ -1982,7 +1982,7 @@ class Command(object):
|
||||
|
||||
:param filename: The filename to use, the basename of the parameter
|
||||
will be given to the bmc.
|
||||
:param filename: Optional callback for progress updates
|
||||
:param progress: Optional callback for progress updates
|
||||
"""
|
||||
self.oem_init()
|
||||
return self._oem.upload_media(filename, progress)
|
||||
|
@@ -1198,6 +1198,19 @@ class Command(object):
|
||||
"""
|
||||
return self.oem.apply_storage_configuration(cfgspec)
|
||||
|
||||
def upload_media(self, filename, progress=None):
|
||||
"""Upload a file to be hosted on the target BMC
|
||||
|
||||
This will upload the specified data to
|
||||
the BMC so that it will make it available to the system as an emulated
|
||||
USB device.
|
||||
|
||||
:param filename: The filename to use, the basename of the parameter
|
||||
will be given to the bmc.
|
||||
:param progress: Optional callback for progress updates
|
||||
"""
|
||||
return self.oem.upload_media(filename, progress)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import os
|
||||
import sys
|
||||
|
@@ -52,6 +52,10 @@ class OEMHandler(object):
|
||||
raise exc.UnsupportedFunctionality(
|
||||
'Remote storage configuration not supported on this platform')
|
||||
|
||||
def upload_media(self, filename, progress=None):
|
||||
raise exc.UnsupportedFunctionality(
|
||||
'Remote media upload not supported on this platform')
|
||||
|
||||
def _do_web_request(self, url, payload=None, method=None, cache=True):
|
||||
res = None
|
||||
if cache and payload is None and method is None:
|
||||
|
@@ -22,6 +22,8 @@ import time
|
||||
import pyghmi.ipmi.private.util as util
|
||||
import pyghmi.exceptions as pygexc
|
||||
import pyghmi.storage as storage
|
||||
import pyghmi.util.webclient as webclient
|
||||
import random
|
||||
|
||||
|
||||
class OEMHandler(generic.OEMHandler):
|
||||
@@ -79,7 +81,7 @@ class OEMHandler(generic.OEMHandler):
|
||||
except ValueError:
|
||||
pass
|
||||
yield ('{0} {1}'.format(aname, fname), bdata)
|
||||
|
||||
|
||||
def _get_disk_firmware_single(self, diskent, prefix=''):
|
||||
bdata = {}
|
||||
if not prefix and diskent.get('location', '').startswith('M.2'):
|
||||
@@ -178,6 +180,15 @@ class OEMHandler(generic.OEMHandler):
|
||||
'Unexpected return to set disk state: {0}'.format(
|
||||
rsp.get('return', -1)))
|
||||
|
||||
def _refresh_token(self):
|
||||
self._refresh_token_wc(self.wc)
|
||||
|
||||
def _refresh_token_wc(self, wc):
|
||||
wc.grab_json_response('/api/providers/identity')
|
||||
if '_csrf_token' in wc.cookies:
|
||||
wc.set_header('X-XSRF-TOKEN', self.wc.cookies['_csrf_token'])
|
||||
wc.vintage = util._monotonic_time()
|
||||
|
||||
def _make_available(self, disk, realcfg):
|
||||
# 8 if jbod, 4 if hotspare.., leave alone if already...
|
||||
currstatus = self._get_status(disk, realcfg)
|
||||
@@ -414,3 +425,48 @@ class OEMHandler(generic.OEMHandler):
|
||||
if '_csrf_token' in wc.cookies:
|
||||
wc.set_header('X-XSRF-TOKEN', wc.cookies['_csrf_token'])
|
||||
return wc
|
||||
|
||||
def upload_media(self, filename, progress=None):
|
||||
xid = random.randint(0, 1000000000)
|
||||
self._refresh_token()
|
||||
uploadthread = webclient.FileUploader(
|
||||
self.wc, '/upload?X-Progress-ID={0}'.format(xid), filename, None)
|
||||
uploadthread.start()
|
||||
while uploadthread.isAlive():
|
||||
uploadthread.join(3)
|
||||
rsp = self.wc.grab_json_response(
|
||||
'/upload/progress?X-Progress-ID={0}'.format(xid))
|
||||
if progress and rsp['state'] == 'uploading':
|
||||
progress({'phase': 'upload',
|
||||
'progress': 100.0 * rsp['received'] / rsp['size']})
|
||||
self._refresh_token()
|
||||
rsp = json.loads(uploadthread.rsp)
|
||||
if progress:
|
||||
progress({'phase': 'upload',
|
||||
'progress': 100.0})
|
||||
thepath = rsp['items'][0]['path']
|
||||
thename = rsp['items'][0]['name']
|
||||
writeable = 1 if filename.lower().endswith('.img') else 0
|
||||
addfile = {"Url": thepath, "Protocol": 6, "Write": writeable,
|
||||
"Credential": ":", "Option": "", "Domain": "",
|
||||
"WebUploadName": thename}
|
||||
rsp = self.wc.grab_json_response('/api/providers/rp_rdoc_addfile',
|
||||
addfile)
|
||||
self._refresh_token()
|
||||
if rsp.get('return', -1) != 0:
|
||||
errmsg = repr(rsp) if rsp else self.wc.lastjsonerror
|
||||
raise Exception('Unrecognized return: ' + errmsg)
|
||||
rsp = self.wc.grab_json_response('/api/providers/rp_rdoc_getfiles')
|
||||
if 'items' not in rsp or len(rsp['items']) == 0:
|
||||
raise Exception(
|
||||
'Image upload was not accepted, it may be too large')
|
||||
self._refresh_token()
|
||||
rsp = self.wc.grab_json_response('/api/providers/rp_rdoc_mountall',
|
||||
{})
|
||||
self._refresh_token()
|
||||
if rsp.get('return', -1) != 0:
|
||||
errmsg = repr(rsp) if rsp else self.wc.lastjsonerror
|
||||
raise Exception('Unrecognized return: ' + errmsg)
|
||||
if progress:
|
||||
progress({'phase': 'complete'})
|
||||
#self.weblogout()
|
||||
|
Reference in New Issue
Block a user