Merge "libvirt: allow querying devices from the persistent domain"
This commit is contained in:
commit
f0cfa3ca6d
@ -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 = """
|
||||
<domain type="kvm">
|
||||
<devices>
|
||||
<disk type="file">
|
||||
<source file="disk1_file"/>
|
||||
<target dev="vda" bus="virtio"/>
|
||||
<serial>0e38683e-f0af-418f-a3f1-6b67ea0f919d</serial>
|
||||
</disk>
|
||||
<disk type="block">
|
||||
<source dev="/path/to/dev/1"/>
|
||||
<target dev="vdb" bus="virtio" serial="1234"/>
|
||||
</disk>
|
||||
</devices>
|
||||
</domain>
|
||||
"""
|
||||
|
||||
diska_xml = """<disk type="file" device="disk">
|
||||
<source file="disk1_file"/>
|
||||
<target bus="virtio" dev="vda"/>
|
||||
<serial>0e38683e-f0af-418f-a3f1-6b67ea0f919d</serial>
|
||||
</disk>"""
|
||||
|
||||
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)
|
||||
|
@ -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 = """<domain>
|
||||
<devices>
|
||||
<interface type="bridge">
|
||||
<mac address="fa:16:3e:f9:af:ae"/>
|
||||
<model type="virtio"/>
|
||||
<driver name="qemu"/>
|
||||
<source bridge="qbr84008d03-11"/>
|
||||
<target dev="tap84008d03-11"/>
|
||||
</interface>
|
||||
</devices>
|
||||
</domain>"""
|
||||
cfg = vconfig.LibvirtConfigGuestInterface()
|
||||
cfg.parse_str("""
|
||||
<interface type="bridge">
|
||||
<mac address="fa:16:3e:f9:af:ae"/>
|
||||
<model type="virtio"/>
|
||||
<driver name="qemu"/>
|
||||
<source bridge="qbr84008d03-11"/>
|
||||
<target dev="tap84008d03-11"/>
|
||||
</interface>""")
|
||||
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 = """<domain>
|
||||
|
@ -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 []
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user