Fix LibvirtGenericVIFDriver.get_config() for quota

When Nova is used with Neutron and Open vSwitch, network quotas on the
bandwidth are ignored by libvirt: the "<bandwidth>" tag is not generated in
libvirt.xml of the virtual machine. This change fixes this issue but also for
the network types: "bridge", "network" and "direct".

Commands to create the flavor with download limited to 1 MB/sec and create a
virtual machine with this flavor:
---
nova flavor-create --ephemeral=1 victor_test_vif 50 256 1 1
nova flavor-key victor_test_vif set quota:vif_inbound_average=1000
nova boot --flavor=victor_test_vif --image=cirros-0.3.1-x86_64-uec victor_test
---

Commands to upload a file to this virtual machine with SCP to check that the
bandwidth is limited to 1 MB/sec (replace 10.0.0.3 with the IP of the virtual
machine):
---
ip netns
sudo ip netns exec qrouter-128db593-a0db-40c3-84c7-e6383d40c75f bash

dd if=/dev/urandom of=random10MB bs=1024 count=10240
scp random10M cirros@10.0.3:
---

Change-Id: I0f0111fc79fe90900e38df022034b208f1129088
Closes-Bug: #1254664
This commit is contained in:
Victor Stinner 2013-11-22 17:47:05 +01:00
parent 4a944ab86e
commit 497bdfec93
2 changed files with 75 additions and 13 deletions

View File

@ -186,18 +186,25 @@ class LibvirtVifTestCase(test.TestCase):
type=network_model.VIF_TYPE_MIDONET,
devname='tap-xxx-yyy-zzz')
vif_iovisor = network_model.VIF(id='vif-xxx-yyy-zzz',
address='ca:fe:de:ad:be:ef',
network=network_bridge,
type=network_model.VIF_TYPE_IOVISOR,
devname='tap-xxx-yyy-zzz',
ovs_interfaceid=None)
instance = {
'name': 'instance-name',
'uuid': 'instance-uuid'
}
bandwidth = {
'quota:vif_inbound_peak': '102400',
'quota:vif_outbound_peak': '102400',
'quota:vif_inbound_average': '102400',
'quota:vif_outbound_average': '102400',
'quota:vif_inbound_burst': '102400',
'quota:vif_inbound_burst': '102400'
'quota:vif_inbound_peak': '200',
'quota:vif_outbound_peak': '20',
'quota:vif_inbound_average': '100',
'quota:vif_outbound_average': '10',
'quota:vif_inbound_burst': '300',
'quota:vif_outbound_burst': '30'
}
def setUp(self):
@ -360,20 +367,65 @@ class LibvirtVifTestCase(test.TestCase):
self.vif_bridge,
image_meta)
def test_model_qemu(self):
def _test_model_qemu(self, *vif_objs, **kw):
libvirt_version = kw.get('libvirt_version')
self.flags(use_virtio_for_bridges=True,
virt_type='qemu',
group='libvirt')
d = vif.LibvirtGenericVIFDriver(self._get_conn())
xml = self._get_instance_xml(d, self.vif_bridge)
for vif_obj in vif_objs:
d = vif.LibvirtGenericVIFDriver(self._get_conn())
if libvirt_version is not None:
d.libvirt_version = libvirt_version
doc = etree.fromstring(xml)
xml = self._get_instance_xml(d, vif_obj)
ret = doc.findall('./devices/interface/bandwidth')
self.assertEqual(len(ret), 1)
doc = etree.fromstring(xml)
self._assertModel(xml, "virtio", "qemu")
bandwidth = doc.find('./devices/interface/bandwidth')
self.assertNotEqual(bandwidth, None)
inbound = bandwidth.find('inbound')
self.assertEqual(inbound.get("average"),
self.bandwidth['quota:vif_inbound_average'])
self.assertEqual(inbound.get("peak"),
self.bandwidth['quota:vif_inbound_peak'])
self.assertEqual(inbound.get("burst"),
self.bandwidth['quota:vif_inbound_burst'])
outbound = bandwidth.find('outbound')
self.assertEqual(outbound.get("average"),
self.bandwidth['quota:vif_outbound_average'])
self.assertEqual(outbound.get("peak"),
self.bandwidth['quota:vif_outbound_peak'])
self.assertEqual(outbound.get("burst"),
self.bandwidth['quota:vif_outbound_burst'])
self._assertModel(xml, "virtio", "qemu")
def test_model_qemu_no_firewall(self):
self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver")
self._test_model_qemu(
self.vif_bridge,
self.vif_8021qbh,
self.vif_8021qbg,
self.vif_iovisor,
self.vif_mlnx,
)
self._test_model_qemu(self.vif_ovs,
libvirt_version=vif.LIBVIRT_OVS_VPORT_VERSION)
def test_model_qemu_iptables(self):
self.flags(firewall_driver="nova.virt.firewall.IptablesFirewallDriver")
self._test_model_qemu(
self.vif_bridge,
self.vif_ovs,
self.vif_ivs,
self.vif_8021qbh,
self.vif_8021qbg,
self.vif_iovisor,
self.vif_mlnx,
)
def test_model_xen(self):
self.flags(use_virtio_for_bridges=True,

View File

@ -203,6 +203,8 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
self.get_ovs_interfaceid(vif),
self.get_vif_devname(vif))
designer.set_vif_bandwidth_config(conf, inst_type)
return conf
def get_config_ovs_hybrid(self, instance, vif, image_meta,
@ -272,6 +274,8 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
params['typeidversion'],
params['instanceid'])
designer.set_vif_bandwidth_config(conf, inst_type)
return conf
def get_config_802qbh(self, instance, vif, image_meta,
@ -285,6 +289,8 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
conf, vif['network'].get_meta('interface'),
params['profileid'])
designer.set_vif_bandwidth_config(conf, inst_type)
return conf
def get_config_iovisor(self, instance, vif, image_meta,
@ -296,6 +302,8 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
dev = self.get_vif_devname(vif)
designer.set_vif_host_backend_ethernet_config(conf, dev)
designer.set_vif_bandwidth_config(conf, inst_type)
return conf
def get_config_midonet(self, instance, vif, image_meta,
@ -318,6 +326,8 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
devname = self.get_vif_devname_with_prefix(vif, DEV_PREFIX_ETH)
designer.set_vif_host_backend_direct_config(conf, devname)
designer.set_vif_bandwidth_config(conf, inst_type)
return conf
def get_config(self, instance, vif, image_meta, inst_type):