Merge "Save previous hd boot device when setting Pxe"
This commit is contained in:
commit
7115db2f3a
|
@ -412,9 +412,11 @@ class LibvirtDriver(AbstractSystemsDriver):
|
|||
tree = ET.fromstring(self.get_xml_desc(domain))
|
||||
|
||||
# Remove bootloader configuration
|
||||
os_element_order = []
|
||||
|
||||
for os_element in tree.findall('os'):
|
||||
for boot_element in os_element.findall('boot'):
|
||||
os_element_order.append(boot_element.get('dev'))
|
||||
os_element.remove(boot_element)
|
||||
|
||||
if self.SUSHY_EMULATOR_IGNORE_BOOT_DEVICE:
|
||||
|
@ -437,20 +439,31 @@ class LibvirtDriver(AbstractSystemsDriver):
|
|||
raise error.FishyError(msg)
|
||||
|
||||
target_device_elements = []
|
||||
cur_hd_osboot_elements = []
|
||||
cur_hd_order_elements = []
|
||||
|
||||
# Remove per-disk boot configuration
|
||||
# We should save at least hdd boot entries instead of just removing
|
||||
# everything. In some scenarious PXE after provisioning stops replying
|
||||
# and if there is no other boot device, then vm will fail to boot
|
||||
# cdrom and floppy are ignored.
|
||||
|
||||
for disk_element in devices_element.findall('disk'):
|
||||
|
||||
device_attr = disk_element.get('device')
|
||||
if device_attr is None:
|
||||
continue
|
||||
boot_elements = disk_element.findall('boot')
|
||||
|
||||
# NOTE(etingof): multiple devices of the same type not supported
|
||||
if device_attr == target:
|
||||
target_device_elements.append(disk_element)
|
||||
elif 'hd' in os_element_order:
|
||||
cur_hd_osboot_elements.append(disk_element)
|
||||
elif boot_elements:
|
||||
cur_hd_order_elements.append(disk_element)
|
||||
|
||||
for boot_element in disk_element.findall('boot'):
|
||||
for boot_element in boot_elements:
|
||||
disk_element.remove(boot_element)
|
||||
|
||||
target = self.INTERFACE_MAP.get(boot_source)
|
||||
|
@ -472,6 +485,15 @@ class LibvirtDriver(AbstractSystemsDriver):
|
|||
|
||||
raise error.FishyError(msg)
|
||||
|
||||
# OS boot and per device boot order are mutually exclusive
|
||||
if cur_hd_osboot_elements:
|
||||
sorted_hd_elements = sorted(
|
||||
cur_hd_osboot_elements,
|
||||
key=lambda child: child.find('target').get('dev'))
|
||||
target_device_elements.extend(sorted_hd_elements)
|
||||
else:
|
||||
target_device_elements.extend(cur_hd_order_elements)
|
||||
|
||||
# NOTE(etingof): Make all chosen devices bootable (important for NICs)
|
||||
|
||||
for order, target_device_element in enumerate(target_device_elements):
|
||||
|
@ -774,7 +796,10 @@ class LibvirtDriver(AbstractSystemsDriver):
|
|||
def _process_bios(self, identity,
|
||||
bios_attributes=DEFAULT_BIOS_ATTRIBUTES,
|
||||
update_existing_attributes=False):
|
||||
"""Process Libvirt domain XML for BIOS attributes and update it if necessary
|
||||
"""Process Libvirt domain XML for BIOS attributes
|
||||
|
||||
Process Libvirt domain XML for BIOS attributes and update it if
|
||||
necessary
|
||||
|
||||
:param identity: libvirt domain name or ID
|
||||
:param bios_attributes: Full list of BIOS attributes to use if
|
||||
|
@ -785,6 +810,7 @@ class LibvirtDriver(AbstractSystemsDriver):
|
|||
|
||||
:raises: `error.FishyError` if BIOS attributes cannot be saved
|
||||
"""
|
||||
|
||||
domain = self._get_domain(identity)
|
||||
|
||||
result = self._process_bios_attributes(
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<domain type='qemu'>
|
||||
<name>QEmu-fedora-i686</name>
|
||||
<uuid>c7a5fdbd-cdaf-9455-926a-d65c16db1809</uuid>
|
||||
<memory>219200</memory>
|
||||
<currentMemory>219200</currentMemory>
|
||||
<vcpu>2</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64' machine='pc'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
<loader type='rom'/>
|
||||
</os>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||
<disk type='file' device='cdrom'>
|
||||
<source file='/home/user/boot.iso'/>
|
||||
<target dev='hdc'/>
|
||||
<readonly/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='/home/user/fedora.img'/>
|
||||
<target dev='hda'/>
|
||||
</disk>
|
||||
<interface type='network'>
|
||||
<source network='default'/>
|
||||
<mac address='52:54:00:da:ac:54'/>
|
||||
<model type='virtio'/>
|
||||
<address type='pci' domain='0x0000' bus='0x01' slot='0x01' function='0x0'/>
|
||||
</interface>
|
||||
<graphics type='vnc' port='-1'/>
|
||||
</devices>
|
||||
</domain>
|
|
@ -327,6 +327,66 @@ class LibvirtDriverTestCase(base.BaseTestCase):
|
|||
|
||||
self.assertIn(expected, conn_mock.defineXML.call_args[0][0])
|
||||
|
||||
@mock.patch('libvirt.open', autospec=True)
|
||||
def test_set_boot_device_network_from_hd(self, libvirt_mock):
|
||||
with open('sushy_tools/tests/unit/emulator/'
|
||||
'domain_to_boot_pxe.xml', 'r') as f:
|
||||
data = f.read()
|
||||
|
||||
conn_mock = libvirt_mock.return_value
|
||||
domain_mock = conn_mock.lookupByUUID.return_value
|
||||
domain_mock.XMLDesc.return_value = data
|
||||
|
||||
with mock.patch.object(
|
||||
self.test_driver, 'get_power_state', return_value='Off'):
|
||||
self.test_driver.set_boot_device(self.uuid, 'Pxe')
|
||||
|
||||
conn_mock.defineXML.assert_called_once_with(mock.ANY)
|
||||
|
||||
newtree = ET.fromstring(conn_mock.defineXML.call_args[0][0])
|
||||
# check that os section does not have boot defined.
|
||||
# We find all os sections if any. Then count about of boot sections.
|
||||
# And the final summ should be 0
|
||||
os_boot_amount = sum(
|
||||
[len(ossec.findall('boot')) for ossec in newtree.findall('os')])
|
||||
self.assertEqual(0, os_boot_amount)
|
||||
|
||||
# check that Network device has order=1
|
||||
interface_orders = [
|
||||
theint.find('boot').get('order')
|
||||
for theint in newtree.find('devices').findall('interface')]
|
||||
self.assertIn('1', interface_orders)
|
||||
|
||||
# Check that we have at least one hd device set after a network device
|
||||
diskdrives_order_sum = len([
|
||||
thedrive.find('boot').get('order')
|
||||
for thedrive in newtree.find('devices').findall('disk')])
|
||||
self.assertEqual(2, diskdrives_order_sum)
|
||||
|
||||
# Check overal config to match expected fixture
|
||||
expected = '<domain type="qemu">\n <name>QEmu-fedora-i686</name>\n '\
|
||||
' <uuid>c7a5fdbd-cdaf-9455-926a-d65c16db1809</uuid>\n '\
|
||||
'<memory>219200</memory>\n '\
|
||||
'<currentMemory>219200</currentMemory>\n <vcpu>2</vcpu>\n '\
|
||||
'<os>\n <type arch="x86_64" machine="pc">hvm</type>\n '\
|
||||
'<loader type="rom" />\n </os>\n <devices>\n '\
|
||||
'<emulator>/usr/bin/qemu-system-x86_64</emulator>\n '\
|
||||
'<disk type="file" device="cdrom">\n '\
|
||||
'<source file="/home/user/boot.iso" />\n '\
|
||||
'<target dev="hdc" />\n <readonly />\n '\
|
||||
'<boot order="3" /></disk>\n '\
|
||||
'<disk type="file" device="disk">\n '\
|
||||
'<source file="/home/user/fedora.img" />\n '\
|
||||
'<target dev="hda" />\n <boot order="2" /></disk>\n '\
|
||||
'<interface type="network">\n '\
|
||||
'<source network="default" />\n '\
|
||||
'<mac address="52:54:00:da:ac:54" />\n '\
|
||||
'<model type="virtio" />\n <address type="pci" '\
|
||||
'domain="0x0000" bus="0x01" slot="0x01" function="0x0" />\n '\
|
||||
'<boot order="1" /></interface>\n '\
|
||||
'<graphics type="vnc" port="-1" />\n </devices>\n</domain>'
|
||||
self.assertIn(expected, conn_mock.defineXML.call_args[0][0])
|
||||
|
||||
@mock.patch('libvirt.openReadOnly', autospec=True)
|
||||
def test_get_boot_mode_legacy(self, libvirt_mock):
|
||||
with open('sushy_tools/tests/unit/emulator/domain.xml', 'r') as f:
|
||||
|
|
Loading…
Reference in New Issue