Commit 25c5878d authored by Alexander Schreiber's avatar Alexander Schreiber
Browse files

Support selecting the boot device order for HVM.

This patch adds support for specifying and changing the boot device order for
HVM instances. The boot device order specification is ignored for non HVM
instances.

Reviewed-by: iustinp
parent c234fe4c
......@@ -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)
......
......@@ -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"
......@@ -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")
......
......@@ -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",
]
......
......@@ -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.
......
......@@ -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,
......
......@@ -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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment