diff --git a/lib/cmdlib.py b/lib/cmdlib.py index a625dcde4283c3713614b2eed125fc1b3a3f797a..bb998063e40d9f00c9dea16e4abb6fb498e7e5c1 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -3049,6 +3049,12 @@ class LUCreateInstance(LogicalUnit): " destination node '%s'" % (self.op.bridge, pnode.name)) + # boot order verification + if self.op.hvm_boot_order is not None: + if len(self.op.hvm_boot_order.strip("acdn")) != 0: + raise errors.OpPrereqError("invalid boot order specified," + " must be one or more of [acdn]") + if self.op.start: self.instance_status = 'up' else: @@ -3092,6 +3098,7 @@ class LUCreateInstance(LogicalUnit): network_port=network_port, kernel_path=self.op.kernel_path, initrd_path=self.op.initrd_path, + hvm_boot_order=self.op.hvm_boot_order, ) feedback_fn("* creating instance disks...") @@ -4110,8 +4117,9 @@ class LUSetInstanceParms(LogicalUnit): self.bridge = getattr(self.op, "bridge", None) self.kernel_path = getattr(self.op, "kernel_path", None) self.initrd_path = getattr(self.op, "initrd_path", None) + self.hvm_boot_order = getattr(self.op, "hvm_boot_order", None) all_parms = [self.mem, self.vcpus, self.ip, self.bridge, self.mac, - self.kernel_path, self.initrd_path] + self.kernel_path, self.initrd_path, self.hvm_boot_order] if all_parms.count(None) == len(all_parms): raise errors.OpPrereqError("No changes submitted") if self.mem is not None: @@ -4163,6 +4171,14 @@ class LUSetInstanceParms(LogicalUnit): else: self.do_initrd_path = False + # boot order verification + if self.hvm_boot_order is not None: + if self.hvm_boot_order != constants.VALUE_DEFAULT: + if len(self.hvm_boot_order.strip("acdn")) != 0: + raise errors.OpPrereqError("invalid boot order specified," + " must be one or more of [acdn]" + " or 'default'") + instance = self.cfg.GetInstanceInfo( self.cfg.ExpandInstanceName(self.op.instance_name)) if instance is None: @@ -4200,6 +4216,12 @@ class LUSetInstanceParms(LogicalUnit): if self.do_initrd_path: instance.initrd_path = self.initrd_path result.append(("initrd_path", self.initrd_path)) + if self.hvm_boot_order: + if self.hvm_boot_order == constants.VALUE_DEFAULT: + instance.hvm_boot_order = None + else: + instance.hvm_boot_order = self.hvm_boot_order + result.append(("hvm_boot_order", self.hvm_boot_order)) self.cfg.AddInstance(instance) diff --git a/lib/constants.py b/lib/constants.py index 47db98e5e6a797e79ca6e981620604e915403448..81876dd1d4d23cc89e3bac499130ebccfeb3668f 100644 --- a/lib/constants.py +++ b/lib/constants.py @@ -159,4 +159,5 @@ HYPER_TYPES = frozenset([HT_XEN_PVM30, HT_FAKE, HT_XEN_HVM31]) HTS_REQ_PORT = frozenset([HT_XEN_HVM31]) HT_HVM_VNC_BASE_PORT = 5900 +HT_HVM_DEFAULT_BOOT_ORDER = 'dc' VNC_PASSWORD_FILE = _autoconf.SYSCONFDIR + "/ganeti/vnc-cluster-password" diff --git a/lib/hypervisor.py b/lib/hypervisor.py index d3b7e870933ac22bf923a79851d082db706d1f76..e77e4b8d8854f0db7392906c4c6fff2db95bfd6a 100644 --- a/lib/hypervisor.py +++ b/lib/hypervisor.py @@ -596,7 +596,10 @@ class XenHvmHypervisor(XenHypervisor): config.write("device_model = '/usr/lib64/xen/bin/qemu-dm'\n") else: config.write("device_model = '/usr/lib/xen/bin/qemu-dm'\n") - config.write("boot = 'dc'\n") + if instance.hvm_boot_order is None: + config.write("boot = '%s'\n" % constants.HT_HVM_DEFAULT_BOOT_ORDER) + else: + config.write("boot = '%s'\n" % instance.hvm_boot_order) config.write("sdl = 0\n") config.write("vnc = 1\n") config.write("vnclisten = '0.0.0.0'\n") diff --git a/lib/opcodes.py b/lib/opcodes.py index 3aa3a2cdfb6be24b5f59823471999e469234a45a..73afaf8c7743b066c0b1ce907a81b7a0682cf573 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -165,7 +165,7 @@ class OpCreateInstance(OpCode): "disk_template", "snode", "swap_size", "mode", "vcpus", "ip", "bridge", "src_node", "src_path", "start", "wait_for_sync", "ip_check", "mac", - "kernel_path", "initrd_path", + "kernel_path", "initrd_path", "hvm_boot_order", ] @@ -265,7 +265,7 @@ class OpSetInstanceParms(OpCode): OP_ID = "OP_INSTANCE_SET_PARMS" __slots__ = [ "instance_name", "mem", "vcpus", "ip", "bridge", "mac", - "kernel_path", "initrd_path", + "kernel_path", "initrd_path", "hvm_boot_order", ] diff --git a/man/gnt-instance.sgml b/man/gnt-instance.sgml index a96fd8f2142082ae994e4e2a5205c7ba471a7065..36a6c14688881e03a66a623956bdff3bfc7a2b2c 100644 --- a/man/gnt-instance.sgml +++ b/man/gnt-instance.sgml @@ -69,6 +69,7 @@ <arg>-o <replaceable>os-type</replaceable></arg> <arg>-b <replaceable>bridge</replaceable></arg> <arg>--mac <replaceable>MAC-address</replaceable></arg> + <arg>--hvm-boot-order <replaceable>boot-order</replaceable></arg> <sbr> <arg>--kernel <group choice="req"> <arg>default</arg> @@ -146,6 +147,55 @@ this cluster. </para> + <para> + The <option>--hvm-boot-order</option> option specifies the + boot device order for Xen HVM instances. The boot order is a + string of letters listing the boot devices, with valid + device letters being: + </para> + + <para> + <variablelist> + <varlistentry> + <term>a</term> + <listitem> + <para> + floppy drive + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>c</term> + <listitem> + <para> + hard disk + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>d</term> + <listitem> + <para> + CDROM drive + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>n</term> + <listitem> + <para> + network boot (PXE) + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + + <para> + The option is only relevant for Xen HVM instances and + ignored by all other instances types. + </para> + <para> The <option>--kernel</option> options allows the instance to use a custom kernel (if a filename is passed) or to use the @@ -439,6 +489,7 @@ <arg choice="opt">-i <replaceable>ip</replaceable></arg> <arg choice="opt">-b <replaceable>bridge</replaceable></arg> <arg choice="opt">--mac <replaceable>MAC-address</replaceable></arg> + <arg>--hvm-boot-order <replaceable>boot-order</replaceable></arg> <sbr> <arg>--kernel <group choice="req"> <arg>default</arg> @@ -466,10 +517,16 @@ </para> <para> - The <option>--kernel</option> and <option>--initrd</option> + The <option>--kernel</option>, <option>--initrd</option> + and <option>--hvm-boot-order</option> options are described in the <command>add</command> command. </para> + <para> + Additionally, the HVM boot order can be reset to the default + values by using <option>--hvm-boot-order=default</option>. + </para> + <para> All the changes take effect at the next restart. If the instance is running, there is no effect on the instance. diff --git a/scripts/gnt-instance b/scripts/gnt-instance index f230714f01dd01f32f9585d575ce7b0c77e2c668..d89cce9fe9eb49311a43ffe60d189c07976b69ca 100755 --- a/scripts/gnt-instance +++ b/scripts/gnt-instance @@ -255,7 +255,8 @@ def AddInstance(opts, args): wait_for_sync=opts.wait_for_sync, mac=opts.mac, kernel_path=kernel_path, - initrd_path=initrd_path) + initrd_path=initrd_path, + hvm_boot_order=opts.hvm_boot_order) SubmitOpCode(op) return 0 @@ -669,18 +670,23 @@ def SetInstanceParms(opts, args): """ if not (opts.mem or opts.vcpus or opts.ip or opts.bridge or opts.mac or - opts.kernel_path or opts.initrd_path): + opts.kernel_path or opts.initrd_path or opts.hvm_boot_order): logger.ToStdout("Please give at least one of the parameters.") return 1 kernel_path = _TransformPath(opts.kernel_path) initrd_path = _TransformPath(opts.initrd_path) + if opts.hvm_boot_order.lower() == 'default': + hvm_boot_order = constants.VALUE_DEFAULT + else: + hvm_boot_order = opts.hvm_boot_order op = opcodes.OpSetInstanceParms(instance_name=args[0], mem=opts.mem, vcpus=opts.vcpus, ip=opts.ip, bridge=opts.bridge, mac=opts.mac, kernel_path=opts.kernel_path, - initrd_path=opts.initrd_path) + initrd_path=opts.initrd_path, + hvm_boot_order=hvm_boot_order) result = SubmitOpCode(op) if result: @@ -771,6 +777,9 @@ add_opts = [ help="Path to the instances' initrd (or 'none', or 'default')", default=None, type="string", metavar="<FILENAME>"), + make_option("--hvm-boot-order", dest="hvm_boot_order", + help="boot device order for HVM (one or more of [acdn])", + default=None, type="string", metavar="<BOOTORDER>"), ] commands = { @@ -878,6 +887,10 @@ commands = { help="Path to the instances' initrd (or 'none', or" " 'default')", default=None, type="string", metavar="<FILENAME>"), + make_option("--hvm-boot-order", dest="hvm_boot_order", + help="boot device order for HVM" + "(either one or more of [acdn] or 'default')", + default=None, type="string", metavar="<BOOTORDER>"), ], "<instance>", "Alters the parameters of an instance"), 'shutdown': (ShutdownInstance, ARGS_ANY, diff --git a/tools/burnin b/tools/burnin index 4ded7492a2e7adf53bcd705dc8190f7b152f9fd9..2b5203c2caf4aa37f3601d9d5f1a814ae25c0050 100755 --- a/tools/burnin +++ b/tools/burnin @@ -203,7 +203,8 @@ class Burner(object): wait_for_sync=True, mac="auto", kernel_path=None, - initrd_path=None) + initrd_path=None, + hvm_boot_order=None) Log("- Add instance %s on node %s" % (instance, pnode)) self.ExecOp(op) self.to_rem.append(instance)