From f832f1073d47a430111c59563962922dfe37a0a5 Mon Sep 17 00:00:00 2001 From: Matt Rae Date: Thu, 16 Mar 2017 01:32:42 -0700 Subject: [PATCH] Add support of a linuxbridge bridge in data-port config When configuring data-port parameter with "ovs-bridge:linuxbridge" a veth pair will be created to connect these two bridges. Name of these virtual interfaces will be "veth-ovsbridge_name" and "veth-linuxbridge_name". Problem: When deploying neutron-openvswitch charm on a node contain only one interface, we are not able to connect an ovs Bridge to the physical interface because it is assigned to juju Bridge. Change-Id: I5be72b9cc5948f5f791d522d1b46fd27e7303613 Closes-Bug:#1635067 --- config.yaml | 3 +++ hooks/neutron_ovs_utils.py | 7 ++++++- unit_tests/test_neutron_ovs_utils.py | 21 +++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/config.yaml b/config.yaml index 36e5298d..eb6ae10c 100644 --- a/config.yaml +++ b/config.yaml @@ -68,6 +68,9 @@ options: bridge:mac for the same bridge so as to be able to configure multiple units. In this case the charm will run through the provided MAC addresses for each bridge until it finds one it can resolve to an interface name. + Port can also be a linuxbridge bridge. In this case a veth pair will be + created, the ovs bridge and the linuxbridge bridge will be connected. It + can be useful to connect the ovs bridge to juju bridge. disable-security-groups: type: boolean default: false diff --git a/hooks/neutron_ovs_utils.py b/hooks/neutron_ovs_utils.py index 24b4b5df..0db4166a 100644 --- a/hooks/neutron_ovs_utils.py +++ b/hooks/neutron_ovs_utils.py @@ -43,6 +43,8 @@ import neutron_ovs_context from charmhelpers.contrib.network.ovs import ( add_bridge, add_bridge_port, + is_linuxbridge_interface, + add_ovsbridge_linuxbridge, full_restart, ) from charmhelpers.core.hookenv import ( @@ -410,7 +412,10 @@ def configure_ovs(): for port, _br in portmaps.iteritems(): if _br == br: - add_bridge_port(br, port, promisc=True) + if not is_linuxbridge_interface(port): + add_bridge_port(br, port, promisc=True) + else: + add_ovsbridge_linuxbridge(br, port) else: # NOTE: when in dpdk mode, add based on pci bus order # with type 'dpdk' diff --git a/unit_tests/test_neutron_ovs_utils.py b/unit_tests/test_neutron_ovs_utils.py index aef7b3d3..a2f30b28 100644 --- a/unit_tests/test_neutron_ovs_utils.py +++ b/unit_tests/test_neutron_ovs_utils.py @@ -31,6 +31,8 @@ import charmhelpers.core.hookenv as hookenv TO_PATCH = [ 'add_bridge', 'add_bridge_port', + 'add_ovsbridge_linuxbridge', + 'is_linuxbridge_interface', 'dpdk_add_bridge_port', 'apt_install', 'apt_update', @@ -322,6 +324,7 @@ class TestNeutronOVSUtils(CharmTestCase): @patch('charmhelpers.contrib.openstack.context.config') def test_configure_ovs_ovs_data_port(self, mock_config, _use_dvr): _use_dvr.return_value = False + self.is_linuxbridge_interface.return_value = False mock_config.side_effect = self.test_config.get self.config.side_effect = self.test_config.get self.ExternalPortContext.return_value = \ @@ -350,6 +353,24 @@ class TestNeutronOVSUtils(CharmTestCase): # Not called since we have a bogus bridge in data-ports self.assertFalse(self.add_bridge_port.called) + @patch.object(nutils, 'use_dvr') + @patch('charmhelpers.contrib.openstack.context.config') + def test_configure_ovs_data_port_with_bridge(self, mock_config, _use_dvr): + _use_dvr.return_value = False + self.is_linuxbridge_interface.return_value = True + mock_config.side_effect = self.test_config.get + self.config.side_effect = self.test_config.get + self.ExternalPortContext.return_value = \ + DummyContext(return_value=None) + + # Now test with bridge:bridge format + self.test_config.set('bridge-mappings', 'physnet1:br-foo') + self.test_config.set('data-port', 'br-foo:br-juju') + self.add_bridge.reset_mock() + self.add_bridge_port.reset_mock() + nutils.configure_ovs() + self.assertTrue(self.add_ovsbridge_linuxbridge.called) + @patch.object(nutils, 'use_dvr') @patch('charmhelpers.contrib.openstack.context.config') def test_configure_ovs_starts_service_if_required(self, mock_config,