+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 = _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 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.op.os_type = getattr(self.op, "os_type", None)
+ if self.op.os_type is not None:
+ # OS verification
+ pnode = self.cfg.GetNodeInfo(
+ self.cfg.ExpandNodeName(instance.primary_node))
+ if pnode is None:
+ raise errors.OpPrereqError("Primary node '%s' is unknown" %
+ self.op.pnode)
+ os_obj = rpc.call_os_get([pnode.name], self.op.os_type)[pnode.name]
+ if not isinstance(os_obj, objects.OS):
+ raise errors.OpPrereqError("OS '%s' not in supported OS list for"
+ " primary node" % self.op.os_type)
+
+ self.instance = instance
+
+ def Exec(self, feedback_fn):
+ """Reinstall the instance.
+
+ """
+ inst = self.instance
+
+ if self.op.os_type is not None:
+ feedback_fn("Changing OS to '%s'..." % self.op.os_type)
+ inst.os = self.op.os_type
+ self.cfg.AddInstance(inst)
+
+ _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 LURenameInstance(LogicalUnit):
+ """Rename an instance.
+
+ """
+ HPATH = "instance-rename"
+ HTYPE = constants.HTYPE_INSTANCE
+ _OP_REQP = ["instance_name", "new_name"]
+
+ def BuildHooksEnv(self):
+ """Build hooks env.
+
+ This runs on master, primary and secondary nodes of the instance.
+
+ """
+ env = _BuildInstanceHookEnvByObject(self.instance)
+ env["INSTANCE_NEW_NAME"] = self.op.new_name
+ 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.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
+
+ # new name verification
+ name_info = utils.HostInfo(self.op.new_name)
+
+ self.op.new_name = new_name = name_info.name
+ if not getattr(self.op, "ignore_ip", False):
+ command = ["fping", "-q", name_info.ip]
+ result = utils.RunCmd(command)
+ if not result.failed:
+ raise errors.OpPrereqError("IP %s of instance %s already in use" %
+ (name_info.ip, new_name))
+
+
+ def Exec(self, feedback_fn):
+ """Reinstall the instance.
+
+ """
+ inst = self.instance
+ old_name = inst.name
+
+ self.cfg.RenameInstance(inst.name, self.op.new_name)
+
+ # re-read the instance from the configuration after rename
+ inst = self.cfg.GetInstanceInfo(self.op.new_name)
+
+ _StartInstanceDisks(self.cfg, inst, None)
+ try:
+ if not rpc.call_instance_run_rename(inst.primary_node, inst, old_name,
+ "sda", "sdb"):
+ msg = ("Could run OS rename script for instance %s\n"
+ "on node %s\n"
+ "(but the instance has been renamed in Ganeti)" %
+ (inst.name, inst.primary_node))
+ logger.Error(msg)
+ finally:
+ _ShutdownInstanceDisks(inst, self.cfg)
+
+