diff --git a/doc/hooks.sgml b/doc/hooks.sgml index daa1d07e867c9c44f42678fb398f6497191f06a7..b6cf2e956a3a111667f2f2377a5e605b0ac8b2a6 100644 --- a/doc/hooks.sgml +++ b/doc/hooks.sgml @@ -256,6 +256,7 @@ <entry>Remove an instance</entry> <entry><computeroutput>gnt-instance remove</computeroutput></entry> <entry><constant>INSTANCE_NAME</constant>, <constant>INSTANCE_PRIMARY</constant>, <constant>INSTANCE_SECONDARIES</constant></entry> + <entry spanname="bothhooks">master node</entry> </row> <row> <entry>OP_INSTANCE_ADD_MDDRBD</entry> diff --git a/lib/cmdlib.py b/lib/cmdlib.py index ea563459123ff54db3f2a7413975ea5a6add63bd..d41ed5af9a3fbe208722fd3c775527576224c126 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -2193,8 +2193,7 @@ class LURemoveInstance(LogicalUnit): """ env = _BuildInstanceHookEnvByObject(self.instance) - nl = ([self.sstore.GetMasterNode(), self.instance.primary_node] + - list(self.instance.secondary_nodes)) + nl = [self.sstore.GetMasterNode()] return env, nl, nl def CheckPrereq(self): @@ -2219,12 +2218,19 @@ class LURemoveInstance(LogicalUnit): (instance.name, instance.primary_node)) if not rpc.call_instance_shutdown(instance.primary_node, instance): - raise errors.OpExecError("Could not shutdown instance %s on node %s" % - (instance.name, instance.primary_node)) + if self.op.ignore_failures: + feedback_fn("Warning: can't shutdown instance") + else: + raise errors.OpExecError("Could not shutdown instance %s on node %s" % + (instance.name, instance.primary_node)) logger.Info("removing block devices for instance %s" % instance.name) - _RemoveDisks(instance, self.cfg) + if not _RemoveDisks(instance, self.cfg): + if self.op.ignore_failures: + feedback_fn("Warning: can't remove instance's disks") + else: + raise errors.OpExecError("Can't remove instance's disks") logger.Info("removing instance %s out of cluster config" % instance.name) @@ -2649,7 +2655,7 @@ def _RemoveDisks(instance, cfg): This abstracts away some work from `AddInstance()` and `RemoveInstance()`. Note that in case some of the devices couldn't - be remove, the removal will continue with the other ones (compare + be removed, the removal will continue with the other ones (compare with `_CreateDisks()`). Args: diff --git a/lib/opcodes.py b/lib/opcodes.py index 7beb299d6dc6f42d91171fadce89c9ce9df97e7c..5e11fbae858624a8e877ce84648fe9fb1df42990 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -150,7 +150,7 @@ class OpReinstallInstance(OpCode): class OpRemoveInstance(OpCode): """Remove an instance.""" OP_ID = "OP_INSTANCE_REMOVE" - __slots__ = ["instance_name"] + __slots__ = ["instance_name", "ignore_failures"] class OpRenameInstance(OpCode): diff --git a/man/gnt-instance.sgml b/man/gnt-instance.sgml index 9ada7c76f9ae9e1669a65208c75d28dc68887321..f31dca2fafa982ac72f589111171abf8dbc6764e 100644 --- a/man/gnt-instance.sgml +++ b/man/gnt-instance.sgml @@ -196,6 +196,7 @@ <cmdsynopsis> <command>remove</command> + <arg>--ignore-failures</arg> <arg choice="req"><replaceable>instance</replaceable></arg> </cmdsynopsis> @@ -205,6 +206,15 @@ you are not sure if you use an instance again, use <command>shutdown</command> first and leave it in the shutdown state for a while. + + </para> + + <para> + The <option>--ignore-failures</option> option will cause the + removal to proceed even in the presence of errors during the + removal of the instance (e.g. during the shutdown or the + disk removal). If this option is not given, the command will + stop at the first error. </para> <para> diff --git a/scripts/gnt-instance b/scripts/gnt-instance index 5768b44ec9882419e5c33986f886f443a1ce95a1..943f4899b9ad13b76f8eec710f37e26a63fa40a3 100755 --- a/scripts/gnt-instance +++ b/scripts/gnt-instance @@ -270,7 +270,8 @@ def RemoveInstance(opts, args): if not AskUser(usertext): return 1 - op = opcodes.OpRemoveInstance(instance_name=instance_name) + op = opcodes.OpRemoveInstance(instance_name=instance_name, + ignore_failures=opts.ignore_failures) SubmitOpCode(op) return 0 @@ -689,7 +690,14 @@ commands = { "", "Lists the instances and their status"), 'reinstall': (ReinstallInstance, ARGS_ONE, [DEBUG_OPT, FORCE_OPT, os_opt], "[-f] <instance>", "Reinstall the instance"), - 'remove': (RemoveInstance, ARGS_ONE, [DEBUG_OPT, FORCE_OPT], + 'remove': (RemoveInstance, ARGS_ONE, + [DEBUG_OPT, FORCE_OPT, + make_option("--ignore-failures", dest="ignore_failures", + action="store_true", default=False, + help=("Remove the instance from the cluster even" + " if there are failures during the removal" + " process (shutdown, disk removal, etc.)")), + ], "[-f] <instance>", "Shuts down the instance and removes it"), 'remove-mirror': (RemoveMDDRBDComponent, ARGS_ONE, [DEBUG_OPT, node_opt,