Move calls to ovs-vsctl to privsep.

The exception handling isn't perfect, but it keeps the interface
unchanged. Its quite hard to include the command in the exception
like we did before, so I am hoping we can just not do that thing.

Change-Id: I9d46e0dc228ed2df9f681c1a2f4dca3c018c7822
This commit is contained in:
Michael Still 2019-02-26 03:07:24 +00:00 committed by Stephen Finucane
parent 7e98253729
commit 2c29d54fb7
3 changed files with 44 additions and 33 deletions

View File

@ -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):

View File

@ -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)

View File

@ -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,