Commit 1c5945b6 authored by Iustin Pop's avatar Iustin Pop

Unify multi-instance handling in gnt-instance

Start, stop and reboot have the same code for dealing with
multi-instance handling. This patch moves all that into a single generic
function, and leaves only the building of the specific opcode for the
operation in the individual functions.
Signed-off-by: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarMichael Hanselmann <hansmi@google.com>
parent 3e54ace7
......@@ -31,7 +31,6 @@ import time
from cStringIO import StringIO
from ganeti.cli import *
from ganeti import cli
from ganeti import opcodes
from ganeti import constants
from ganeti import utils
......@@ -175,6 +174,36 @@ def _EnsureInstancesExist(client, names):
raise errors.OpPrereqError("Instance '%s' does not exist" % orig_name)
def GenericManyOps(operation, fn):
"""Generic multi-instance operations.
The will return a wrapper that processes the options and arguments
given, and uses the passed function to build the opcode needed for
the specific operation. Thus all the generic loop/confirmation code
is abstracted into this function.
"""
def realfn(opts, args):
if opts.multi_mode is None:
opts.multi_mode = _SHUTDOWN_INSTANCES
cl = GetClient()
inames = _ExpandMultiNames(opts.multi_mode, args, client=cl)
if not inames:
raise errors.OpPrereqError("Selection filter does not match"
" any instances")
multi_on = opts.multi_mode != _SHUTDOWN_INSTANCES or len(inames) > 1
if not (opts.force_multi or not multi_on
or _ConfirmOperation(inames, operation)):
return 1
jex = JobExecutor(verbose=multi_on, cl=cl)
for name in inames:
op = fn(name, opts)
jex.QueueJob(name, op)
jex.WaitOrShow(not opts.submit_only)
return 0
return realfn
def ListInstances(opts, args):
"""List instances and their properties.
......@@ -729,109 +758,55 @@ def GrowDisk(opts, args):
return 0
def StartupInstance(opts, args):
def _StartupInstance(name, opts):
"""Startup instances.
Depending on the options given, this will start one or more
instances.
This returns the opcode to start an instance, and its decorator will
wrap this into a loop starting all desired instances.
@param name: the name of the instance to act on
@param opts: the command line options selected by the user
@type args: list
@param args: the instance or node names based on which we
create the final selection (in conjunction with the
opts argument)
@rtype: int
@return: the desired exit code
@return: the opcode needed for the operation
"""
cl = GetClient()
if opts.multi_mode is None:
opts.multi_mode = _SHUTDOWN_INSTANCES
inames = _ExpandMultiNames(opts.multi_mode, args, client=cl)
if not inames:
raise errors.OpPrereqError("Selection filter does not match any instances")
multi_on = opts.multi_mode != _SHUTDOWN_INSTANCES or len(inames) > 1
if not (opts.force_multi or not multi_on
or _ConfirmOperation(inames, "startup")):
return 1
jex = cli.JobExecutor(verbose=multi_on, cl=cl)
for name in inames:
op = opcodes.OpStartupInstance(instance_name=name,
force=opts.force)
# do not add these parameters to the opcode unless they're defined
if opts.hvparams:
op.hvparams = opts.hvparams
if opts.beparams:
op.beparams = opts.beparams
jex.QueueJob(name, op)
jex.WaitOrShow(not opts.submit_only)
return 0
op = opcodes.OpStartupInstance(instance_name=name,
force=opts.force)
# do not add these parameters to the opcode unless they're defined
if opts.hvparams:
op.hvparams = opts.hvparams
if opts.beparams:
op.beparams = opts.beparams
return op
def RebootInstance(opts, args):
def _RebootInstance(name, opts):
"""Reboot instance(s).
Depending on the parameters given, this will reboot one or more
instances.
This returns the opcode to reboot an instance, and its decorator
will wrap this into a loop rebooting all desired instances.
@param name: the name of the instance to act on
@param opts: the command line options selected by the user
@type args: list
@param args: the instance or node names based on which we
create the final selection (in conjunction with the
opts argument)
@rtype: int
@return: the desired exit code
@return: the opcode needed for the operation
"""
cl = GetClient()
if opts.multi_mode is None:
opts.multi_mode = _SHUTDOWN_INSTANCES
inames = _ExpandMultiNames(opts.multi_mode, args, client=cl)
if not inames:
raise errors.OpPrereqError("Selection filter does not match any instances")
multi_on = opts.multi_mode != _SHUTDOWN_INSTANCES or len(inames) > 1
if not (opts.force_multi or not multi_on
or _ConfirmOperation(inames, "reboot")):
return 1
jex = JobExecutor(verbose=multi_on, cl=cl)
for name in inames:
op = opcodes.OpRebootInstance(instance_name=name,
return opcodes.OpRebootInstance(instance_name=name,
reboot_type=opts.reboot_type,
ignore_secondaries=opts.ignore_secondaries)
jex.QueueJob(name, op)
jex.WaitOrShow(not opts.submit_only)
return 0
def ShutdownInstance(opts, args):
def _ShutdownInstance(name, opts):
"""Shutdown an instance.
This returns the opcode to shutdown an instance, and its decorator
will wrap this into a loop shutting down all desired instances.
@param name: the name of the instance to act on
@param opts: the command line options selected by the user
@type args: list
@param args: the instance or node names based on which we
create the final selection (in conjunction with the
opts argument)
@rtype: int
@return: the desired exit code
@return: the opcode needed for the operation
"""
cl = GetClient()
if opts.multi_mode is None:
opts.multi_mode = _SHUTDOWN_INSTANCES
inames = _ExpandMultiNames(opts.multi_mode, args, client=cl)
if not inames:
raise errors.OpPrereqError("Selection filter does not match any instances")
multi_on = opts.multi_mode != _SHUTDOWN_INSTANCES or len(inames) > 1
if not (opts.force_multi or not multi_on
or _ConfirmOperation(inames, "shutdown")):
return 1
jex = cli.JobExecutor(verbose=multi_on, cl=cl)
for name in inames:
op = opcodes.OpShutdownInstance(instance_name=name)
jex.QueueJob(name, op)
jex.WaitOrShow(not opts.submit_only)
return 0
return opcodes.OpShutdownInstance(instance_name=name)
def ReplaceDisks(opts, args):
......@@ -1445,18 +1420,18 @@ commands = {
[BACKEND_OPT, DISK_OPT, FORCE_OPT, HVOPTS_OPT, NET_OPT, SUBMIT_OPT],
"<instance>", "Alters the parameters of an instance"),
'shutdown': (
ShutdownInstance, [ArgInstance()],
GenericManyOps("shutdown", _ShutdownInstance), [ArgInstance()],
[m_node_opt, m_pri_node_opt, m_sec_node_opt, m_clust_opt,
m_inst_opt, m_force_multi, SUBMIT_OPT],
"<instance>", "Stops an instance"),
'startup': (
StartupInstance, [ArgInstance()],
GenericManyOps("startup", _StartupInstance), [ArgInstance()],
[FORCE_OPT, m_force_multi, m_node_opt, m_pri_node_opt,
m_sec_node_opt, m_clust_opt, m_inst_opt, SUBMIT_OPT, HVOPTS_OPT,
BACKEND_OPT],
"<instance>", "Starts an instance"),
'reboot': (
RebootInstance, [ArgInstance()],
GenericManyOps("reboot", _RebootInstance), [ArgInstance()],
[m_force_multi, REBOOT_TYPE_OPT, IGNORE_SECONDARIES_OPT, m_node_opt,
m_pri_node_opt, m_sec_node_opt, m_clust_opt, m_inst_opt, SUBMIT_OPT],
"<instance>", "Reboots an instance"),
......
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