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.
---
Second try, now with less sugar! Err, fewer wrappers.
scripts/gnt-instance | 143 +++++++++++++++++++++-----------------------------
1 files changed, 59 insertions(+), 84 deletions(-)
diff --git a/scripts/gnt-instance b/scripts/gnt-instance
index 779b948..3ed658e 100755
--- a/scripts/gnt-instance
+++ b/scripts/gnt-instance
@@ -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"),
--
1.6.3.3