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 []