Commit fe7b0351 authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

- Move --force option to cli.py

- Implement “gnt-instance reinstall”
- Fix two typos

Reviewed-by: iustinp
parent 330cda58
...@@ -39,7 +39,7 @@ from optparse import (OptionParser, make_option, TitledHelpFormatter, ...@@ -39,7 +39,7 @@ from optparse import (OptionParser, make_option, TitledHelpFormatter,
__all__ = ["DEBUG_OPT", "NOHDR_OPT", "SEP_OPT", "GenericMain", "SubmitOpCode", __all__ = ["DEBUG_OPT", "NOHDR_OPT", "SEP_OPT", "GenericMain", "SubmitOpCode",
"cli_option", "OutputTable", "cli_option", "OutputTable",
"ARGS_NONE", "ARGS_FIXED", "ARGS_ATLEAST", "ARGS_ANY", "ARGS_ONE", "ARGS_NONE", "ARGS_FIXED", "ARGS_ATLEAST", "ARGS_ANY", "ARGS_ONE",
"USEUNITS_OPT", "FIELDS_OPT"] "USEUNITS_OPT", "FIELDS_OPT", "FORCE_OPT"]
DEBUG_OPT = make_option("-d", "--debug", default=False, DEBUG_OPT = make_option("-d", "--debug", default=False,
action="store_true", action="store_true",
...@@ -62,6 +62,9 @@ FIELDS_OPT = make_option("-o", "--output", dest="output", action="store", ...@@ -62,6 +62,9 @@ FIELDS_OPT = make_option("-o", "--output", dest="output", action="store",
type="string", help="Select output fields", type="string", help="Select output fields",
metavar="FIELDS") metavar="FIELDS")
FORCE_OPT = make_option("-f", "--force", dest="force", action="store_true",
default=False, help="Force the operation")
_LOCK_OPT = make_option("--lock-retries", default=None, _LOCK_OPT = make_option("--lock-retries", default=None,
type="int", help=SUPPRESS_HELP) type="int", help=SUPPRESS_HELP)
......
...@@ -1648,6 +1648,17 @@ def _AssembleInstanceDisks(instance, cfg, ignore_secondaries=False): ...@@ -1648,6 +1648,17 @@ def _AssembleInstanceDisks(instance, cfg, ignore_secondaries=False):
return disks_ok, device_info return disks_ok, device_info
def _StartInstanceDisks(cfg, instance, force):
disks_ok, dummy = _AssembleInstanceDisks(instance, cfg,
ignore_secondaries=force)
if not disks_ok:
_ShutdownInstanceDisks(instance, cfg)
if force is not None and not force:
logger.Error("If the message above refers to a secondary node,"
" you can retry the operation using '--force'.")
raise errors.OpExecError, ("Disk consistency error")
class LUDeactivateInstanceDisks(NoHooksLU): class LUDeactivateInstanceDisks(NoHooksLU):
"""Shutdown an instance's disks. """Shutdown an instance's disks.
...@@ -1776,14 +1787,7 @@ class LUStartupInstance(LogicalUnit): ...@@ -1776,14 +1787,7 @@ class LUStartupInstance(LogicalUnit):
(instance.name, node_current, memory, (instance.name, node_current, memory,
freememory)) freememory))
disks_ok, dummy = _AssembleInstanceDisks(instance, self.cfg, _StartInstanceDisks(self.cfg, instance, force)
ignore_secondaries=force)
if not disks_ok:
_ShutdownInstanceDisks(instance, self.cfg)
if not force:
logger.Error("If the message above refers to a secondary node,"
" you can retry the operation using '--force'.")
raise errors.OpExecError, ("Disk consistency error")
if not rpc.call_instance_start(node_current, instance, extra_args): if not rpc.call_instance_start(node_current, instance, extra_args):
_ShutdownInstanceDisks(instance, self.cfg) _ShutdownInstanceDisks(instance, self.cfg)
...@@ -1841,6 +1845,70 @@ class LUShutdownInstance(LogicalUnit): ...@@ -1841,6 +1845,70 @@ class LUShutdownInstance(LogicalUnit):
_ShutdownInstanceDisks(instance, self.cfg) _ShutdownInstanceDisks(instance, self.cfg)
class LUReinstallInstance(LogicalUnit):
"""Reinstall an instance.
"""
HPATH = "instance-reinstall"
HTYPE = constants.HTYPE_INSTANCE
_OP_REQP = ["instance_name"]
def BuildHooksEnv(self):
"""Build hooks env.
This runs on master, primary and secondary nodes of the instance.
"""
env = {
"INSTANCE_NAME": self.op.instance_name,
"INSTANCE_PRIMARY": self.instance.primary_node,
"INSTANCE_SECONDARIES": " ".join(self.instance.secondary_nodes),
}
nl = ([self.sstore.GetMasterNode(), self.instance.primary_node] +
list(self.instance.secondary_nodes))
return env, nl, nl
def CheckPrereq(self):
"""Check prerequisites.
This checks that the instance is in the cluster and is not running.
"""
instance = self.cfg.GetInstanceInfo(
self.cfg.ExpandInstanceName(self.op.instance_name))
if instance is None:
raise errors.OpPrereqError, ("Instance '%s' not known" %
self.op.instance_name)
if instance.disk_template == constants.DT_DISKLESS:
raise errors.OpPrereqError, ("Instance '%s' has no disks" %
self.op.instance_name)
if instance.status != "down":
raise errors.OpPrereqError, ("Instance '%s' is marked to be up" %
self.op.instance_name)
remote_info = rpc.call_instance_info(instance.primary_node, instance.name)
if remote_info:
raise errors.OpPrereqError, ("Instance '%s' is running on the node %s" %
(self.op.instance_name,
instance.primary_node))
self.instance = instance
def Exec(self, feedback_fn):
"""Reinstall the instance.
"""
inst = self.instance
_StartInstanceDisks(self.cfg, inst, None)
try:
feedback_fn("Running the instance OS create scripts...")
if not rpc.call_instance_os_add(inst.primary_node, inst, "sda", "sdb"):
raise errors.OpExecError, ("Could not install OS for instance %s "
"on node %s" %
(inst.name, inst.primary_node))
finally:
_ShutdownInstanceDisks(inst, self.cfg)
class LURemoveInstance(LogicalUnit): class LURemoveInstance(LogicalUnit):
"""Remove an instance. """Remove an instance.
...@@ -2395,7 +2463,7 @@ class LUCreateInstance(LogicalUnit): ...@@ -2395,7 +2463,7 @@ class LUCreateInstance(LogicalUnit):
# check primary node # check primary node
pnode = self.cfg.GetNodeInfo(self.cfg.ExpandNodeName(self.op.pnode)) pnode = self.cfg.GetNodeInfo(self.cfg.ExpandNodeName(self.op.pnode))
if pnode is None: if pnode is None:
raise errors.OpPrereqError, ("Primary node '%s' is uknown" % raise errors.OpPrereqError, ("Primary node '%s' is unknown" %
self.op.pnode) self.op.pnode)
self.op.pnode = pnode.name self.op.pnode = pnode.name
self.pnode = pnode self.pnode = pnode
...@@ -3264,7 +3332,7 @@ class LUExportInstance(LogicalUnit): ...@@ -3264,7 +3332,7 @@ class LUExportInstance(LogicalUnit):
self.dst_node = self.cfg.GetNodeInfo(dst_node_short) self.dst_node = self.cfg.GetNodeInfo(dst_node_short)
if self.dst_node is None: if self.dst_node is None:
raise errors.OpPrereqError, ("Destination node '%s' is uknown." % raise errors.OpPrereqError, ("Destination node '%s' is unknown." %
self.op.target_node) self.op.target_node)
self.op.target_node = self.dst_node.name self.op.target_node = self.dst_node.name
......
...@@ -63,6 +63,7 @@ class Processor(object): ...@@ -63,6 +63,7 @@ class Processor(object):
opcodes.OpRemoveNode: cmdlib.LURemoveNode, opcodes.OpRemoveNode: cmdlib.LURemoveNode,
# instance lu # instance lu
opcodes.OpCreateInstance: cmdlib.LUCreateInstance, opcodes.OpCreateInstance: cmdlib.LUCreateInstance,
opcodes.OpReinstallInstance: cmdlib.LUReinstallInstance,
opcodes.OpRemoveInstance: cmdlib.LURemoveInstance, opcodes.OpRemoveInstance: cmdlib.LURemoveInstance,
opcodes.OpActivateInstanceDisks: cmdlib.LUActivateInstanceDisks, opcodes.OpActivateInstanceDisks: cmdlib.LUActivateInstanceDisks,
opcodes.OpShutdownInstance: cmdlib.LUShutdownInstance, opcodes.OpShutdownInstance: cmdlib.LUShutdownInstance,
......
...@@ -139,6 +139,12 @@ class OpCreateInstance(OpCode): ...@@ -139,6 +139,12 @@ class OpCreateInstance(OpCode):
"wait_for_sync"] "wait_for_sync"]
class OpReinstallInstance(OpCode):
"""Reinstall an instance."""
OP_ID = "OP_INSTANCE_REINSTALL"
__slots__ = ["instance_name"]
class OpRemoveInstance(OpCode): class OpRemoveInstance(OpCode):
"""Remove an instance.""" """Remove an instance."""
OP_ID = "OP_INSTANCE_REMOVE" OP_ID = "OP_INSTANCE_REMOVE"
......
...@@ -100,8 +100,6 @@ def ImportInstance(opts, args): ...@@ -100,8 +100,6 @@ def ImportInstance(opts, args):
# options used in more than one cmd # options used in more than one cmd
node_opt = make_option("-n", "--node", dest="node", help="Target node", node_opt = make_option("-n", "--node", dest="node", help="Target node",
metavar="<node>") metavar="<node>")
force_opt = make_option("-f", "--force", dest="force", action="store_true",
default=False, help="Force the operation")
# this is defined separately due to readability only # this is defined separately due to readability only
import_opts = [ import_opts = [
...@@ -143,7 +141,7 @@ commands = { ...@@ -143,7 +141,7 @@ commands = {
], ],
"", "Lists instance exports available in the ganeti cluster"), "", "Lists instance exports available in the ganeti cluster"),
'export': (ExportInstance, ARGS_ONE, 'export': (ExportInstance, ARGS_ONE,
[node_opt, DEBUG_OPT, force_opt, [node_opt, DEBUG_OPT, FORCE_OPT,
make_option("","--noshutdown", dest="shutdown", make_option("","--noshutdown", dest="shutdown",
action="store_false", default=True, action="store_false", default=True,
help="Don't shutdown the instance (unsafe)"), ], help="Don't shutdown the instance (unsafe)"), ],
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
import sys import sys
import os import os
from optparse import make_option from optparse import make_option
import textwrap
from cStringIO import StringIO from cStringIO import StringIO
from ganeti.cli import * from ganeti.cli import *
...@@ -96,6 +95,28 @@ def AddInstance(opts, args): ...@@ -96,6 +95,28 @@ def AddInstance(opts, args):
return 0 return 0
def ReinstallInstance(opts, args):
"""Reinstall an instance.
Args:
opts - class with options as members
args - list containing a single element, the instance name
"""
instance_name = args[0]
if not opts.force:
usertext = ("This will reinstall the instance %s and remove "
"all data. Continue?") % instance_name
if not opts._ask_user(usertext):
return 1
op = opcodes.OpReinstallInstance(instance_name=instance_name)
SubmitOpCode(op)
return 0
def RemoveInstance(opts, args): def RemoveInstance(opts, args):
"""Remove an instance. """Remove an instance.
...@@ -244,7 +265,6 @@ def FailoverInstance(opts, args): ...@@ -244,7 +265,6 @@ def FailoverInstance(opts, args):
usertext = ("Failover will happen to image %s." usertext = ("Failover will happen to image %s."
" This requires a shutdown of the instance. Continue?" % " This requires a shutdown of the instance. Continue?" %
(instance_name,)) (instance_name,))
usertext = textwrap.fill(usertext)
if not opts._ask_user(usertext): if not opts._ask_user(usertext):
return 1 return 1
...@@ -400,8 +420,6 @@ def SetInstanceParms(opts, args): ...@@ -400,8 +420,6 @@ def SetInstanceParms(opts, args):
# options used in more than one cmd # options used in more than one cmd
node_opt = make_option("-n", "--node", dest="node", help="Target node", node_opt = make_option("-n", "--node", dest="node", help="Target node",
metavar="<node>") metavar="<node>")
force_opt = make_option("-f", "--force", dest="force", action="store_true",
default=False, help="Force the operation")
# this is defined separately due to readability only # this is defined separately due to readability only
add_opts = [ add_opts = [
...@@ -448,7 +466,7 @@ commands = { ...@@ -448,7 +466,7 @@ commands = {
"<instance>", "<instance>",
"Opens a console on the specified instance"), "Opens a console on the specified instance"),
'failover': (FailoverInstance, ARGS_ONE, 'failover': (FailoverInstance, ARGS_ONE,
[DEBUG_OPT, force_opt, [DEBUG_OPT, FORCE_OPT,
make_option("--ignore-consistency", dest="ignore_consistency", make_option("--ignore-consistency", dest="ignore_consistency",
action="store_true", default=False, action="store_true", default=False,
help="Ignore the consistency of the disks on" help="Ignore the consistency of the disks on"
...@@ -462,7 +480,9 @@ commands = { ...@@ -462,7 +480,9 @@ commands = {
'list': (ListInstances, ARGS_NONE, 'list': (ListInstances, ARGS_NONE,
[DEBUG_OPT, NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT], [DEBUG_OPT, NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT],
"", "Lists the instances and their status"), "", "Lists the instances and their status"),
'remove': (RemoveInstance, ARGS_ONE, [DEBUG_OPT, force_opt], 'reinstall': (ReinstallInstance, ARGS_ONE, [DEBUG_OPT, FORCE_OPT],
"[-f] <instance>", "Reinstall the instance"),
'remove': (RemoveInstance, ARGS_ONE, [DEBUG_OPT, FORCE_OPT],
"[-f] <instance>", "Shuts down the instance and removes it"), "[-f] <instance>", "Shuts down the instance and removes it"),
'remove-mirror': (RemoveMDDRBDComponent, ARGS_ONE, 'remove-mirror': (RemoveMDDRBDComponent, ARGS_ONE,
[DEBUG_OPT, node_opt, [DEBUG_OPT, node_opt,
...@@ -484,9 +504,8 @@ commands = { ...@@ -484,9 +504,8 @@ commands = {
" change the secondary)"))], " change the secondary)"))],
"[-n NODE] <instance>", "[-n NODE] <instance>",
"Replaces all disks for the instance"), "Replaces all disks for the instance"),
'modify': (SetInstanceParms, ARGS_ONE, 'modify': (SetInstanceParms, ARGS_ONE,
[DEBUG_OPT, force_opt, [DEBUG_OPT, FORCE_OPT,
cli_option("-m", "--memory", dest="mem", cli_option("-m", "--memory", dest="mem",
help="Memory size", help="Memory size",
default=None, type="unit", metavar="<mem>"), default=None, type="unit", metavar="<mem>"),
...@@ -504,7 +523,7 @@ commands = { ...@@ -504,7 +523,7 @@ commands = {
'shutdown': (ShutdownInstance, ARGS_ONE, [DEBUG_OPT], 'shutdown': (ShutdownInstance, ARGS_ONE, [DEBUG_OPT],
"<instance>", "Stops an instance"), "<instance>", "Stops an instance"),
'startup': (StartupInstance, ARGS_ONE, 'startup': (StartupInstance, ARGS_ONE,
[DEBUG_OPT, force_opt, [DEBUG_OPT, FORCE_OPT,
make_option("-e", "--extra", dest="extra_args", make_option("-e", "--extra", dest="extra_args",
help="Extra arguments for the instance's kernel", help="Extra arguments for the instance's kernel",
default=None, type="string", metavar="<PARAMS>"), default=None, type="string", metavar="<PARAMS>"),
......
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