mirror of
https://github.com/xcat2/confluent.git
synced 2025-03-19 18:07:48 +00:00
Add remote media handling to API
This commit is contained in:
parent
ae39a84a30
commit
09d20ea1ff
@ -250,6 +250,25 @@ def _init_core():
|
||||
},
|
||||
},
|
||||
},
|
||||
'media': {
|
||||
'uploads': PluginCollection({
|
||||
'pluginattrs': ['hardwaremanagement.method'],
|
||||
'default': 'ipmi',
|
||||
}),
|
||||
'attach': PluginRoute({
|
||||
'pluginattrs': ['hardwaremanagement.method'],
|
||||
'default': 'ipmi',
|
||||
}),
|
||||
'detach': PluginRoute({
|
||||
'pluginattrs': ['hardwaremanagement.method'],
|
||||
'default': 'ipmi',
|
||||
}),
|
||||
'current': PluginRoute({
|
||||
'pluginattrs': ['hardwaremanagement.method'],
|
||||
'default': 'ipmi',
|
||||
}),
|
||||
|
||||
},
|
||||
'power': {
|
||||
'state': PluginRoute({
|
||||
'pluginattrs': ['hardwaremanagement.method'],
|
||||
|
@ -23,13 +23,17 @@ import confluent.messages as msg
|
||||
import eventlet
|
||||
|
||||
updatesbytarget = {}
|
||||
uploadsbytarget = {}
|
||||
updatepool = eventlet.greenpool.GreenPool(256)
|
||||
|
||||
|
||||
def execupdate(handler, filename, updateobj):
|
||||
def execupdate(handler, filename, updateobj, type):
|
||||
try:
|
||||
completion = handler(filename, progress=updateobj.handle_progress,
|
||||
bank=updateobj.bank)
|
||||
if type == 'firmware':
|
||||
completion = handler(filename, progress=updateobj.handle_progress,
|
||||
bank=updateobj.bank)
|
||||
else:
|
||||
completion = handler(filename, progress=updateobj.handle_progress)
|
||||
if completion is None:
|
||||
completion = 'complete'
|
||||
updateobj.handle_progress({'phase': completion, 'progress': 100.0})
|
||||
@ -44,26 +48,30 @@ def execupdate(handler, filename, updateobj):
|
||||
|
||||
class Updater(object):
|
||||
def __init__(self, node, handler, filename, tenant=None, name=None,
|
||||
bank=None):
|
||||
bank=None, type='firmware'):
|
||||
self.bank = bank
|
||||
self.node = node
|
||||
self.phase = 'initializing'
|
||||
self.detail = ''
|
||||
self.percent = 0.0
|
||||
#Change the below to a pool???
|
||||
self.updateproc = updatepool.spawn(execupdate, handler, filename, self)
|
||||
if (node, tenant) not in updatesbytarget:
|
||||
updatesbytarget[(node, tenant)] = {}
|
||||
self.updateproc = updatepool.spawn(execupdate, handler, filename,
|
||||
self, type)
|
||||
if type == 'firmware':
|
||||
myparty = updatesbytarget
|
||||
elif type == 'mediaupload':
|
||||
myparty = uploadsbytarget
|
||||
if (node, tenant) not in myparty:
|
||||
myparty[(node, tenant)] = {}
|
||||
if name is None:
|
||||
name = 1
|
||||
while '{0}'.format(name) in updatesbytarget[(node, tenant)]:
|
||||
while '{0}'.format(name) in myparty[(node, tenant)]:
|
||||
name += 1
|
||||
self.name = '{0}'.format(name)
|
||||
updatesbytarget[(node, tenant)][self.name] = self
|
||||
myparty[(node, tenant)][self.name] = self
|
||||
|
||||
def handle_progress(self, progress):
|
||||
self.phase = progress['phase']
|
||||
self.percent = float(progress['progress'])
|
||||
self.phase = progress.get('phase', 'unknown')
|
||||
self.percent = float(progress.get('progress', 100.0))
|
||||
self.detail = progress.get('detail', '')
|
||||
|
||||
def cancel(self):
|
||||
@ -91,18 +99,25 @@ def remove_updates(nodes, tenant, element):
|
||||
node, upid))
|
||||
|
||||
|
||||
def list_updates(nodes, tenant, element):
|
||||
def list_updates(nodes, tenant, element, type='firmware'):
|
||||
showmode = False
|
||||
if type == 'mediaupload':
|
||||
myparty = uploadsbytarget
|
||||
verb = 'upload'
|
||||
else:
|
||||
myparty = updatesbytarget
|
||||
verb = 'update'
|
||||
if len(element) > 4:
|
||||
showmode = True
|
||||
upid = element[-1]
|
||||
for node in nodes:
|
||||
if showmode:
|
||||
try:
|
||||
updater = updatesbytarget[(node, tenant)][upid]
|
||||
updater = myparty[(node, tenant)][upid]
|
||||
except KeyError:
|
||||
raise exc.NotFoundException('No matching update process found')
|
||||
raise exc.NotFoundException(
|
||||
'No matching {0} process found'.format(verb))
|
||||
yield msg.KeyValueData(updater.progress, name=node)
|
||||
else:
|
||||
for updateid in updatesbytarget.get((node, tenant), {}):
|
||||
for updateid in myparty.get((node, tenant), {}):
|
||||
yield msg.ChildCollection(updateid)
|
||||
|
@ -407,6 +407,10 @@ def get_input_message(path, operation, inputdata, nodes=None, multinode=False,
|
||||
return InputNTPServer(path, nodes, inputdata)
|
||||
elif 'inventory/firmware/updates/active' in '/'.join(path) and inputdata:
|
||||
return InputFirmwareUpdate(path, nodes, inputdata)
|
||||
elif '/'.join(path).startswith('media/detach'):
|
||||
return DetachMedia(path, nodes, inputdata)
|
||||
elif '/'.join(path).startswith('media/'):
|
||||
return InputMedia(path, nodes, inputdata)
|
||||
elif inputdata:
|
||||
raise exc.InvalidArgumentException(
|
||||
'No known input handler for request')
|
||||
@ -414,10 +418,22 @@ def get_input_message(path, operation, inputdata, nodes=None, multinode=False,
|
||||
class InputFirmwareUpdate(ConfluentMessage):
|
||||
|
||||
def __init__(self, path, nodes, inputdata):
|
||||
self.filename = inputdata['filename']
|
||||
self.filename = inputdata.get('filename', inputdata['url'])
|
||||
self.bank = inputdata.get('bank', None)
|
||||
self.nodes = nodes
|
||||
|
||||
class InputMedia(InputFirmwareUpdate):
|
||||
# Use InputFirmwareUpdate
|
||||
pass
|
||||
|
||||
class DetachMedia(ConfluentMessage):
|
||||
def __init__(self, path, nodes, inputdata):
|
||||
if inputdata['detach'] != 'all':
|
||||
raise exc.InvalidArgumentException('Currently only supporting'
|
||||
'{"detach": "all"}')
|
||||
class Media(ConfluentMessage):
|
||||
def __init__(self, node, media):
|
||||
self.kvpairs = {node: {'name': media.name, 'url': media.url}}
|
||||
|
||||
class InputAlertData(ConfluentMessage):
|
||||
|
||||
|
@ -450,6 +450,14 @@ class IpmiHandler(object):
|
||||
self.handle_update()
|
||||
elif self.element[0] == 'inventory':
|
||||
self.handle_inventory()
|
||||
elif self.element == ['media', 'attach']:
|
||||
self.handle_attach_media()
|
||||
elif self.element == ['media', 'detach']:
|
||||
self.handle_detach_media()
|
||||
elif self.element == ['media', 'uploads']:
|
||||
self.handle_media_upload()
|
||||
elif self.element == ['media', 'current']:
|
||||
self.handle_list_media()
|
||||
elif self.element == ['events', 'hardware', 'log']:
|
||||
self.do_eventlog()
|
||||
elif self.element == ['events', 'hardware', 'decode']:
|
||||
@ -468,6 +476,22 @@ class IpmiHandler(object):
|
||||
'nodes/{0}/inventory/firmware/updates/active/{1}'.format(
|
||||
self.node, u.name)))
|
||||
|
||||
def handle_media_upload(self):
|
||||
u = firmwaremanager.Updater(self.node, self.ipmicmd.upload_media,
|
||||
self.inputdata.filename, self.tenant,
|
||||
type='mediaupload')
|
||||
self.output.put(msg.CreatedResource(
|
||||
'nodes/{0}/media/uploads/{1}'.format(self.node, u.name)))
|
||||
|
||||
def handle_attach_media(self):
|
||||
self.ipmicmd.attach_remote_media(self.inputdata.filename)
|
||||
|
||||
def handle_detach_media(self):
|
||||
self.ipmicmd.detach_remote_media()
|
||||
|
||||
def handle_list_media(self):
|
||||
for media in self.ipmicmd.list_media():
|
||||
self.output.put(msg.Media(self.node, media))
|
||||
|
||||
def handle_configuration(self):
|
||||
if self.element[1:3] == ['management_controller', 'alerts']:
|
||||
@ -1022,6 +1046,9 @@ def retrieve(nodes, element, configmanager, inputdata):
|
||||
if '/'.join(element).startswith('inventory/firmware/updates/active'):
|
||||
return firmwaremanager.list_updates(nodes, configmanager.tenant,
|
||||
element)
|
||||
elif '/'.join(element).startswith('media/uploads'):
|
||||
return firmwaremanager.list_updates(nodes, configmanager.tenent,
|
||||
element, 'mediaupload')
|
||||
else:
|
||||
return perform_requests('read', nodes, element, configmanager, inputdata)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user