From bf6929a22dc99c0da5404b1e55569e14db820956 Mon Sep 17 00:00:00 2001 From: Alexander Schreiber <als@google.com> Date: Thu, 18 Oct 2007 10:25:50 +0000 Subject: [PATCH] Patch series for reboot feature, part 2 This patch series implements the reboot command for gnt-instance. It supports three types of reboot: soft (hypervisor reboot), hard (instance config rebuild and reboot) and full (full instance shutdown and startup again). This patch contains the opcode and lu part. Reviewed-by: iustinp --- lib/cmdlib.py | 94 +++++++++++++++++++++++++++++++++++++++++++++++--- lib/mcpu.py | 1 + lib/opcodes.py | 7 ++++ 3 files changed, 97 insertions(+), 5 deletions(-) diff --git a/lib/cmdlib.py b/lib/cmdlib.py index f84ac6337..2fce8a2a5 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -528,6 +528,18 @@ def _InitGanetiServerSetup(ss): (result.cmd, result.exit_code, result.output)) +def _CheckInstanceBridgesExist(instance): + """Check that the brigdes needed by an instance exist. + + """ + # check bridges existance + brlist = [nic.bridge for nic in instance.nics] + if not rpc.call_bridges_exist(instance.primary_node, brlist): + raise errors.OpPrereqError("one or more target bridges %s does not" + " exist on destination node '%s'" % + (brlist, instance.primary_node)) + + class LUInitCluster(LogicalUnit): """Initialise the cluster. @@ -1934,11 +1946,7 @@ class LUStartupInstance(LogicalUnit): self.op.instance_name) # check bridges existance - brlist = [nic.bridge for nic in instance.nics] - if not rpc.call_bridges_exist(instance.primary_node, brlist): - raise errors.OpPrereqError("one or more target bridges %s does not" - " exist on destination node '%s'" % - (brlist, instance.primary_node)) + _CheckInstanceBridgesExist(instance) self.instance = instance self.op.instance_name = instance.name @@ -1976,6 +1984,82 @@ class LUStartupInstance(LogicalUnit): self.cfg.MarkInstanceUp(instance.name) +class LURebootInstance(LogicalUnit): + """Reboot an instance. + + """ + HPATH = "instance-reboot" + HTYPE = constants.HTYPE_INSTANCE + _OP_REQP = ["instance_name", "ignore_secondaries", "reboot_type"] + + def BuildHooksEnv(self): + """Build hooks env. + + This runs on master, primary and secondary nodes of the instance. + + """ + env = { + "IGNORE_SECONDARIES": self.op.ignore_secondaries, + } + env.update(_BuildInstanceHookEnvByObject(self.instance)) + 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. + + """ + 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) + + # check bridges existance + _CheckInstanceBridgesExist(instance) + + self.instance = instance + self.op.instance_name = instance.name + + def Exec(self, feedback_fn): + """Reboot the instance. + + """ + instance = self.instance + ignore_secondaries = self.op.ignore_secondaries + reboot_type = self.op.reboot_type + extra_args = getattr(self.op, "extra_args", "") + + node_current = instance.primary_node + + if reboot_type not in [constants.INSTANCE_REBOOT_SOFT, + constants.INSTANCE_REBOOT_HARD, + constants.INSTANCE_REBOOT_FULL]: + raise errors.ParameterError("reboot type not in [%s, %s, %s]" % + (constants.INSTANCE_REBOOT_SOFT, + constants.INSTANCE_REBOOT_HARD, + constants.INSTANCE_REBOOT_FULL)) + + if reboot_type in [constants.INSTANCE_REBOOT_SOFT, + constants.INSTANCE_REBOOT_HARD]: + if not rpc.call_instance_reboot(node_current, instance, + reboot_type, extra_args): + raise errors.OpExecError("Could not reboot instance") + else: + if not rpc.call_instance_shutdown(node_current, instance): + raise errors.OpExecError("could not shutdown instance for full reboot") + _ShutdownInstanceDisks(instance, self.cfg) + _StartInstanceDisks(self.cfg, instance, ignore_secondaries) + if not rpc.call_instance_start(node_current, instance, extra_args): + _ShutdownInstanceDisks(instance, self.cfg) + raise errors.OpExecError("Could not start instance for full reboot") + + self.cfg.MarkInstanceUp(instance.name) + + class LUShutdownInstance(LogicalUnit): """Shutdown an instance. diff --git a/lib/mcpu.py b/lib/mcpu.py index 0eb4324a1..2f89842fb 100644 --- a/lib/mcpu.py +++ b/lib/mcpu.py @@ -63,6 +63,7 @@ class Processor(object): opcodes.OpActivateInstanceDisks: cmdlib.LUActivateInstanceDisks, opcodes.OpShutdownInstance: cmdlib.LUShutdownInstance, opcodes.OpStartupInstance: cmdlib.LUStartupInstance, + opcodes.OpRebootInstance: cmdlib.LURebootInstance, opcodes.OpDeactivateInstanceDisks: cmdlib.LUDeactivateInstanceDisks, opcodes.OpAddMDDRBDComponent: cmdlib.LUAddMDDRBDComponent, opcodes.OpRemoveMDDRBDComponent: cmdlib.LURemoveMDDRBDComponent, diff --git a/lib/opcodes.py b/lib/opcodes.py index 5e11fbae8..e06a37ec9 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -171,6 +171,13 @@ class OpShutdownInstance(OpCode): __slots__ = ["instance_name"] +class OpRebootInstance(OpCode): + """Reboot an instance.""" + OP_ID = "OP_INSTANCE_STARTUP" + __slots__ = ["instance_name", "reboot_type", "extra_args", + "ignore_secondaries" ] + + class OpAddMDDRBDComponent(OpCode): """Add a MD-DRBD component.""" OP_ID = "OP_INSTANCE_ADD_MDDRBD" -- GitLab