Commit d77490c5 authored by Iustin Pop's avatar Iustin Pop

Unify the instance creation code

Currently the AddInstance in gnt-instance and ImportInstance in
gnt-backup duplicate all of their code except the actual opcode creation
(the parameters to it). By moving this to cli.py (not optimal location,
but we don't have another one), we can use a single copy of the code,
and simply change based on the mode parameter the few different
opcode parameters.
Signed-off-by: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarMichael Hanselmann <hansmi@google.com>
parent 1c5945b6
......@@ -116,6 +116,7 @@ __all__ = [
"YES_DOIT_OPT",
# Generic functions for CLI programs
"GenericMain",
"GenericInstanceCreate",
"GetClient",
"GetOnlineNodes",
"JobExecutor",
......@@ -1323,6 +1324,116 @@ def GenericMain(commands, override=None, aliases=None):
return result
def GenericInstanceCreate(mode, opts, args):
"""Add an instance to the cluster via either creation or import.
@param mode: constants.INSTANCE_CREATE or constants.INSTANCE_IMPORT
@param opts: the command line options selected by the user
@type args: list
@param args: should contain only one element, the new instance name
@rtype: int
@return: the desired exit code
"""
instance = args[0]
(pnode, snode) = SplitNodeOption(opts.node)
hypervisor = None
hvparams = {}
if opts.hypervisor:
hypervisor, hvparams = opts.hypervisor
if opts.nics:
try:
nic_max = max(int(nidx[0])+1 for nidx in opts.nics)
except ValueError, err:
raise errors.OpPrereqError("Invalid NIC index passed: %s" % str(err))
nics = [{}] * nic_max
for nidx, ndict in opts.nics:
nidx = int(nidx)
if not isinstance(ndict, dict):
msg = "Invalid nic/%d value: expected dict, got %s" % (nidx, ndict)
raise errors.OpPrereqError(msg)
nics[nidx] = ndict
elif opts.no_nics:
# no nics
nics = []
else:
# default of one nic, all auto
nics = [{}]
if opts.disk_template == constants.DT_DISKLESS:
if opts.disks or opts.sd_size is not None:
raise errors.OpPrereqError("Diskless instance but disk"
" information passed")
disks = []
else:
if not opts.disks and not opts.sd_size:
raise errors.OpPrereqError("No disk information specified")
if opts.disks and opts.sd_size is not None:
raise errors.OpPrereqError("Please use either the '--disk' or"
" '-s' option")
if opts.sd_size is not None:
opts.disks = [(0, {"size": opts.sd_size})]
try:
disk_max = max(int(didx[0])+1 for didx in opts.disks)
except ValueError, err:
raise errors.OpPrereqError("Invalid disk index passed: %s" % str(err))
disks = [{}] * disk_max
for didx, ddict in opts.disks:
didx = int(didx)
if not isinstance(ddict, dict):
msg = "Invalid disk/%d value: expected dict, got %s" % (didx, ddict)
raise errors.OpPrereqError(msg)
elif "size" not in ddict:
raise errors.OpPrereqError("Missing size for disk %d" % didx)
try:
ddict["size"] = utils.ParseUnit(ddict["size"])
except ValueError, err:
raise errors.OpPrereqError("Invalid disk size for disk %d: %s" %
(didx, err))
disks[didx] = ddict
utils.ForceDictType(opts.beparams, constants.BES_PARAMETER_TYPES)
utils.ForceDictType(hvparams, constants.HVS_PARAMETER_TYPES)
if mode == constants.INSTANCE_CREATE:
start = opts.start
os_type = opts.os
src_node = None
src_path = None
elif mode == constants.INSTANCE_IMPORT:
start = False
os_type = None
src_node = opts.src_node
src_path = opts.src_dir
else:
raise errors.ProgrammerError("Invalid creation mode %s" % mode)
op = opcodes.OpCreateInstance(instance_name=instance,
disks=disks,
disk_template=opts.disk_template,
nics=nics,
pnode=pnode, snode=snode,
ip_check=opts.ip_check,
wait_for_sync=opts.wait_for_sync,
file_storage_dir=opts.file_storage_dir,
file_driver=opts.file_driver,
iallocator=opts.iallocator,
hypervisor=hypervisor,
hvparams=hvparams,
beparams=opts.beparams,
mode=mode,
start=start,
os_type=os_type,
src_node=src_node,
src_path=src_path)
SubmitOrSend(op, opts)
return 0
def GenerateTable(headers, fields, separator, data,
numfields=None, unitfields=None,
units=None):
......
......@@ -99,95 +99,10 @@ def ExportInstance(opts, args):
def ImportInstance(opts, args):
"""Add an instance to the cluster.
@param opts: the command line options selected by the user
@type args: list
@param args: should contain only one element, the new instance name
@rtype: int
@return: the desired exit code
This is just a wrapper over GenericInstanceCreate.
"""
instance = args[0]
(pnode, snode) = SplitNodeOption(opts.node)
hypervisor = None
hvparams = {}
if opts.hypervisor:
hypervisor, hvparams = opts.hypervisor
if opts.nics:
try:
nic_max = max(int(nidx[0])+1 for nidx in opts.nics)
except ValueError, err:
raise errors.OpPrereqError("Invalid NIC index passed: %s" % str(err))
nics = [{}] * nic_max
for nidx, ndict in opts.nics:
nidx = int(nidx)
if not isinstance(ndict, dict):
msg = "Invalid nic/%d value: expected dict, got %s" % (nidx, ndict)
raise errors.OpPrereqError(msg)
nics[nidx] = ndict
elif opts.no_nics:
# no nics
nics = []
else:
# default of one nic, all auto
nics = [{}]
if opts.disk_template == constants.DT_DISKLESS:
if opts.disks or opts.sd_size is not None:
raise errors.OpPrereqError("Diskless instance but disk"
" information passed")
disks = []
else:
if not opts.disks and not opts.sd_size:
raise errors.OpPrereqError("No disk information specified")
if opts.disks and opts.sd_size is not None:
raise errors.OpPrereqError("Please use either the '--disk' or"
" '-s' option")
if opts.sd_size is not None:
opts.disks = [(0, {"size": opts.sd_size})]
try:
disk_max = max(int(didx[0])+1 for didx in opts.disks)
except ValueError, err:
raise errors.OpPrereqError("Invalid disk index passed: %s" % str(err))
disks = [{}] * disk_max
for didx, ddict in opts.disks:
didx = int(didx)
if not isinstance(ddict, dict):
msg = "Invalid disk/%d value: expected dict, got %s" % (didx, ddict)
raise errors.OpPrereqError(msg)
elif "size" not in ddict:
raise errors.OpPrereqError("Missing size for disk %d" % didx)
try:
ddict["size"] = utils.ParseUnit(ddict["size"])
except ValueError, err:
raise errors.OpPrereqError("Invalid disk size for disk %d: %s" %
(didx, err))
disks[didx] = ddict
utils.ForceDictType(opts.beparams, constants.BES_PARAMETER_TYPES)
utils.ForceDictType(hvparams, constants.HVS_PARAMETER_TYPES)
op = opcodes.OpCreateInstance(instance_name=instance,
disk_template=opts.disk_template,
disks=disks,
nics=nics,
mode=constants.INSTANCE_IMPORT,
pnode=pnode, snode=snode,
ip_check=opts.ip_check,
start=False,
src_node=opts.src_node, src_path=opts.src_dir,
wait_for_sync=opts.wait_for_sync,
file_storage_dir=opts.file_storage_dir,
file_driver=opts.file_driver,
iallocator=opts.iallocator,
hypervisor=hypervisor,
hvparams=hvparams,
beparams=opts.beparams)
SubmitOpCode(op)
return 0
return GenericInstanceCreate(constants.INSTANCE_IMPORT, opts, args)
def RemoveExport(opts, args):
......@@ -225,6 +140,7 @@ import_opts = [
FILESTORE_DIR_OPT,
FILESTORE_DRIVER_OPT,
HYPERVISOR_OPT,
SUBMIT_OPT,
]
commands = {
......
......@@ -311,94 +311,10 @@ def ListInstances(opts, args):
def AddInstance(opts, args):
"""Add an instance to the cluster.
@param opts: the command line options selected by the user
@type args: list
@param args: should contain only one element, the new instance name
@rtype: int
@return: the desired exit code
This is just a wrapper over GenericInstanceCreate.
"""
instance = args[0]
(pnode, snode) = SplitNodeOption(opts.node)
hypervisor = None
hvparams = {}
if opts.hypervisor:
hypervisor, hvparams = opts.hypervisor
if opts.nics:
try:
nic_max = max(int(nidx[0])+1 for nidx in opts.nics)
except ValueError, err:
raise errors.OpPrereqError("Invalid NIC index passed: %s" % str(err))
nics = [{}] * nic_max
for nidx, ndict in opts.nics:
nidx = int(nidx)
if not isinstance(ndict, dict):
msg = "Invalid nic/%d value: expected dict, got %s" % (nidx, ndict)
raise errors.OpPrereqError(msg)
nics[nidx] = ndict
elif opts.no_nics:
# no nics
nics = []
else:
# default of one nic, all auto
nics = [{}]
if opts.disk_template == constants.DT_DISKLESS:
if opts.disks or opts.sd_size is not None:
raise errors.OpPrereqError("Diskless instance but disk"
" information passed")
disks = []
else:
if not opts.disks and not opts.sd_size:
raise errors.OpPrereqError("No disk information specified")
if opts.disks and opts.sd_size is not None:
raise errors.OpPrereqError("Please use either the '--disk' or"
" '-s' option")
if opts.sd_size is not None:
opts.disks = [(0, {"size": opts.sd_size})]
try:
disk_max = max(int(didx[0])+1 for didx in opts.disks)
except ValueError, err:
raise errors.OpPrereqError("Invalid disk index passed: %s" % str(err))
disks = [{}] * disk_max
for didx, ddict in opts.disks:
didx = int(didx)
if not isinstance(ddict, dict):
msg = "Invalid disk/%d value: expected dict, got %s" % (didx, ddict)
raise errors.OpPrereqError(msg)
elif "size" not in ddict:
raise errors.OpPrereqError("Missing size for disk %d" % didx)
try:
ddict["size"] = utils.ParseUnit(ddict["size"])
except ValueError, err:
raise errors.OpPrereqError("Invalid disk size for disk %d: %s" %
(didx, err))
disks[didx] = ddict
utils.ForceDictType(opts.beparams, constants.BES_PARAMETER_TYPES)
utils.ForceDictType(hvparams, constants.HVS_PARAMETER_TYPES)
op = opcodes.OpCreateInstance(instance_name=instance,
disks=disks,
disk_template=opts.disk_template,
nics=nics,
mode=constants.INSTANCE_CREATE,
os_type=opts.os, pnode=pnode,
snode=snode,
start=opts.start, ip_check=opts.ip_check,
wait_for_sync=opts.wait_for_sync,
hypervisor=hypervisor,
hvparams=hvparams,
beparams=opts.beparams,
iallocator=opts.iallocator,
file_storage_dir=opts.file_storage_dir,
file_driver=opts.file_driver,
)
SubmitOrSend(op, opts)
return GenericInstanceCreate(constants.INSTANCE_CREATE, opts, args)
return 0
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment