diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index ad02ec994943..ecc381c62699 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -1178,16 +1178,6 @@ def _ra_pid_for(dev): return int(f.read()) -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 delete_bridge_dev(dev): """Delete a network bridge.""" if nova.privsep.linux_net.device_exists(dev): @@ -1596,14 +1586,16 @@ class LinuxOVSInterfaceDriver(LinuxNetInterfaceDriver): dev = self.get_dev(network) if not nova.privsep.linux_net.device_exists(dev): bridge = CONF.linuxnet_ovs_integration_bridge - _ovs_vsctl(['--', '--may-exist', 'add-port', bridge, dev, - '--', 'set', 'Interface', dev, 'type=internal', - '--', 'set', 'Interface', dev, - 'external-ids:iface-id=%s' % dev, - '--', 'set', 'Interface', dev, - 'external-ids:iface-status=active', - '--', 'set', 'Interface', dev, - 'external-ids:attached-mac=%s' % mac_address]) + + try: + nova.privsep.linux_net.ovs_plug(CONF.ovs_vsctl_timeout, + bridge, dev, mac_address) + except Exception as e: + LOG.error('Unable to execute ovs-plug. Exception: ' + '%(exception)s', + {'exception': e}) + raise exception.OvsConfigurationFailure(inner_exception=e) + nova.privsep.linux_net.set_device_macaddr( dev, mac_address) nova.privsep.linux_net.set_device_mtu(dev, network.get('mtu')) @@ -1633,7 +1625,14 @@ class LinuxOVSInterfaceDriver(LinuxNetInterfaceDriver): def unplug(self, network): dev = self.get_dev(network) bridge = CONF.linuxnet_ovs_integration_bridge - _ovs_vsctl(['--', '--if-exists', 'del-port', bridge, dev]) + try: + nova.privsep.linux_net.ovs_unplug(CONF.ovs_vsctl_timeout, + bridge, dev) + except Exception as e: + LOG.error('Unable to execute ovs-unplug. Exception: %(exception)s', + {'exception': e}) + raise exception.OvsConfigurationFailure(inner_exception=e) + return dev def get_dev(self, network): diff --git a/nova/privsep/linux_net.py b/nova/privsep/linux_net.py index c80fe6a04a83..c0a6b33d27b0 100644 --- a/nova/privsep/linux_net.py +++ b/nova/privsep/linux_net.py @@ -348,3 +348,22 @@ def start_ra(conf_path, pid_path): '-C', '%s' % conf_path, '-p', '%s' % pid_path] processutils.execute(*cmd) + + +@nova.privsep.sys_admin_pctxt.entrypoint +def ovs_plug(timeout, bridge, dev, mac_address): + processutils.execute('ovs-vsctl', '--timeout=%s' % timeout, + '--', '--may-exist', 'add-port', bridge, dev, + '--', 'set', 'Interface', dev, 'type=internal', + '--', 'set', 'Interface', dev, + 'external-ids:iface-id=%s' % dev, + '--', 'set', 'Interface', dev, + 'external-ids:iface-status=active', + '--', 'set', 'Interface', dev, + 'external-ids:attached-mac=%s' % mac_address) + + +@nova.privsep.sys_admin_pctxt.entrypoint +def ovs_unplug(timeout, bridge, dev): + processutils.execute('ovs-vsctl', '--timeout=%s' % timeout, + '--', '--if-exists', 'del-port', bridge, dev) diff --git a/nova/tests/unit/network/test_linux_net.py b/nova/tests/unit/network/test_linux_net.py index 8c24dd418a65..0170d740ce59 100644 --- a/nova/tests/unit/network/test_linux_net.py +++ b/nova/tests/unit/network/test_linux_net.py @@ -34,7 +34,6 @@ from nova.network import driver from nova.network import linux_net from nova import objects from nova import test -from nova import utils CONF = nova.conf.CONF @@ -642,21 +641,15 @@ class LinuxNetworkTestCase(test.NoDBTestCase): "share_address": False}, "fakemac") self.assertEqual(2, mock_add_rule.call_count) - @mock.patch('nova.privsep.linux_net.device_exists') - @mock.patch.object(utils, 'execute') - def test_linux_ovs_driver_plug_exception(self, mock_execute, + @mock.patch('nova.privsep.linux_net.device_exists', + return_value=False) + @mock.patch( + 'nova.privsep.linux_net.ovs_plug', + side_effect=processutils.ProcessExecutionError('specific_error')) + def test_linux_ovs_driver_plug_exception(self, mock_plug, mock_device_exists): self.flags(fake_network=False) - def fake_execute(*args, **kwargs): - raise processutils.ProcessExecutionError('specific_error') - - def fake_device_exists(*args, **kwargs): - return False - - mock_execute.side_effect = fake_execute - mock_device_exists.side_effect = fake_device_exists - driver = linux_net.LinuxOVSInterfaceDriver() exc = self.assertRaises(exception.OvsConfigurationFailure, @@ -668,7 +661,7 @@ class LinuxNetworkTestCase(test.NoDBTestCase): re.DOTALL)) self.assertIsInstance(exc.kwargs['inner_exception'], processutils.ProcessExecutionError) - mock_execute.assert_called_once() + mock_plug.assert_called_once() mock_device_exists.assert_called_once() @mock.patch.object(linux_net.LinuxBridgeInterfaceDriver,