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.
|
# The libvirt URI to use. This option enables libvirt driver.
|
||||||
SUSHY_EMULATOR_LIBVIRT_URI = u'qemu:///system'
|
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
|
# The map of firmware loaders dependant on the boot mode and
|
||||||
# system architecture
|
# system architecture
|
||||||
SUSHY_EMULATOR_BOOT_LOADER_MAP = {
|
SUSHY_EMULATOR_BOOT_LOADER_MAP = {
|
||||||
|
@ -155,6 +155,8 @@ class LibvirtDriver(AbstractSystemsDriver):
|
|||||||
'SUSHY_EMULATOR_BOOT_LOADER_MAP', cls.BOOT_LOADER_MAP)
|
'SUSHY_EMULATOR_BOOT_LOADER_MAP', cls.BOOT_LOADER_MAP)
|
||||||
cls.KNOWN_BOOT_LOADERS = set(y for x in cls.BOOT_LOADER_MAP.values()
|
cls.KNOWN_BOOT_LOADERS = set(y for x in cls.BOOT_LOADER_MAP.values()
|
||||||
for y in x.values())
|
for y in x.values())
|
||||||
|
cls.SUSHY_EMULATOR_IGNORE_BOOT_DEVICE = \
|
||||||
|
cls._config.get('SUSHY_EMULATOR_IGNORE_BOOT_DEVICE', False)
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
@memoize.memoize()
|
@memoize.memoize()
|
||||||
@ -282,6 +284,11 @@ class LibvirtDriver(AbstractSystemsDriver):
|
|||||||
:returns: boot device name as `str` or `None` if device name
|
:returns: boot device name as `str` or `None` if device name
|
||||||
can't be determined
|
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)
|
domain = self._get_domain(identity, readonly=True)
|
||||||
|
|
||||||
tree = ET.fromstring(domain.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE))
|
tree = ET.fromstring(domain.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE))
|
||||||
@ -347,6 +354,15 @@ class LibvirtDriver(AbstractSystemsDriver):
|
|||||||
|
|
||||||
return boot_source_target
|
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):
|
def set_boot_device(self, identity, boot_source):
|
||||||
"""Get/Set computer system boot device name
|
"""Get/Set computer system boot device name
|
||||||
|
|
||||||
@ -372,6 +388,13 @@ class LibvirtDriver(AbstractSystemsDriver):
|
|||||||
for boot_element in os_element.findall('boot'):
|
for boot_element in os_element.findall('boot'):
|
||||||
os_element.remove(boot_element)
|
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)
|
target = self.DISK_DEVICE_MAP.get(boot_source)
|
||||||
|
|
||||||
# Process per-device boot configuration
|
# Process per-device boot configuration
|
||||||
@ -426,15 +449,7 @@ class LibvirtDriver(AbstractSystemsDriver):
|
|||||||
boot_element = ET.SubElement(target_device_element, 'boot')
|
boot_element = ET.SubElement(target_device_element, 'boot')
|
||||||
boot_element.set('order', str(order + 1))
|
boot_element.set('order', str(order + 1))
|
||||||
|
|
||||||
try:
|
self._defineDomain(tree)
|
||||||
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 get_boot_mode(self, identity):
|
def get_boot_mode(self, identity):
|
||||||
"""Get computer system boot mode.
|
"""Get computer system boot mode.
|
||||||
|
@ -214,6 +214,27 @@ class LibvirtDriverTestCase(base.BaseTestCase):
|
|||||||
|
|
||||||
conn_mock.defineXML.assert_called_once_with(mock.ANY)
|
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)
|
@mock.patch('libvirt.openReadOnly', autospec=True)
|
||||||
def test_get_boot_device_disk(self, libvirt_mock):
|
def test_get_boot_device_disk(self, libvirt_mock):
|
||||||
with open('sushy_tools/tests/unit/emulator/'
|
with open('sushy_tools/tests/unit/emulator/'
|
||||||
|
Loading…
Reference in New Issue
Block a user