2
0
mirror of https://github.com/xcat2/confluent.git synced 2024-12-25 04:32:11 +00:00

Add support for volume creation

This commit is contained in:
Jarrod Johnson 2018-10-26 14:31:28 -04:00
parent c2d52d4f83
commit 73cab3774d
3 changed files with 107 additions and 12 deletions

View File

@ -478,7 +478,8 @@ def createresource(args):
collection = targpath
else:
collection, _, resname = targpath.rpartition('/')
keydata['name'] = resname
if 'name' not in keydata:
keydata['name'] = resname
makecall(session.create, (collection, keydata))

View File

@ -422,6 +422,9 @@ def get_input_message(path, operation, inputdata, nodes=None, multinode=False,
elif (path[:3] == ['configuration', 'storage', 'disks'] and
operation != 'retrieve'):
return InputDisk(path, nodes, inputdata)
elif (path[:3] == ['configuration', 'storage', 'volumes'] and
operation in ('update', 'create')):
return InputVolumes(path, nodes, inputdata)
elif 'inventory/firmware/updates/active' in '/'.join(path) and inputdata:
return InputFirmwareUpdate(path, nodes, inputdata)
elif '/'.join(path).startswith('media/detach'):
@ -713,6 +716,60 @@ class InputDisk(ConfluentInputMessage):
keyname = 'state'
class InputVolumes(ConfluentInputMessage):
def __init__(self, path, nodes, inputdata):
self.inputbynode = {}
self.stripped = False
if not inputdata:
raise exc.InvalidArgumentException('missing input data')
if isinstance(inputdata, dict):
volnames = [None]
if len(path) == 6:
volnames = path[-1]
volnames = inputdata.get('name', volnames)
if not isinstance(volnames, list):
volnames = volnames.split(',')
sizes = inputdata.get('size', [None])
if not isinstance(sizes, list):
sizes = sizes.split(',')
disks = inputdata.get('disks', [])
if not disks:
raise exc.InvalidArgumentException(
'disks are currently required to create a volume')
raidlvl = inputdata.get('raidlevel', None)
inputdata = []
for size in sizes:
if volnames:
currname = volnames.pop(0)
else:
currname = None
inputdata.append(
{'name': currname, 'size': size,
'disks': disks,
'raidlevel': raidlvl})
for node in nodes:
self.inputbynode[node] = []
for input in inputdata:
volname = None
if len(path) == 6:
volname = path[-1]
volname = input.get('name', volname)
if not volname:
volname = None
volsize = input.get('size', None)
if isinstance(input['disks'], list):
disks = input['disks']
else:
disks = input['disks'].split(',')
raidlvl = input.get('raidlevel', None)
for node in nodes:
self.inputbynode[node].append({'name': volname,
'size': volsize,
'disks': disks,
'raidlevel': raidlvl,
})
class InputPowerMessage(ConfluentInputMessage):
valid_values = set([
'on',

View File

@ -341,7 +341,7 @@ class IpmiConsole(conapi.Console):
self.solconnection.send_break()
def perform_requests(operator, nodes, element, cfg, inputdata):
def perform_requests(operator, nodes, element, cfg, inputdata, realop):
cryptit = cfg.decrypt
cfg.decrypt = True
configdata = cfg.get_node_attributes(nodes, _configattributes)
@ -351,7 +351,7 @@ def perform_requests(operator, nodes, element, cfg, inputdata):
for node in nodes:
livingthreads.add(_ipmiworkers.spawn(
perform_request, operator, node, element, configdata, inputdata,
cfg, resultdata))
cfg, resultdata, realop))
while livingthreads:
try:
datum = resultdata.get(timeout=10)
@ -377,10 +377,10 @@ def perform_requests(operator, nodes, element, cfg, inputdata):
def perform_request(operator, node, element,
configdata, inputdata, cfg, results):
configdata, inputdata, cfg, results, realop):
try:
return IpmiHandler(operator, node, element, configdata, inputdata,
cfg, results).handle_request()
cfg, results, realop).handle_request()
except pygexc.IpmiException as ipmiexc:
excmsg = str(ipmiexc)
if excmsg in ('Session no longer connected', 'timeout'):
@ -410,7 +410,8 @@ def perform_request(operator, node, element,
persistent_ipmicmds = {}
class IpmiHandler(object):
def __init__(self, operation, node, element, cfd, inputdata, cfg, output):
def __init__(self, operation, node, element, cfd, inputdata, cfg, output,
realop):
self.sensormap = {}
self.invmap = {}
self.output = output
@ -424,6 +425,7 @@ class IpmiHandler(object):
self.node = node
self.element = element
self.op = operation
self.realop = realop
connparams = get_conn_params(node, self.cfg)
self.ipmicmd = None
self.inputdata = inputdata
@ -939,10 +941,12 @@ class IpmiHandler(object):
storelem = self.element[2:]
if 'read' == self.op:
return self._show_storage(storelem)
elif 'update' == self.op:
elif 'update' == self.realop:
return self._update_storage(storelem)
elif 'delete' == self.op:
return self._delete_storage(storelem)
elif 'create' == self.realop:
return self._create_storage(storelem)
def _delete_storage(self, storelem):
if len(storelem) < 2 or storelem[0] != 'volumes':
@ -956,7 +960,39 @@ class IpmiHandler(object):
if simplify_name(vol.name) == volname:
volumes.append(vol)
self.ipmicmd.remove_storage_configuration(toremove)
self.output.put(msg.DeletedResource(volname))
def _create_storage(self, storelem):
if 'volumes' not in storelem:
raise exc.InvalidArgumentException('Can only create volumes')
vols = []
thedisks = None
currcfg = self.ipmicmd.get_storage_configuration()
disks = []
vols = []
vol = self.inputdata.inputbynode[self.node][0]
raidlvl = vol['raidlevel']
for disk in currcfg.disks:
if simplify_name(disk.name) in vol['disks']:
disks.append(disk)
elif (disk.status == 'Unconfigured Good' and
vol['disks'][0] in ('remainder', 'rest')):
disks.append(disk)
elif vol['disks'][0] == 'all':
disks.append(disk)
for vol in self.inputdata.inputbynode[self.node]:
if thedisks and thedisks != vol['disks']:
raise exc.InvalidArgumentException(
'Not currently supported to create multiple arrays '
'in a single request')
if raidlvl and vol['raidlevel'] != raidlvl:
raise exc.InvalidArgumentException('Cannot mix raid levels in '
'a single array')
vols.append(storage.Volume(name=vol['name'], size=vol['size']))
newcfg = storage.ConfigSpec(
arrays=(storage.Array(raid=raidlvl, disks=disks, volumes=vols),))
self.ipmicmd.apply_storage_configuration(newcfg)
return self._show_storage(storelem)
def _update_storage(self, storelem):
if storelem[0] == 'disks':
@ -1315,7 +1351,7 @@ def initthread():
_ipmithread = eventlet.spawn(_ipmi_evtloop)
def create(nodes, element, configmanager, inputdata):
def create(nodes, element, configmanager, inputdata, realop='create'):
initthread()
if element == ['_console', 'session']:
if len(nodes) > 1:
@ -1323,12 +1359,12 @@ def create(nodes, element, configmanager, inputdata):
return IpmiConsole(nodes[0], configmanager)
else:
return perform_requests(
'update', nodes, element, configmanager, inputdata)
'update', nodes, element, configmanager, inputdata, realop)
def update(nodes, element, configmanager, inputdata):
initthread()
return create(nodes, element, configmanager, inputdata)
return create(nodes, element, configmanager, inputdata, 'update')
def retrieve(nodes, element, configmanager, inputdata):
@ -1343,7 +1379,8 @@ def retrieve(nodes, element, configmanager, inputdata):
return firmwaremanager.list_updates(nodes, configmanager.tenant,
element, 'ffdc')
else:
return perform_requests('read', nodes, element, configmanager, inputdata)
return perform_requests('read', nodes, element, configmanager,
inputdata, 'read')
def delete(nodes, element, configmanager, inputdata):
initthread()
@ -1357,5 +1394,5 @@ def delete(nodes, element, configmanager, inputdata):
return firmwaremanager.remove_updates(nodes, configmanager.tenant,
element, type='ffdc')
return perform_requests(
'delete', nodes, element, configmanager, inputdata)
'delete', nodes, element, configmanager, inputdata, 'delete')