installer: Order install CDROM before any manual CDROMs

This is important for the virtio-win case: --cdrom media should
always be ordered first, so it's the boot preference.

https://www.redhat.com/archives/virt-tools-list/2018-September/msg00048.html
This commit is contained in:
Cole Robinson 2018-10-13 10:23:00 -04:00
parent 2e6093d6b6
commit 41d0f8fdf1
4 changed files with 119 additions and 3 deletions

View File

@ -0,0 +1,103 @@
<domain type="test">
<name>foobar</name>
<uuid>00000000-1111-2222-3333-444444444444</uuid>
<memory>65536</memory>
<currentMemory>65536</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch="i686">hvm</type>
<boot dev="cdrom"/>
<boot dev="hd"/>
</os>
<features>
<pae/>
</features>
<clock offset="utc"/>
<on_reboot>destroy</on_reboot>
<pm>
<suspend-to-mem enabled="no"/>
<suspend-to-disk enabled="no"/>
</pm>
<devices>
<emulator>/usr/bin/test-hv</emulator>
<disk type="file" device="disk">
<source file="/var/lib/libvirt/images/foobar.qcow2"/>
<target dev="hda" bus="ide"/>
</disk>
<disk type="file" device="cdrom">
<source file="/dev/default-pool/testvol1.img"/>
<target dev="hdb" bus="ide"/>
<readonly/>
</disk>
<disk type="file" device="cdrom">
<source file="/dev/default-pool/testvol2.img"/>
<target dev="hdc" bus="ide"/>
<readonly/>
</disk>
<controller type="usb" index="0" model="ich9-ehci1"/>
<controller type="usb" index="0" model="ich9-uhci1">
<master startport="0"/>
</controller>
<controller type="usb" index="0" model="ich9-uhci2">
<master startport="2"/>
</controller>
<controller type="usb" index="0" model="ich9-uhci3">
<master startport="4"/>
</controller>
<interface type="user">
<mac address="00:11:22:33:44:55"/>
<model type="e1000"/>
</interface>
<console type="pty"/>
</devices>
</domain>
<domain type="test">
<name>foobar</name>
<uuid>00000000-1111-2222-3333-444444444444</uuid>
<memory>65536</memory>
<currentMemory>65536</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch="i686">hvm</type>
<boot dev="hd"/>
</os>
<features>
<pae/>
</features>
<clock offset="utc"/>
<pm>
<suspend-to-mem enabled="no"/>
<suspend-to-disk enabled="no"/>
</pm>
<devices>
<emulator>/usr/bin/test-hv</emulator>
<disk type="file" device="disk">
<source file="/var/lib/libvirt/images/foobar.qcow2"/>
<target dev="hda" bus="ide"/>
</disk>
<disk type="file" device="cdrom">
<target dev="hdb" bus="ide"/>
<readonly/>
</disk>
<disk type="file" device="cdrom">
<source file="/dev/default-pool/testvol2.img"/>
<target dev="hdc" bus="ide"/>
<readonly/>
</disk>
<controller type="usb" index="0" model="ich9-ehci1"/>
<controller type="usb" index="0" model="ich9-uhci1">
<master startport="0"/>
</controller>
<controller type="usb" index="0" model="ich9-uhci2">
<master startport="2"/>
</controller>
<controller type="usb" index="0" model="ich9-uhci3">
<master startport="4"/>
</controller>
<interface type="user">
<mac address="00:11:22:33:44:55"/>
<model type="e1000"/>
</interface>
<console type="pty"/>
</devices>
</domain>

View File

@ -682,6 +682,7 @@ c.add_valid("--panic help --disk=?") # Make sure introspection doesn't blow up
c.add_valid("--test-stub-command") # --test-stub-command
c.add_invalid("--hvm --nodisks --pxe foobar") # Positional arguments error
c.add_invalid("--nodisks --pxe --name test") # Colliding name
c.add_compare("--cdrom %(EXISTIMG1)s --disk size=1 --disk %(EXISTIMG2)s,device=cdrom", "cdrom-double") # ensure --disk device=cdrom is ordered after --cdrom, this is important for virtio-win installs with a driver ISO

View File

@ -89,7 +89,14 @@ class Installer(object):
dev.sync_path_props()
dev.validate()
self._install_cdrom_device = dev
guest.add_device(dev)
# Insert the CDROM before any other CDROM, so boot=cdrom picks
# it as the priority
for idx, disk in enumerate(guest.devices.disk):
if disk.is_cdrom():
guest.devices.add_child(self._install_cdrom_device, idx=idx)
return
guest.add_device(self._install_cdrom_device)
def _remove_install_cdrom_media(self, guest):
if not self._install_cdrom_device:

View File

@ -152,6 +152,8 @@ class XMLChildProperty(_XMLPropertyBase):
for obj in self._get(xmlbuilder)[:]:
xmlbuilder.remove_child(obj)
def insert(self, xmlbuilder, newobj, idx):
self._get(xmlbuilder).insert(idx, newobj)
def append(self, xmlbuilder, newobj):
self._get(xmlbuilder).append(newobj)
def remove(self, xmlbuilder, obj):
@ -646,14 +648,17 @@ class XMLBuilder(object):
for p in util.listify(getattr(self, propname, [])):
p._parse_with_children(None, self._xmlstate)
def add_child(self, obj):
def add_child(self, obj, idx=None):
"""
Insert the passed XMLBuilder object into our XML document. The
object needs to have an associated mapping via XMLChildProperty
"""
xmlprop = self._find_child_prop(obj.__class__)
xml = obj.get_xml()
xmlprop.append(self, obj)
if idx is None:
xmlprop.append(self, obj)
else:
xmlprop.insert(self, obj, idx)
self._set_child_xpaths()
# Only insert the XML directly into the parent XML for !is_build