diff --git a/lib/cmdlib.py b/lib/cmdlib.py index ff6dbc359526e72e8aaa18b2f5b9c5cc8cec191a..1a9e85f9f89a72fed66fb9a4ff120b99cff2cdbb 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -2761,6 +2761,34 @@ class LUStartupInstance(LogicalUnit): assert self.instance is not None, \ "Cannot retrieve locked instance %s" % self.op.instance_name + # extra beparams + self.beparams = getattr(self.op, "beparams", {}) + if self.beparams: + if not isinstance(self.beparams, dict): + raise errors.OpPrereqError("Invalid beparams passed: %s, expected" + " dict" % (type(self.beparams), )) + # fill the beparams dict + utils.ForceDictType(self.beparams, constants.BES_PARAMETER_TYPES) + self.op.beparams = self.beparams + + # extra hvparams + self.hvparams = getattr(self.op, "hvparams", {}) + if self.hvparams: + if not isinstance(self.hvparams, dict): + raise errors.OpPrereqError("Invalid hvparams passed: %s, expected" + " dict" % (type(self.hvparams), )) + + # check hypervisor parameter syntax (locally) + cluster = self.cfg.GetClusterInfo() + utils.ForceDictType(self.hvparams, constants.HVS_PARAMETER_TYPES) + filled_hvp = cluster.FillDict(cluster.hvparams[instance.hypervisor], + instance.hvparams) + filled_hvp.update(self.hvparams) + hv_type = hypervisor.GetHypervisor(instance.hypervisor) + hv_type.CheckParameterSyntax(filled_hvp) + _CheckHVParams(self, instance.all_nodes, instance.hypervisor, filled_hvp) + self.op.hvparams = self.hvparams + _CheckNodeOnline(self, instance.primary_node) bep = self.cfg.GetClusterInfo().FillBE(instance) @@ -2789,7 +2817,8 @@ class LUStartupInstance(LogicalUnit): _StartInstanceDisks(self, instance, force) - result = self.rpc.call_instance_start(node_current, instance, None, None) + result = self.rpc.call_instance_start(node_current, instance, + self.hvparams, self.beparams) msg = result.RemoteFailMsg() if msg: _ShutdownInstanceDisks(self, instance) diff --git a/lib/opcodes.py b/lib/opcodes.py index 5be660bdc797b9b2e219b443b9367509f26c1051..535db910d0b38fba6c055dc24c0ed0ea1f943117 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -382,7 +382,7 @@ class OpStartupInstance(OpCode): """Startup an instance.""" OP_ID = "OP_INSTANCE_STARTUP" OP_DSC_FIELD = "instance_name" - __slots__ = ["instance_name", "force"] + __slots__ = ["instance_name", "force", "hvparams", "beparams"] class OpShutdownInstance(OpCode): diff --git a/man/gnt-instance.sgml b/man/gnt-instance.sgml index 176f70c0d737cac032e1bbe3f9d21be11b4a45ae..edf267eecac141efb276cbcf64f7983ce783218b 100644 --- a/man/gnt-instance.sgml +++ b/man/gnt-instance.sgml @@ -1127,7 +1127,7 @@ instance5: 11225 <para> Show detailed information about the given instance(s). This is different from <command>list</command> as it shows detailed data - about the instance's disks (especially useful for the drbd disk + about the instance's disks (especially useful for the drbd disk template). </para> @@ -1314,6 +1314,9 @@ instance5: 11225 <arg>--all</arg> </group> <sbr> + <arg>-H <option>key=value...</option></arg> + <arg>-B <option>key=value...</option></arg> + <sbr> <arg>--submit</arg> <sbr> <arg choice="opt" @@ -1382,6 +1385,23 @@ instance5: 11225 instance will be affected. </para> + <para> + The <option>-H</option> and <option>-B</option> options + specify extra, temporary hypervisor and backend parameters + that can be used to start an instance with modified + parameters. They can be useful for quick testing without + having to modify an instance back and forth, e.g.: + <screen> +# gnt-instance start -H root_args="single" instance1 +# gnt-instance start -B memory=2048 instance2 + </screen> + The first form will start the instance + <userinput>instance1</userinput> in single-user mode, and + the instance <userinput>instance2</userinput> with 2GB of + RAM (this time only, unless that is the actual instance + memory size already). + </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 diff --git a/scripts/gnt-instance b/scripts/gnt-instance index 62a1f038e59f88a74e6e3ec07c08384d228e37a9..7b93e3bc150b53eb6663cb5e5560a05fb6055822 100755 --- a/scripts/gnt-instance +++ b/scripts/gnt-instance @@ -710,6 +710,11 @@ def StartupInstance(opts, args): for name in inames: op = opcodes.OpStartupInstance(instance_name=name, force=opts.force) + # do not add these parameters to the opcode unless they're defined + if opts.hvparams: + op.hvparams = opts.hvparams + if opts.beparams: + op.beparams = opts.beparams jex.QueueJob(name, op) jex.WaitOrShow(not opts.submit_only) return 0 @@ -1472,8 +1477,14 @@ commands = { m_node_opt, m_pri_node_opt, m_sec_node_opt, m_clust_opt, m_inst_opt, SUBMIT_OPT, + keyval_option("-H", "--hypervisor", type="keyval", + default={}, dest="hvparams", + help="Temporary hypervisor parameters"), + keyval_option("-B", "--backend", type="keyval", + default={}, dest="beparams", + help="Temporary backend parameters"), ], - "<instance>", "Starts an instance"), + "<instance>", "Starts an instance"), 'reboot': (RebootInstance, ARGS_ANY, [DEBUG_OPT, m_force_multi,