diff --git a/nova/tests/unit/virt/libvirt/test_config.py b/nova/tests/unit/virt/libvirt/test_config.py
index 6228e6e7d91e..2a79b50e0bb9 100644
--- a/nova/tests/unit/virt/libvirt/test_config.py
+++ b/nova/tests/unit/virt/libvirt/test_config.py
@@ -2863,9 +2863,10 @@ class LibvirtConfigGuestTest(LibvirtConfigBaseTest):
obj.os_mach_type = "pc-q35-5.1"
obj.os_loader = '/tmp/OVMF_CODE.secboot.fd'
obj.os_loader_type = 'pflash'
- obj.os_nvram = '/foo/bar/instance-00000012_VARS.fd'
+ obj.os_loader_readonly = True
obj.os_loader_secure = True
obj.os_loader_stateless = True
+ obj.os_nvram = '/foo/bar/instance-00000012_VARS.fd'
xml = obj.to_xml()
self.assertxmlequal(
@@ -2878,7 +2879,7 @@ class LibvirtConfigGuestTest(LibvirtConfigBaseTest):
hvm
/tmp/OVMF_CODE.secboot.fd
- /foo/bar/instance-00000012_VARS.fd
+ /foo/bar/instance-00000012_VARS.fd
""", # noqa: E501
xml,
@@ -3135,6 +3136,11 @@ class LibvirtConfigGuestTest(LibvirtConfigBaseTest):
self.assertEqual('/tmp/vmlinuz', obj.os_kernel)
self.assertEqual('/usr/lib/xen/boot/hvmloader', obj.os_loader)
self.assertIsNone(obj.os_loader_type)
+ self.assertIsNone(obj.os_loader_readonly)
+ self.assertIsNone(obj.os_loader_secure)
+ self.assertIsNone(obj.os_loader_stateless)
+ self.assertIsNone(obj.os_nvram)
+ self.assertIsNone(obj.os_nvram_template)
self.assertEqual('/tmp/ramdisk', obj.os_initrd)
self.assertEqual('console=xvc0', obj.os_cmdline)
self.assertEqual('root=xvda', obj.os_root)
@@ -3149,9 +3155,11 @@ class LibvirtConfigGuestTest(LibvirtConfigBaseTest):
hvm
/tmp/OVMF_CODE.fd
+ /var/lib/libvirt/qemu/nvram/instance.fd
- """
+ """ # noqa: E501
+
obj = config.LibvirtConfigGuest()
obj.parse_str(xmldoc)
@@ -3161,6 +3169,76 @@ class LibvirtConfigGuestTest(LibvirtConfigBaseTest):
self.assertIsNone(obj.os_kernel)
self.assertEqual('/tmp/OVMF_CODE.fd', obj.os_loader)
self.assertEqual('pflash', obj.os_loader_type)
+ self.assertTrue(obj.os_loader_readonly)
+ self.assertIsNone(obj.os_loader_secure)
+ self.assertIsNone(obj.os_loader_stateless)
+ self.assertEqual('/var/lib/libvirt/qemu/nvram/instance.fd',
+ obj.os_nvram)
+ self.assertEqual('/tmp/OVMF_VARS.fd', obj.os_nvram_template)
+ self.assertIsNone(obj.os_initrd)
+ self.assertIsNone(obj.os_cmdline)
+ self.assertIsNone(obj.os_root)
+ self.assertIsNone(obj.os_init_path)
+ self.assertEqual([], obj.os_boot_dev)
+ self.assertFalse(obj.os_bootmenu)
+ self.assertIsNone(obj.os_smbios)
+
+ xmldoc = """
+
+
+ hvm
+ /tmp/OVMF_CODE.secboot.fd
+ /var/lib/libvirt/qemu/nvram/instance.fd
+
+
+ """ # noqa: E501
+
+ obj = config.LibvirtConfigGuest()
+ obj.parse_str(xmldoc)
+
+ self.assertIsNone(obj.virt_type)
+ self.assertEqual('hvm', obj.os_type)
+ self.assertIsNone(obj.os_mach_type)
+ self.assertIsNone(obj.os_kernel)
+ self.assertEqual('/tmp/OVMF_CODE.secboot.fd', obj.os_loader)
+ self.assertEqual('pflash', obj.os_loader_type)
+ self.assertTrue(obj.os_loader_readonly)
+ self.assertTrue(obj.os_loader_secure)
+ self.assertIsNone(obj.os_loader_stateless)
+ self.assertEqual('/var/lib/libvirt/qemu/nvram/instance.fd',
+ obj.os_nvram)
+ self.assertEqual('/tmp/OVMF_VARS.secboot.fd', obj.os_nvram_template)
+ self.assertIsNone(obj.os_initrd)
+ self.assertIsNone(obj.os_cmdline)
+ self.assertIsNone(obj.os_root)
+ self.assertIsNone(obj.os_init_path)
+ self.assertEqual([], obj.os_boot_dev)
+ self.assertFalse(obj.os_bootmenu)
+ self.assertIsNone(obj.os_smbios)
+
+ xmldoc = """
+
+
+ hvm
+ /tmp/OVMF_CODE.fd
+
+
+ """ # noqa: E501
+
+ obj = config.LibvirtConfigGuest()
+ obj.parse_str(xmldoc)
+
+ self.assertIsNone(obj.virt_type)
+ self.assertEqual('hvm', obj.os_type)
+ self.assertIsNone(obj.os_mach_type)
+ self.assertIsNone(obj.os_kernel)
+ self.assertEqual('/tmp/OVMF_CODE.fd', obj.os_loader)
+ self.assertEqual('pflash', obj.os_loader_type)
+ self.assertTrue(obj.os_loader_readonly)
+ self.assertIsNone(obj.os_loader_secure)
+ self.assertTrue(obj.os_loader_stateless)
+ self.assertIsNone(obj.os_nvram)
+ self.assertIsNone(obj.os_nvram_template)
self.assertIsNone(obj.os_initrd)
self.assertIsNone(obj.os_cmdline)
self.assertIsNone(obj.os_root)
diff --git a/nova/virt/libvirt/config.py b/nova/virt/libvirt/config.py
index 32d947806142..91f70931be95 100644
--- a/nova/virt/libvirt/config.py
+++ b/nova/virt/libvirt/config.py
@@ -3131,6 +3131,7 @@ class LibvirtConfigGuest(LibvirtConfigObject):
self.os_loader = None
self.os_firmware = None
self.os_loader_type = None
+ self.os_loader_readonly = None
self.os_loader_secure = None
self.os_loader_stateless = None
self.os_nvram = None
@@ -3206,13 +3207,16 @@ class LibvirtConfigGuest(LibvirtConfigObject):
if (
self.os_loader is not None or
self.os_loader_type is not None or
+ self.os_loader_readonly is not None or
self.os_loader_secure is not None or
self.os_loader_stateless is not None
):
loader = self._text_node("loader", self.os_loader)
if self.os_loader_type is not None:
loader.set("type", self.os_loader_type)
- loader.set("readonly", "yes")
+ if self.os_loader_readonly is not None:
+ loader.set(
+ "readonly", self.get_yes_no_str(self.os_loader_readonly))
if self.os_loader_secure is not None:
loader.set(
"secure", self.get_yes_no_str(self.os_loader_secure))
@@ -3352,8 +3356,16 @@ class LibvirtConfigGuest(LibvirtConfigObject):
self.os_kernel = c.text
elif c.tag == 'loader':
self.os_loader = c.text
- if c.get('type') == 'pflash':
- self.os_loader_type = 'pflash'
+ self.os_loader_type = c.get('type')
+ if c.get('readonly'):
+ self.os_loader_readonly = (c.get('readonly') == 'yes')
+ if c.get('secure'):
+ self.os_loader_secure = (c.get('secure') == 'yes')
+ if c.get('stateless'):
+ self.os_loader_stateless = (c.get('stateless') == 'yes')
+ elif c.tag == 'nvram':
+ self.os_nvram = c.text
+ self.os_nvram_template = c.get('template')
elif c.tag == 'initrd':
self.os_initrd = c.text
elif c.tag == 'cmdline':
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index c56f1467bd95..14a388c23017 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -7208,6 +7208,7 @@ class LibvirtDriver(driver.ComputeDriver):
guest.os_loader = loader
guest.os_loader_type = 'pflash'
+ guest.os_loader_readonly = True
if hw_firmware_stateless:
guest.os_loader_stateless = True
else: