Merge "Ensure the OVS bridge exists when plugging"

This commit is contained in:
Jenkins 2016-07-05 18:36:07 +00:00 committed by Gerrit Code Review
commit 2025adb978
6 changed files with 69 additions and 12 deletions

View File

@ -0,0 +1,7 @@
---
features:
- The ovs plugin has been modified to ensure that the
specified OVS bridge that the vif will be attached to
has been created. If the OVS bridge does not exist, it
will be created with the proper datapath_type.

View File

@ -11,3 +11,6 @@
# under the License.
OVS_VHOSTUSER_INTERFACE_TYPE = 'dpdkvhostuser'
OVS_DATAPATH_SYSTEM = 'system'
OVS_DATAPATH_NETDEV = 'netdev'

View File

@ -60,6 +60,11 @@ def _create_ovs_vif_cmd(bridge, dev, iface_id, mac,
return cmd
def _create_ovs_bridge_cmd(bridge, datapath_type):
return ['--', '--may-exist', 'add-br', bridge,
'--', 'set', 'Bridge', bridge, 'datapath_type=%s' % datapath_type]
@privsep.vif_plug.entrypoint
def create_ovs_vif_port(bridge, dev, iface_id, mac, instance_id,
mtu=None, interface_type=None, timeout=None):
@ -117,6 +122,11 @@ def create_veth_pair(dev1_name, dev2_name, mtu):
_set_device_mtu(dev, mtu)
@privsep.vif_plug.entrypoint
def ensure_ovs_bridge(bridge, datapath_type):
_ovs_vsctl(_create_ovs_bridge_cmd(bridge, datapath_type))
@privsep.vif_plug.entrypoint
def ensure_bridge(bridge):
if not device_exists(bridge):

View File

@ -81,6 +81,8 @@ class OvsPlugin(plugin.PluginBase):
])
def _plug_vhostuser(self, vif, instance_info):
linux_net.ensure_ovs_bridge(vif.network.bridge,
constants.OVS_DATAPATH_NETDEV)
linux_net.create_ovs_vif_port(
vif.network.bridge,
OvsPlugin.gen_port_name("vhu", vif.id),
@ -107,6 +109,8 @@ class OvsPlugin(plugin.PluginBase):
linux_net.create_veth_pair(v1_name, v2_name,
self.config.network_device_mtu)
linux_net.add_bridge_port(vif.bridge_name, v1_name)
linux_net.ensure_ovs_bridge(vif.network.bridge,
constants.OVS_DATAPATH_SYSTEM)
linux_net.create_ovs_vif_port(
vif.network.bridge,
v2_name,
@ -124,7 +128,8 @@ class OvsPlugin(plugin.PluginBase):
profile=vif.port_profile.__class__.__name__)
if isinstance(vif, objects.vif.VIFOpenVSwitch):
pass # no special plugging required
linux_net.ensure_ovs_bridge(vif.network.bridge,
constants.OVS_DATAPATH_SYSTEM)
elif isinstance(vif, objects.vif.VIFBridge):
self._plug_bridge(vif, instance_info)
elif isinstance(vif, objects.vif.VIFVHostUser):

View File

@ -141,6 +141,24 @@ class LinuxNetTest(testtools.TestCase):
'fake-type')
self.assertEqual(expected, cmd)
@mock.patch.object(linux_net, '_create_ovs_bridge_cmd')
@mock.patch.object(linux_net, '_ovs_vsctl')
def test_ensure_ovs_bridge(self, mock_vsctl, mock_create_ovs_bridge):
bridge = 'fake-bridge'
dp_type = 'fake-type'
linux_net.ensure_ovs_bridge(bridge, dp_type)
mock_create_ovs_bridge.assert_called_once_with(bridge, dp_type)
self.assertTrue(mock_vsctl.called)
def test_create_ovs_bridge_cmd(self):
bridge = 'fake-bridge'
dp_type = 'fake-type'
expected = ['--', '--may-exist', 'add-br', bridge,
'--', 'set', 'Bridge', bridge,
'datapath_type=%s' % dp_type]
actual = linux_net._create_ovs_bridge_cmd(bridge, dp_type)
self.assertEqual(expected, actual)
@mock.patch.object(linux_net, '_ovs_vsctl')
@mock.patch.object(linux_net, '_create_ovs_vif_cmd')
@mock.patch.object(linux_net, '_set_device_mtu')

View File

@ -17,6 +17,7 @@ import testtools
from os_vif import objects
from vif_plug_ovs import constants
from vif_plug_ovs import linux_net
from vif_plug_ovs import ovs
@ -88,11 +89,15 @@ class PluginTest(testtools.TestCase):
uuid='f0000000-0000-0000-0000-000000000001')
def test_plug_ovs(self):
plug_bridge_mock = mock.Mock()
plugin = ovs.OvsPlugin.load("ovs")
plugin._plug_bridge = plug_bridge_mock
plugin.plug(self.vif_ovs, self.instance)
self.assertFalse(plug_bridge_mock.called)
with mock.patch.object(linux_net, 'ensure_ovs_bridge') as (
ensure_ovs_bridge):
plug_bridge_mock = mock.Mock()
plugin = ovs.OvsPlugin.load("ovs")
plugin._plug_bridge = plug_bridge_mock
plugin.plug(self.vif_ovs, self.instance)
self.assertFalse(plug_bridge_mock.called)
ensure_ovs_bridge.assert_called_once_with(
self.vif_ovs.network.bridge, constants.OVS_DATAPATH_SYSTEM)
def test_plug_ovs_bridge(self):
calls = {
@ -109,7 +114,9 @@ class PluginTest(testtools.TestCase):
'ca:fe:de:ad:be:ef',
'f0000000-0000-0000-0000-000000000001',
1500,
timeout=120)]
timeout=120)],
'ensure_ovs_bridge': [mock.call('br0',
constants.OVS_DATAPATH_SYSTEM)]
}
with nested(
@ -118,9 +125,10 @@ class PluginTest(testtools.TestCase):
return_value=False),
mock.patch.object(linux_net, 'create_veth_pair'),
mock.patch.object(linux_net, 'add_bridge_port'),
mock.patch.object(linux_net, 'create_ovs_vif_port')
mock.patch.object(linux_net, 'create_ovs_vif_port'),
mock.patch.object(linux_net, 'ensure_ovs_bridge')
) as (ensure_bridge, device_exists, create_veth_pair,
add_bridge_port, create_ovs_vif_port):
add_bridge_port, create_ovs_vif_port, ensure_ovs_bridge):
plugin = ovs.OvsPlugin.load("ovs")
plugin.plug(self.vif_ovs_hybrid, self.instance)
ensure_bridge.assert_has_calls(calls['ensure_bridge'])
@ -128,6 +136,7 @@ class PluginTest(testtools.TestCase):
create_veth_pair.assert_has_calls(calls['create_veth_pair'])
add_bridge_port.assert_has_calls(calls['add_bridge_port'])
create_ovs_vif_port.assert_has_calls(calls['create_ovs_vif_port'])
ensure_ovs_bridge.assert_has_calls(calls['ensure_ovs_bridge'])
def test_unplug_ovs(self):
unplug_bridge_mock = mock.Mock()
@ -160,14 +169,19 @@ class PluginTest(testtools.TestCase):
'f0000000-0000-0000-0000-000000000001',
1500,
interface_type='dpdkvhostuser',
timeout=120)]
timeout=120)],
'ensure_ovs_bridge': [mock.call('br0',
constants.OVS_DATAPATH_NETDEV)]
}
with mock.patch.object(linux_net, 'create_ovs_vif_port') \
as (create_ovs_vif_port):
with nested(
mock.patch.object(linux_net, 'create_ovs_vif_port'),
mock.patch.object(linux_net, 'ensure_ovs_bridge')
) as (create_ovs_vif_port, ensure_ovs_bridge):
plugin = ovs.OvsPlugin.load("ovs")
plugin.plug(self.vif_vhostuser, self.instance)
create_ovs_vif_port.assert_has_calls(calls['create_ovs_vif_port'])
ensure_ovs_bridge.assert_has_calls(calls['ensure_ovs_bridge'])
def test_unplug_ovs_vhostuser(self):
calls = {