2
0
mirror of https://opendev.org/x/pyghmi synced 2025-08-29 06:18:07 +00:00

Implement remote media upload

Platforms that support concept of media upload can be supported.

Change-Id: I7475563ac6af90b10e2c1870f72f227db5cdfd70
This commit is contained in:
Jarrod Johnson
2017-12-06 16:29:28 -05:00
parent ced920016f
commit 7d0df42298
5 changed files with 120 additions and 3 deletions

View File

@@ -1860,8 +1860,30 @@ class Command(object):
:param password: Password for endpoint to use when accessing the URL.
"""
self.oem_init()
self._oem.attach_remote_media(url, username, password)
return self._oem.attach_remote_media(url, username, password)
def detach_remote_media(self):
self.oem_init()
self._oem.detach_remote_media()
return self._oem.detach_remote_media()
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 filename: Optional callback for progress updates
"""
self.oem_init()
return self._oem.upload_media(filename, progress)
def list_media(self):
"""List attached remote media
:returns: An iterable list of attached media
"""
self.oem_init()
return self._oem.list_media()

View File

@@ -245,6 +245,12 @@ class OEMHandler(object):
def attach_remote_media(self, imagename, username, password):
raise exc.UnsupportedFunctionality()
def upload_media(self, filename, progress):
raise exc.UnsupportedFunctionality()
def list_media(self):
raise exc.UnsupportedFunctionality()
def set_identify(self, on, duration):
"""Provide an OEM override for set_identify

View File

@@ -903,3 +903,13 @@ class OEMHandler(generic.OEMHandler):
self.ipmicmd.xraw_command(
netfn=0x32, command=0x9f, data=(8, 10, 0, 0))
self.ipmicmd.xraw_command(netfn=0x32, command=0x9f, data=(8, 11))
def upload_media(self, filename, progress):
if self.has_xcc:
return self.immhandler.upload_media(filename, progress)
return super(OEMHandler, self).upload_media(filename, progress)
def list_media(self):
if self.has_xcc:
return self.immhandler.list_media()
return super(OEMHandler, self).list_media()

View File

@@ -24,6 +24,7 @@ import pyghmi.ipmi.oem.lenovo.energy as energy
import pyghmi.ipmi.private.session as ipmisession
import pyghmi.ipmi.private.util as util
import pyghmi.ipmi.sdr as sdr
import pyghmi.media as media
import pyghmi.storage as storage
import pyghmi.util.webclient as webclient
import random
@@ -797,6 +798,7 @@ class XCCClient(IMMClient):
'{}')
if 'return' not in rt or rt['return'] != 0:
raise Exception('Unhandled return: ' + repr(rt))
self.weblogout()
def get_firmware_inventory(self, bmcver):
# First we fetch the system firmware found in imm properties
@@ -887,9 +889,61 @@ class XCCClient(IMMClient):
for slot in slots:
rt = self.wc.grab_json_response(
'/api/providers/rp_vm_remote_unmount',
json.dumps({'Slot': slot}))
json.dumps({'Slot': str(slot)}))
if 'return' not in rt or rt['return'] != 0:
raise Exception("Unrecognized return: " + repr(rt))
rdocs = self.wc.grab_json_response('/api/providers/rp_rdoc_imagelist')
for rdoc in rdocs['items']:
filename = rdoc['filename']
rt = self.wc.grab_json_response('/api/providers/rp_rdoc_unmount',
{'ImageName': filename})
if rt.get('return', 1) != 0:
raise Exception("Unrecognized return: " + repr(rt))
self.weblogout()
def list_media(self):
rt = self.wc.grab_json_response('/api/providers/rp_vm_remote_getdisk')
if 'items' in rt:
for mt in rt['items']:
yield media.Media(mt['filename'], mt['remotepath'])
rt = self.wc.grab_json_response('/api/providers/rp_rdoc_imagelist')
if 'items' in rt:
for mt in rt['items']:
yield media.Media(mt['filename'])
self.weblogout()
def upload_media(self, filename, progress=None):
xid = random.randint(0, 1000000000)
uploadthread = 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': 'complete'})
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)
if rsp['return'] != 0:
raise Exception('Unrecognized return: ' + repr(rsp))
rsp = self.wc.grab_json_response('/api/providers/rp_rdoc_mountall',
{})
if rsp['return'] != 0:
raise Exception('Unrecognized return: ' + repr(rsp))
self.weblogout()
def update_firmware(self, filename, data=None, progress=None, bank=None):
result = None

25
pyghmi/media.py Normal file
View File

@@ -0,0 +1,25 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 IBM Corporation
# Copyright 2015-2017 Lenovo
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# These are the objects returned by list_media
class Media(object):
def __init__(self, name, url=None):
self.name = name
self.url = url