diff --git a/nova/tests/unit/virt/lxd/test_vif.py b/nova/tests/unit/virt/lxd/test_vif.py index 2cd6aa17..7e2f37c6 100644 --- a/nova/tests/unit/virt/lxd/test_vif.py +++ b/nova/tests/unit/virt/lxd/test_vif.py @@ -168,9 +168,8 @@ class LXDGenericVifDriverTest(test.NoDBTestCase): self.vif_driver = vif.LXDGenericVifDriver() @mock.patch.object(vif, '_post_plug_wiring') - @mock.patch('nova.virt.lxd.vif.linux_net') @mock.patch('nova.virt.lxd.vif.os_vif') - def test_plug_ovs(self, os_vif, linux_net, _post_plug_wiring): + def test_plug_ovs(self, os_vif, _post_plug_wiring): self.vif_driver.plug(INSTANCE, OVS_VIF) self.assertEqual( @@ -180,9 +179,8 @@ class LXDGenericVifDriverTest(test.NoDBTestCase): _post_plug_wiring.assert_called_with(INSTANCE, OVS_VIF) @mock.patch.object(vif, '_post_unplug_wiring') - @mock.patch('nova.virt.lxd.vif.linux_net') @mock.patch('nova.virt.lxd.vif.os_vif') - def test_unplug_ovs(self, os_vif, linux_net, _post_unplug_wiring): + def test_unplug_ovs(self, os_vif, _post_unplug_wiring): self.vif_driver.unplug(INSTANCE, OVS_VIF) self.assertEqual( @@ -220,11 +218,9 @@ class PostPlugTest(test.NoDBTestCase): @mock.patch('nova.virt.lxd.vif._create_veth_pair') @mock.patch('nova.virt.lxd.vif._add_bridge_port') - @mock.patch('nova.virt.lxd.vif.linux_net') @mock.patch('nova.virt.lxd.vif.network_utils') def test_post_plug_ovs_hybrid(self, network_utils, - linux_net, add_bridge_port, create_veth_pair): network_utils.device_exists.return_value = False @@ -240,11 +236,11 @@ class PostPlugTest(test.NoDBTestCase): @mock.patch('nova.virt.lxd.vif._create_veth_pair') @mock.patch('nova.virt.lxd.vif._add_bridge_port') - @mock.patch('nova.virt.lxd.vif.linux_net') + @mock.patch.object(vif, '_create_ovs_vif_port') @mock.patch('nova.virt.lxd.vif.network_utils') def test_post_plug_ovs(self, network_utils, - linux_net, + create_ovs_vif_port, add_bridge_port, create_veth_pair): @@ -257,7 +253,7 @@ class PostPlugTest(test.NoDBTestCase): 'tinda5cc4bf-f1', 1000) add_bridge_port.assert_not_called() - linux_net.create_ovs_vif_port.assert_called_with( + create_ovs_vif_port.assert_called_with( 'br0', 'tapda5cc4bf-f1', 'da5cc4bf-f16c-4807-a0b6-911c7c67c3f8', @@ -268,11 +264,9 @@ class PostPlugTest(test.NoDBTestCase): @mock.patch('nova.virt.lxd.vif._create_veth_pair') @mock.patch('nova.virt.lxd.vif._add_bridge_port') - @mock.patch('nova.virt.lxd.vif.linux_net') @mock.patch('nova.virt.lxd.vif.network_utils') def test_post_plug_bridge(self, network_utils, - linux_net, add_bridge_port, create_veth_pair): network_utils.device_exists.return_value = False @@ -308,12 +302,12 @@ class PostUnplugTest(test.NoDBTestCase): vif._post_unplug_wiring(INSTANCE, OVS_HYBRID_VIF) network_utils.delete_net_dev.assert_called_with('tapda5cc4bf-f1') - @mock.patch('nova.virt.lxd.vif.linux_net') - def test_post_unplug_ovs(self, linux_net): + @mock.patch.object(vif, '_delete_ovs_vif_port') + def test_post_unplug_ovs(self, delete_ovs_vif_port): vif._post_unplug_wiring(INSTANCE, OVS_VIF) - linux_net.delete_ovs_vif_port.assert_called_with('br0', - 'tapda5cc4bf-f1', - True) + delete_ovs_vif_port.assert_called_with('br0', + 'tapda5cc4bf-f1', + True) @mock.patch('nova.virt.lxd.vif.network_utils') def test_post_unplug_bridge(self, network_utils): diff --git a/nova/virt/lxd/vif.py b/nova/virt/lxd/vif.py index 4b6598ef..6df6cf32 100644 --- a/nova/virt/lxd/vif.py +++ b/nova/virt/lxd/vif.py @@ -23,7 +23,6 @@ from nova.network import os_vif_util from nova.network import linux_utils as network_utils import os_vif -from vif_plug_ovs import linux_net CONF = conf.CONF @@ -91,6 +90,44 @@ def _get_tap_config(vif): return {'mac_address': vif['address']} +def _ovs_vsctl(args): + full_args = ['ovs-vsctl', '--timeout=%s' % CONF.ovs_vsctl_timeout] + args + try: + return utils.execute(*full_args, run_as_root=True) + except Exception as e: + LOG.error("Unable to execute %(cmd)s. Exception: %(exception)s", + {'cmd': full_args, 'exception': e}) + raise exception.OvsConfigurationFailure(inner_exception=e) + + +def _create_ovs_vif_cmd(bridge, dev, iface_id, mac, + instance_id, interface_type=None): + cmd = ['--', '--if-exists', 'del-port', dev, '--', + 'add-port', bridge, dev, + '--', 'set', 'Interface', dev, + 'external-ids:iface-id=%s' % iface_id, + 'external-ids:iface-status=active', + 'external-ids:attached-mac=%s' % mac, + 'external-ids:vm-uuid=%s' % instance_id] + if interface_type: + cmd += ['type=%s' % interface_type] + return cmd + + +def _create_ovs_vif_port(bridge, dev, iface_id, mac, instance_id, + mtu=None, interface_type=None): + _ovs_vsctl(_create_ovs_vif_cmd(bridge, dev, iface_id, + mac, instance_id, + interface_type)) + network_utils.set_device_mtu(dev, mtu) + + +def _delete_ovs_vif_port(bridge, dev, delete_dev=True): + _ovs_vsctl(['--', '--if-exists', 'del-port', bridge, dev]) + if delete_dev: + network_utils.delete_net_dev(dev) + + CONFIG_GENERATORS = { 'bridge': _get_bridge_config, 'ovs': _get_ovs_config, @@ -129,12 +166,12 @@ def _post_plug_wiring_veth_and_bridge(instance, vif): _create_veth_pair(v1_name, v2_name, mtu) if _is_ovs_vif_port(vif): # NOTE(jamespage): wire tap device directly to ovs bridge - linux_net.create_ovs_vif_port(vif['network']['bridge'], - v1_name, - vif['id'], - vif['address'], - instance.uuid, - mtu) + _create_ovs_vif_port(vif['network']['bridge'], + v1_name, + vif['id'], + vif['address'], + instance.uuid, + mtu) else: # NOTE(jamespage): wire tap device linux bridge _add_bridge_port(config['bridge'], v1_name) @@ -189,8 +226,8 @@ def _post_unplug_wiring_delete_veth(instance, vif): v1_name = get_vif_devname(vif) try: if _is_ovs_vif_port(vif): - linux_net.delete_ovs_vif_port(vif['network']['bridge'], - v1_name, True) + _delete_ovs_vif_port(vif['network']['bridge'], + v1_name, True) else: network_utils.delete_net_dev(v1_name) except processutils.ProcessExecutionError: