From 194b23c422b4120db8a9c2e16d2371fc31092a6b Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Tue, 22 Jan 2013 11:32:28 +0000 Subject: Merge LibvirtOpenVswitchDriver class into LibvirtGenericVIFDriver The LibvirtGenericVIFDriver class can use the 'vif_type' mapping field to determine whether an OVS network configuration is required, thus a dedicated driver for OVS is no longer required. The LibvirtOpenVswitchDriver class functionality is merged into LibvirtGenericVIFDriver. For backwards compatibility with the Folsom release, the existing LibvirtOpenVswitchDriver class is made to inherit from LibvirtGenericVIFDriver and directly call the bridge specific setup APIs. This eases migration to the new VIF impl during the Grizzly deployment lifecycle, with an expectation that the LibvirtOpenVswitchDriver stub will be deleted after the Havana release. Blueprint: libvirt-vif-driver Change-Id: Iac79e0880b6fbcca0fd8cc26b59d23e579b947fa Signed-off-by: Daniel P. Berrange --- nova/tests/test_libvirt_vif.py | 28 ++++++++++--- nova/virt/libvirt/vif.py | 91 ++++++++++++++++++++++++++++-------------- 2 files changed, 84 insertions(+), 35 deletions(-) diff --git a/nova/tests/test_libvirt_vif.py b/nova/tests/test_libvirt_vif.py index 58504dcd8..6a3530588 100644 --- a/nova/tests/test_libvirt_vif.py +++ b/nova/tests/test_libvirt_vif.py @@ -98,9 +98,18 @@ class LibvirtVifTestCase(test.TestCase): 'dhcp_server': '191.168.1.1', 'vif_uuid': 'vif-xxx-yyy-zzz', 'vif_devname': 'tap-xxx-yyy-zzz', + 'vif_type': network_model.VIF_TYPE_OVS, 'ovs_interfaceid': 'aaa-bbb-ccc', } + mapping_ovs_legacy = { + 'mac': 'ca:fe:de:ad:be:ef', + 'gateway_v6': net_ovs['gateway_v6'], + 'ips': [{'ip': '101.168.1.9'}], + 'dhcp_server': '191.168.1.1', + 'vif_uuid': 'vif-xxx-yyy-zzz', + } + mapping_none = { 'mac': 'ca:fe:de:ad:be:ef', 'gateway_v6': net_bridge['gateway_v6'], @@ -300,11 +309,8 @@ class LibvirtVifTestCase(test.TestCase): self.mapping_bridge_quantum, br_want) - def test_ovs_ethernet_driver(self): - d = vif.LibvirtOpenVswitchDriver() - xml = self._get_instance_xml(d, - self.net_ovs, - self.mapping_ovs) + def _check_ovs_ethernet_driver(self, d, net, mapping): + xml = self._get_instance_xml(d, net, mapping) doc = etree.fromstring(xml) ret = doc.findall('./devices/interface') @@ -318,6 +324,18 @@ class LibvirtVifTestCase(test.TestCase): script = node.find("script").get("path") self.assertEquals(script, "") + def test_ovs_ethernet_driver(self): + d = vif.LibvirtOpenVswitchDriver() + self._check_ovs_ethernet_driver(d, + self.net_ovs, + self.mapping_ovs_legacy) + + def test_ovs_ethernet_driver(self): + d = vif.LibvirtGenericVIFDriver() + self._check_ovs_ethernet_driver(d, + self.net_ovs, + self.mapping_ovs) + def test_ovs_virtualport_driver(self): d = vif.LibvirtOpenVswitchVirtualPortDriver() xml = self._get_instance_xml(d, diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py index 3ffdfd0ac..131fb10e9 100644 --- a/nova/virt/libvirt/vif.py +++ b/nova/virt/libvirt/vif.py @@ -85,6 +85,9 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): def get_bridge_name(self, network): return network['bridge'] + def get_ovs_interfaceid(self, mapping): + return mapping['ovs_interfaceid'] + def get_config_bridge(self, instance, network, mapping): """Get VIF configurations for bridge type.""" conf = super(LibvirtGenericVIFDriver, @@ -116,6 +119,21 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): return conf + def get_config_ovs_ethernet(self, instance, network, mapping): + conf = super(LibvirtGenericVIFDriver, + self).get_config(instance, + network, + mapping) + + dev = self.get_vif_devname(mapping) + designer.set_vif_host_backend_ethernet_config(conf, dev) + + return conf + + def get_config_ovs(self, instance, network, mapping): + return self.get_config_ovs_ethernet(instance, network, + mapping) + def get_config(self, instance, network, mapping): vif_type = mapping.get('vif_type') @@ -130,6 +148,8 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): if vif_type == network_model.VIF_TYPE_BRIDGE: return self.get_config_bridge(instance, network, mapping) + elif vif_type == network_model.VIF_TYPE_OVS: + return self.get_config_ovs(instance, network, mapping) else: raise exception.NovaException( _("Unexpected vif_type=%s") % vif_type) @@ -160,6 +180,21 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): self.get_bridge_name(network), iface) + def plug_ovs_ethernet(self, instance, vif): + super(LibvirtGenericVIFDriver, + self).plug(instance, vif) + + network, mapping = vif + iface_id = self.get_ovs_interfaceid(mapping) + dev = self.get_vif_devname(mapping) + linux_net.create_tap_dev(dev) + linux_net.create_ovs_vif_port(self.get_bridge_name(network), + dev, iface_id, mapping['mac'], + instance['uuid']) + + def plug_ovs(self, instance, vif): + self.plug_ovs_ethernet(instance, vif) + def plug(self, instance, vif): network, mapping = vif vif_type = mapping.get('vif_type') @@ -175,6 +210,8 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): if vif_type == network_model.VIF_TYPE_BRIDGE: self.plug_bridge(instance, vif) + elif vif_type == network_model.VIF_TYPE_OVS: + self.plug_ovs(instance, vif) else: raise exception.NovaException( _("Unexpected vif_type=%s") % vif_type) @@ -184,6 +221,21 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): super(LibvirtGenericVIFDriver, self).unplug(instance, vif) + def unplug_ovs_ethernet(self, instance, vif): + """Unplug the VIF by deleting the port from the bridge.""" + super(LibvirtGenericVIFDriver, + self).unplug(instance, vif) + + try: + network, mapping = vif + linux_net.delete_ovs_vif_port(self.get_bridge_name(network), + self.get_vif_devname(mapping)) + except exception.ProcessExecutionError: + LOG.exception(_("Failed while unplugging vif"), instance=instance) + + def unplug_ovs(self, instance, vif): + return self.unplug_ovs_ethernet(instance, vif) + def unplug(self, instance, vif): network, mapping = vif vif_type = mapping.get('vif_type') @@ -199,6 +251,8 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): if vif_type == network_model.VIF_TYPE_BRIDGE: self.unplug_bridge(instance, vif) + elif vif_type == network_model.VIF_TYPE_OVS: + self.unplug_ovs(instance, vif) else: raise exception.NovaException( _("Unexpected vif_type=%s") % vif_type) @@ -219,12 +273,10 @@ class LibvirtBridgeDriver(LibvirtGenericVIFDriver): self.unplug_bridge(instance, vif) -class LibvirtOpenVswitchDriver(LibvirtBaseVIFDriver): - """VIF driver for Open vSwitch that uses libivrt type='ethernet' - - Used for libvirt versions that do not support - OVS virtual port XML (0.9.10 or earlier). - """ +class LibvirtOpenVswitchDriver(LibvirtGenericVIFDriver): + """Retained in Grizzly for compatibility with Quantum + drivers which do not yet report 'vif_type' port binding. + Will be deprecated in Havana, and removed in Ixxxx.""" def get_bridge_name(self, network): return network.get('bridge') or CONF.libvirt_ovs_bridge @@ -233,34 +285,13 @@ class LibvirtOpenVswitchDriver(LibvirtBaseVIFDriver): return mapping.get('ovs_interfaceid') or mapping['vif_uuid'] def get_config(self, instance, network, mapping): - dev = self.get_vif_devname(mapping) - - conf = super(LibvirtOpenVswitchDriver, - self).get_config(instance, - network, - mapping) - - designer.set_vif_host_backend_ethernet_config(conf, dev) - - return conf + return self.get_config_ovs_ethernet(instance, network, mapping) def plug(self, instance, vif): - network, mapping = vif - iface_id = self.get_ovs_interfaceid(mapping) - dev = self.get_vif_devname(mapping) - linux_net.create_tap_dev(dev) - linux_net.create_ovs_vif_port(self.get_bridge_name(network), - dev, iface_id, mapping['mac'], - instance['uuid']) + self.plug_ovs_ethernet(instance, vif) def unplug(self, instance, vif): - """Unplug the VIF by deleting the port from the bridge.""" - try: - network, mapping = vif - linux_net.delete_ovs_vif_port(self.get_bridge_name(network), - self.get_vif_devname(mapping)) - except exception.ProcessExecutionError: - LOG.exception(_("Failed while unplugging vif"), instance=instance) + self.unplug_ovs_ethernet(instance, vif) class LibvirtHybridOVSBridgeDriver(LibvirtBridgeDriver): -- cgit