_ShutdownInstanceDisks(self, inst)
+class LURecreateInstanceDisks(LogicalUnit):
+ """Recreate an instance's missing disks.
+
+ """
+ HPATH = "instance-recreate-disks"
+ HTYPE = constants.HTYPE_INSTANCE
+ _OP_REQP = ["instance_name", "disks"]
+ REQ_BGL = False
+
+ def CheckArguments(self):
+ """Check the arguments.
+
+ """
+ if not isinstance(self.op.disks, list):
+ raise errors.OpPrereqError("Invalid disks parameter")
+ for item in self.op.disks:
+ if (not isinstance(item, int) or
+ item < 0):
+ raise errors.OpPrereqError("Invalid disk specification '%s'" %
+ str(item))
+
+ def ExpandNames(self):
+ self._ExpandAndLockInstance()
+
+ def BuildHooksEnv(self):
+ """Build hooks env.
+
+ This runs on master, primary and secondary nodes of the instance.
+
+ """
+ env = _BuildInstanceHookEnvByObject(self, self.instance)
+ nl = [self.cfg.GetMasterNode()] + list(self.instance.all_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.op.instance_name)
+ assert instance is not None, \
+ "Cannot retrieve locked instance %s" % self.op.instance_name
+ _CheckNodeOnline(self, instance.primary_node)
+
+ if instance.disk_template == constants.DT_DISKLESS:
+ raise errors.OpPrereqError("Instance '%s' has no disks" %
+ self.op.instance_name)
+ if instance.admin_up:
+ raise errors.OpPrereqError("Instance '%s' is marked to be up" %
+ self.op.instance_name)
+ remote_info = self.rpc.call_instance_info(instance.primary_node,
+ instance.name,
+ instance.hypervisor)
+ remote_info.Raise("Error checking node %s" % instance.primary_node,
+ prereq=True)
+ if remote_info.payload:
+ raise errors.OpPrereqError("Instance '%s' is running on the node %s" %
+ (self.op.instance_name,
+ instance.primary_node))
+
+ if not self.op.disks:
+ self.op.disks = range(len(instance.disks))
+ else:
+ for idx in self.op.disks:
+ if idx >= len(instance.disks):
+ raise errors.OpPrereqError("Invalid disk index passed '%s'" % idx)
+
+ self.instance = instance
+
+ def Exec(self, feedback_fn):
+ """Recreate the disks.
+
+ """
+ to_skip = []
+ for idx, disk in enumerate(self.instance.disks):
+ if idx not in self.op.disks: # disk idx has not been passed in
+ to_skip.append(idx)
+ continue
+
+ _CreateDisks(self, self.instance, to_skip=to_skip)
+
+
class LURenameInstance(LogicalUnit):
"""Rename an instance.
return "originstname+%s" % instance.name
-def _CreateDisks(lu, instance):
+def _CreateDisks(lu, instance, to_skip=None):
"""Create all disks for an instance.
This abstracts away some work from AddInstance.
@param lu: the logical unit on whose behalf we execute
@type instance: L{objects.Instance}
@param instance: the instance whose disks we should create
+ @type to_skip: list
+ @param to_skip: list of indices to skip
@rtype: boolean
@return: the success of the creation
# Note: this needs to be kept in sync with adding of disks in
# LUSetInstanceParams
- for device in instance.disks:
+ for idx, device in enumerate(instance.disks):
+ if to_skip and idx in to_skip:
+ continue
logging.info("Creating volume %s for instance %s",
device.iv_name, instance.name)
#HARDCODE
opcodes.OpRebootInstance: cmdlib.LURebootInstance,
opcodes.OpDeactivateInstanceDisks: cmdlib.LUDeactivateInstanceDisks,
opcodes.OpReplaceDisks: cmdlib.LUReplaceDisks,
+ opcodes.OpRecreateInstanceDisks: cmdlib.LURecreateInstanceDisks,
opcodes.OpFailoverInstance: cmdlib.LUFailoverInstance,
opcodes.OpMigrateInstance: cmdlib.LUMigrateInstance,
opcodes.OpConnectConsole: cmdlib.LUConnectConsole,
__slots__ = OpCode.__slots__ + ["instance_name"]
+class OpRecreateInstanceDisks(OpCode):
+ """Deactivate an instance's disks."""
+ OP_ID = "OP_INSTANCE_RECREATE_DISKS"
+ OP_DSC_FIELD = "instance_name"
+ __slots__ = OpCode.__slots__ + ["instance_name", "disks"]
+
+
class OpQueryInstances(OpCode):
"""Compute the list of instances."""
OP_ID = "OP_INSTANCE_QUERY"
</para>
</refsect3>
+ <refsect3>
+ <title>RECREATE-DISKS</title>
+
+ <cmdsynopsis>
+ <command>recreate-disks</command>
+ <arg>--submit</arg>
+ <arg>--disks=<option>indices</option></arg>
+ <arg choice="req"><replaceable>instance</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Recreates the disks of the given instance, or only a subset
+ of the disks (if the option <option>disks</option> is
+ passed, which must be a comma-separated list of disk
+ indices, starting from zero).
+ </para>
+
+ <para>
+ The <option>--submit</option> option is used to send the job to
+ the master daemon but not wait for its completion. The job
+ ID will be shown so that it can be examined via
+ <command>gnt-job info</command>.
+ </para>
+
+ </refsect3>
+
</refsect2>
<refsect2>
def DeactivateDisks(opts, args):
- """Deactivate an instance's disks..
+ """Deactivate an instance's disks.
This function takes the instance name, looks for its primary node
and the tries to shutdown its block devices on that node.
return 0
+def RecreateDisks(opts, args):
+ """Recreate an instance's disks.
+
+ @param opts: the command line options selected by the user
+ @type args: list
+ @param args: should contain only one element, the instance name
+ @rtype: int
+ @return: the desired exit code
+
+ """
+ instance_name = args[0]
+ if opts.disks:
+ try:
+ opts.disks = [int(v) for v in opts.disks.split(",")]
+ except (ValueError, TypeError), err:
+ ToStderr("Invalid disks value: %s" % str(err))
+ return 1
+ else:
+ opts.disks = []
+
+ op = opcodes.OpRecreateInstanceDisks(instance_name=instance_name,
+ disks=opts.disks)
+ SubmitOrSend(op, opts)
+ return 0
+
+
def GrowDisk(opts, args):
"""Grow an instance's disks.
'deactivate-disks': (DeactivateDisks, ARGS_ONE, [DEBUG_OPT, SUBMIT_OPT],
"<instance>",
"Deactivate an instance's disks"),
+ 'recreate-disks': (RecreateDisks, ARGS_ONE,
+ [DEBUG_OPT, SUBMIT_OPT,
+ make_option("--disks", dest="disks", default=None,
+ help="Comma-separated list of disks"
+ " indices to replace (e.g. 0,2) (optional,"
+ " defaults to all disks)"),
+ ],
+ "<instance>",
+ "Recreate an instance's disks"),
'grow-disk': (GrowDisk, ARGS_FIXED(3),
[DEBUG_OPT, SUBMIT_OPT,
make_option("--no-wait-for-sync",