Start, stop and reboot have the same code for dealing with
multi-instance handling. This patch moves all that into a single
decorator function, and leaves only the building of the specific opcode
for the operation in these functions.
---
scripts/gnt-instance | 147 ++++++++++++++++++++++----------------------------
1 files changed, 64 insertions(+), 83 deletions(-)
diff --git a/scripts/gnt-instance b/scripts/gnt-instance
index 779b948..69ebca6 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,39 @@ def _EnsureInstancesExist(client, names):
raise errors.OpPrereqError("Instance '%s' does not exist" % orig_name)
+def _ManyOpsWrapper(operation):
+ """Wrapper for multi-instance operations.
+
+ The wrapper, given an operation name, will return (another) wrapper
+ that processes the options and arguments given, and uses the wrapped
+ function to build the opcode needed for the specific operation. Thus
+ all the generic loop/confirmation code is abstracted into this
+ function.
+
+ """
+ def wrap(fn):
+ 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
+ return wrap
+
+
def ListInstances(opts, args):
"""List instances and their properties.
@@ -729,109 +761,58 @@ def GrowDisk(opts, args):
return 0
-def StartupInstance(opts, args):
+...@_manyopswrapper("startup")
+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
-
-
-def RebootInstance(opts, args):
+ 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
+
+
+...@_manyopswrapper("reboot")
+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):
+...@_manyopswrapper("shutdown")
+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):
--
1.6.3.3