New option to prevent libvirt defining boot order
Add a new config option "SUSHY_EMULATOR_IGNORE_BOOT_DEVICE". Instructs the libvirt driver to ignore any instructions to set the boot device. Allowing the UEFI firmware to instead rely on the EFI Boot Manager Change-Id: Ica78dab39639d7acb2168866b0035f9c3d865fa1
This commit is contained in:
parent
57d05d944b
commit
02b451b500
@ -19,6 +19,15 @@ SUSHY_EMULATOR_OS_CLOUD = None
|
||||
# The libvirt URI to use. This option enables libvirt driver.
|
||||
SUSHY_EMULATOR_LIBVIRT_URI = u'qemu:///system'
|
||||
|
||||
# Instruct the libvirt driver to ignore any instructions to
|
||||
# set the boot device. Allowing the UEFI firmware to instead
|
||||
# rely on the EFI Boot Manager
|
||||
# Note: This sets the legacy boot element to dev="fd"
|
||||
# and relies on the floppy not existing, it likely wont work
|
||||
# your VM has a floppy drive.
|
||||
SUSHY_EMULATOR_IGNORE_BOOT_DEVICE = False
|
||||
|
||||
|
||||
# The map of firmware loaders dependant on the boot mode and
|
||||
# system architecture
|
||||
SUSHY_EMULATOR_BOOT_LOADER_MAP = {
|
||||
|
@ -155,6 +155,8 @@ class LibvirtDriver(AbstractSystemsDriver):
|
||||
'SUSHY_EMULATOR_BOOT_LOADER_MAP', cls.BOOT_LOADER_MAP)
|
||||
cls.KNOWN_BOOT_LOADERS = set(y for x in cls.BOOT_LOADER_MAP.values()
|
||||
for y in x.values())
|
||||
cls.SUSHY_EMULATOR_IGNORE_BOOT_DEVICE = \
|
||||
cls._config.get('SUSHY_EMULATOR_IGNORE_BOOT_DEVICE', False)
|
||||
return cls
|
||||
|
||||
@memoize.memoize()
|
||||
@ -282,6 +284,11 @@ class LibvirtDriver(AbstractSystemsDriver):
|
||||
:returns: boot device name as `str` or `None` if device name
|
||||
can't be determined
|
||||
"""
|
||||
|
||||
# If not setting Boot devices then just report HDD
|
||||
if self.SUSHY_EMULATOR_IGNORE_BOOT_DEVICE:
|
||||
return constants.DEVICE_TYPE_HDD
|
||||
|
||||
domain = self._get_domain(identity, readonly=True)
|
||||
|
||||
tree = ET.fromstring(domain.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE))
|
||||
@ -347,6 +354,15 @@ class LibvirtDriver(AbstractSystemsDriver):
|
||||
|
||||
return boot_source_target
|
||||
|
||||
def _defineDomain(self, tree):
|
||||
try:
|
||||
with libvirt_open(self._uri) as conn:
|
||||
conn.defineXML(ET.tostring(tree).decode('utf-8'))
|
||||
except libvirt.libvirtError as e:
|
||||
msg = ('Error changing boot device at libvirt URI "%(uri)s": '
|
||||
'%(error)s' % {'uri': self._uri, 'error': e})
|
||||
raise error.FishyError(msg)
|
||||
|
||||
def set_boot_device(self, identity, boot_source):
|
||||
"""Get/Set computer system boot device name
|
||||
|
||||
@ -372,6 +388,13 @@ class LibvirtDriver(AbstractSystemsDriver):
|
||||
for boot_element in os_element.findall('boot'):
|
||||
os_element.remove(boot_element)
|
||||
|
||||
if self.SUSHY_EMULATOR_IGNORE_BOOT_DEVICE:
|
||||
self._logger.warning('Ignoring setting of boot device')
|
||||
boot_element = ET.SubElement(os_element, 'boot')
|
||||
boot_element.set('dev', 'fd')
|
||||
self._defineDomain(tree)
|
||||
return
|
||||
|
||||
target = self.DISK_DEVICE_MAP.get(boot_source)
|
||||
|
||||
# Process per-device boot configuration
|
||||
@ -426,15 +449,7 @@ class LibvirtDriver(AbstractSystemsDriver):
|
||||
boot_element = ET.SubElement(target_device_element, 'boot')
|
||||
boot_element.set('order', str(order + 1))
|
||||
|
||||
try:
|
||||
with libvirt_open(self._uri) as conn:
|
||||
conn.defineXML(ET.tostring(tree).decode('utf-8'))
|
||||
|
||||
except libvirt.libvirtError as e:
|
||||
msg = ('Error changing boot device at libvirt URI "%(uri)s": '
|
||||
'%(error)s' % {'uri': self._uri, 'error': e})
|
||||
|
||||
raise error.FishyError(msg)
|
||||
self._defineDomain(tree)
|
||||
|
||||
def get_boot_mode(self, identity):
|
||||
"""Get computer system boot mode.
|
||||
|
@ -214,6 +214,27 @@ class LibvirtDriverTestCase(base.BaseTestCase):
|
||||
|
||||
conn_mock.defineXML.assert_called_once_with(mock.ANY)
|
||||
|
||||
@mock.patch('libvirt.open', autospec=True)
|
||||
def test_set_boot_device_ignored(self, libvirt_mock):
|
||||
with open('sushy_tools/tests/unit/emulator/'
|
||||
'domain_boot_os.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
|
||||
|
||||
self.test_driver.SUSHY_EMULATOR_IGNORE_BOOT_DEVICE = True
|
||||
|
||||
self.test_driver.set_boot_device(self.uuid, 'Hdd')
|
||||
|
||||
conn_mock.defineXML.assert_called_once_with(mock.ANY)
|
||||
tree = ET.fromstring(conn_mock.defineXML.call_args[0][0])
|
||||
self.assertEqual(1, len(tree.findall('.//boot')))
|
||||
os_element = tree.find('os')
|
||||
boot_element = os_element.find('boot')
|
||||
self.assertEqual('fd', boot_element.get('dev'))
|
||||
|
||||
@mock.patch('libvirt.openReadOnly', autospec=True)
|
||||
def test_get_boot_device_disk(self, libvirt_mock):
|
||||
with open('sushy_tools/tests/unit/emulator/'
|
||||
|
Loading…
Reference in New Issue
Block a user