diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py
index 584c9abe3720..79d2a50371db 100644
--- a/nova/tests/unit/virt/libvirt/test_driver.py
+++ b/nova/tests/unit/virt/libvirt/test_driver.py
@@ -24242,6 +24242,41 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
self.assertIsNone(guest.get_disk('vdc'))
+ dom.XMLDesc.assert_has_calls([mock.call(0)] * 3)
+
+ def test_get_disk_xml_from_persistent_config(self):
+ dom_xml = """
+
+
+
+
+
+ 0e38683e-f0af-418f-a3f1-6b67ea0f919d
+
+
+
+
+
+
+
+ """
+
+ diska_xml = """
+
+
+ 0e38683e-f0af-418f-a3f1-6b67ea0f919d
+"""
+
+ dom = mock.MagicMock()
+ dom.XMLDesc.return_value = dom_xml
+ guest = libvirt_guest.Guest(dom)
+
+ actual_diska_xml = guest.get_disk(
+ 'vda', from_persistent_config=True).to_xml()
+ self.assertXmlEqual(diska_xml, actual_diska_xml)
+ dom.XMLDesc.assert_called_once_with(
+ fakelibvirt.VIR_DOMAIN_XML_INACTIVE)
+
def test_vcpu_model_from_config(self):
drv = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
vcpu_model = drv._cpu_config_to_vcpu_model(None, None)
diff --git a/nova/tests/unit/virt/libvirt/test_guest.py b/nova/tests/unit/virt/libvirt/test_guest.py
index 6ccd81cd09d8..d9674703507e 100644
--- a/nova/tests/unit/virt/libvirt/test_guest.py
+++ b/nova/tests/unit/virt/libvirt/test_guest.py
@@ -540,6 +540,49 @@ class GuestTestCase(test.NoDBTestCase):
self.assertIsNotNone(
self.guest.get_interface_by_cfg(cfg))
self.assertIsNone(self.guest.get_interface_by_cfg(None))
+ self.domain.XMLDesc.assert_has_calls([mock.call(0)] * 6)
+
+ # now check if the persistent config can be queried too
+ self.domain.XMLDesc.reset_mock()
+ devs = self.guest.get_all_devices(
+ devtype=None, from_persistent_config=True)
+ self.domain.XMLDesc.assert_called_once_with(
+ fakelibvirt.VIR_DOMAIN_XML_INACTIVE)
+
+ def test_get_interface_by_cfg_persistent_domain(self):
+ self.domain.XMLDesc.return_value = """
+
+
+
+
+
+
+
+
+
+"""
+ cfg = vconfig.LibvirtConfigGuestInterface()
+ cfg.parse_str("""
+
+
+
+
+
+
+ """)
+ self.assertIsNotNone(
+ self.guest.get_interface_by_cfg(
+ cfg, from_persistent_config=True))
+ self.assertIsNone(
+ self.guest.get_interface_by_cfg(
+ vconfig.LibvirtConfigGuestInterface(),
+ from_persistent_config=True))
+ self.domain.XMLDesc.assert_has_calls(
+ [
+ mock.call(fakelibvirt.VIR_DOMAIN_XML_INACTIVE),
+ mock.call(fakelibvirt.VIR_DOMAIN_XML_INACTIVE),
+ ]
+ )
def test_get_interface_by_cfg_vhostuser(self):
self.domain.XMLDesc.return_value = """
diff --git a/nova/virt/libvirt/guest.py b/nova/virt/libvirt/guest.py
index 5143f142eb73..b738097377b2 100644
--- a/nova/virt/libvirt/guest.py
+++ b/nova/virt/libvirt/guest.py
@@ -227,19 +227,22 @@ class Guest(object):
return interfaces
- def get_interface_by_cfg(self, cfg):
+ def get_interface_by_cfg(self, cfg, from_persistent_config=False):
"""Lookup a full LibvirtConfigGuestDevice with
LibvirtConfigGuesDevice generated
by nova.virt.libvirt.vif.get_config.
:param cfg: config object that represents the guest interface.
:type cfg: a subtype of LibvirtConfigGuestDevice object
+ :param from_persistent_config: query the device from the persistent
+ domain instead of the live domain configuration
:returns: nova.virt.libvirt.config.LibvirtConfigGuestDevice instance
if found, else None
"""
if cfg:
- interfaces = self.get_all_devices(type(cfg))
+ interfaces = self.get_all_devices(
+ type(cfg), from_persistent_config)
for interface in interfaces:
# NOTE(leehom) LibvirtConfigGuest get from domain and
# LibvirtConfigGuest generated by
@@ -334,13 +337,16 @@ class Guest(object):
config.parse_str(self._domain.XMLDesc(0))
return config
- def get_disk(self, device):
+ def get_disk(self, device, from_persistent_config=False):
"""Returns the disk mounted at device
:returns LivirtConfigGuestDisk: mounted at device or None
"""
+ flags = 0
+ if from_persistent_config:
+ flags |= libvirt.VIR_DOMAIN_XML_INACTIVE
try:
- doc = etree.fromstring(self._domain.XMLDesc(0))
+ doc = etree.fromstring(self._domain.XMLDesc(flags))
except Exception:
return None
@@ -365,18 +371,24 @@ class Guest(object):
return self.get_all_devices(vconfig.LibvirtConfigGuestDisk)
- def get_all_devices(self, devtype=None):
+ def get_all_devices(self, devtype=None, from_persistent_config=False):
"""Returns all devices for a guest
:param devtype: a LibvirtConfigGuestDevice subclass class
-
+ :param from_persistent_config: query the device from the persistent
+ domain (i.e. inactive XML configuration that'll be used on next
+ start of the domain) instead of the live domain configuration
:returns: a list of LibvirtConfigGuestDevice instances
"""
+ flags = 0
+ if from_persistent_config:
+ flags |= libvirt.VIR_DOMAIN_XML_INACTIVE
+
try:
config = vconfig.LibvirtConfigGuest()
config.parse_str(
- self._domain.XMLDesc(0))
+ self._domain.XMLDesc(flags))
except Exception:
return []