Merge "Move create_tap_dev into privsep."
This commit is contained in:
commit
33f367ec2f
|
@ -17,40 +17,15 @@
|
|||
|
||||
"""Utility methods for linux networking."""
|
||||
|
||||
from oslo_concurrency import processutils
|
||||
from oslo_log import log as logging
|
||||
|
||||
from nova.pci import utils as pci_utils
|
||||
import nova.privsep.linux_net
|
||||
from nova import utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def create_tap_dev(dev, mac_address=None, multiqueue=False):
|
||||
if not nova.privsep.linux_net.device_exists(dev):
|
||||
try:
|
||||
# First, try with 'ip'
|
||||
cmd = ('ip', 'tuntap', 'add', dev, 'mode', 'tap')
|
||||
if multiqueue:
|
||||
cmd = cmd + ('multi_queue', )
|
||||
utils.execute(*cmd, run_as_root=True, check_exit_code=[0, 2, 254])
|
||||
except processutils.ProcessExecutionError:
|
||||
if multiqueue:
|
||||
LOG.warning(
|
||||
'Failed to create a tap device with ip tuntap. '
|
||||
'tunctl does not support creation of multi-queue '
|
||||
'enabled devices, skipping fallback.')
|
||||
raise
|
||||
|
||||
# Second option: tunctl
|
||||
utils.execute('tunctl', '-b', '-t', dev, run_as_root=True)
|
||||
if mac_address:
|
||||
nova.privsep.linux_net.set_device_macaddr(dev, mac_address)
|
||||
nova.privsep.linux_net.set_device_enabled(dev)
|
||||
|
||||
|
||||
def set_vf_interface_vlan(pci_addr, mac_addr, vlan=0):
|
||||
pf_ifname = pci_utils.get_ifname_by_pci_address(pci_addr,
|
||||
pf_interface=True)
|
||||
|
|
|
@ -87,6 +87,10 @@ def _set_device_mtu_inner(dev, mtu):
|
|||
|
||||
@nova.privsep.sys_admin_pctxt.entrypoint
|
||||
def set_device_enabled(dev):
|
||||
_set_device_enabled_inner(dev)
|
||||
|
||||
|
||||
def _set_device_enabled_inner(dev):
|
||||
processutils.execute('ip', 'link', 'set', dev, 'up',
|
||||
check_exit_code=[0, 2, 254])
|
||||
|
||||
|
@ -98,6 +102,10 @@ def set_device_disabled(dev):
|
|||
|
||||
@nova.privsep.sys_admin_pctxt.entrypoint
|
||||
def set_device_macaddr(dev, mac_addr, port_state=None):
|
||||
_set_device_macaddr_inner(dev, mac_addr, port_state=port_state)
|
||||
|
||||
|
||||
def _set_device_macaddr_inner(dev, mac_addr, port_state=None):
|
||||
if port_state:
|
||||
processutils.execute('ip', 'link', 'set', dev, 'address', mac_addr,
|
||||
port_state, check_exit_code=[0, 2, 254])
|
||||
|
@ -125,3 +133,33 @@ def bind_ip(device, ip, scope_is_link=False):
|
|||
processutils.execute('ip', 'addr', 'add', str(ip) + '/32',
|
||||
'scope', 'link', 'dev', device,
|
||||
check_exit_code=[0, 2, 254])
|
||||
|
||||
|
||||
@nova.privsep.sys_admin_pctxt.entrypoint
|
||||
def create_tap_dev(dev, mac_address=None, multiqueue=False):
|
||||
_create_tap_dev_inner(dev, mac_address=mac_address,
|
||||
multiqueue=multiqueue)
|
||||
|
||||
|
||||
def _create_tap_dev_inner(dev, mac_address=None, multiqueue=False):
|
||||
if not device_exists(dev):
|
||||
try:
|
||||
# First, try with 'ip'
|
||||
cmd = ('ip', 'tuntap', 'add', dev, 'mode', 'tap')
|
||||
if multiqueue:
|
||||
cmd = cmd + ('multi_queue', )
|
||||
processutils.execute(*cmd, check_exit_code=[0, 2, 254])
|
||||
except processutils.ProcessExecutionError:
|
||||
if multiqueue:
|
||||
LOG.warning(
|
||||
'Failed to create a tap device with ip tuntap. '
|
||||
'tunctl does not support creation of multi-queue '
|
||||
'enabled devices, skipping fallback.')
|
||||
raise
|
||||
|
||||
# Second option: tunctl
|
||||
processutils.execute('tunctl', '-b', '-t', dev)
|
||||
|
||||
if mac_address:
|
||||
_set_device_macaddr_inner(dev, mac_address)
|
||||
_set_device_enabled_inner(dev)
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
# Copyright 2011 NTT
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import mock
|
||||
|
||||
from oslo_concurrency import processutils
|
||||
|
||||
from nova.network import linux_utils as net_utils
|
||||
from nova import test
|
||||
|
||||
|
||||
class NetUtilsTestCase(test.NoDBTestCase):
|
||||
@mock.patch('nova.utils.execute')
|
||||
@mock.patch('nova.privsep.linux_net.set_device_enabled')
|
||||
def test_create_tap_dev(self, mock_enabled, mock_execute):
|
||||
net_utils.create_tap_dev('tap42')
|
||||
|
||||
mock_execute.assert_has_calls([
|
||||
mock.call('ip', 'tuntap', 'add', 'tap42', 'mode', 'tap',
|
||||
run_as_root=True, check_exit_code=[0, 2, 254])
|
||||
])
|
||||
mock_enabled.assert_called_once_with('tap42')
|
||||
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
@mock.patch('nova.utils.execute')
|
||||
def test_create_tap_skipped_when_exists(self, mock_execute, mock_exists):
|
||||
net_utils.create_tap_dev('tap42')
|
||||
|
||||
mock_exists.assert_called_once_with('/sys/class/net/tap42')
|
||||
mock_execute.assert_not_called()
|
||||
|
||||
@mock.patch('nova.utils.execute')
|
||||
@mock.patch('nova.privsep.linux_net.set_device_enabled')
|
||||
@mock.patch('nova.privsep.linux_net.set_device_macaddr')
|
||||
def test_create_tap_dev_mac(self, mock_set_macaddr, mock_enabled,
|
||||
mock_execute):
|
||||
net_utils.create_tap_dev('tap42', '00:11:22:33:44:55')
|
||||
|
||||
mock_execute.assert_has_calls([
|
||||
mock.call('ip', 'tuntap', 'add', 'tap42', 'mode', 'tap',
|
||||
run_as_root=True, check_exit_code=[0, 2, 254])
|
||||
])
|
||||
mock_enabled.assert_called_once_with('tap42')
|
||||
mock_set_macaddr.assert_has_calls([
|
||||
mock.call('tap42', '00:11:22:33:44:55')])
|
||||
|
||||
@mock.patch('nova.utils.execute')
|
||||
@mock.patch('nova.privsep.linux_net.set_device_enabled')
|
||||
def test_create_tap_dev_fallback_to_tunctl(self, mock_enabled,
|
||||
mock_execute):
|
||||
# ip failed, fall back to tunctl
|
||||
mock_execute.side_effect = [processutils.ProcessExecutionError, 0, 0]
|
||||
|
||||
net_utils.create_tap_dev('tap42')
|
||||
|
||||
mock_execute.assert_has_calls([
|
||||
mock.call('ip', 'tuntap', 'add', 'tap42', 'mode', 'tap',
|
||||
run_as_root=True, check_exit_code=[0, 2, 254]),
|
||||
mock.call('tunctl', '-b', '-t', 'tap42',
|
||||
run_as_root=True)
|
||||
])
|
||||
mock_enabled.assert_called_once_with('tap42')
|
||||
|
||||
@mock.patch('nova.utils.execute')
|
||||
@mock.patch('nova.privsep.linux_net.set_device_enabled')
|
||||
def test_create_tap_dev_multiqueue(self, mock_enabled, mock_execute):
|
||||
net_utils.create_tap_dev('tap42', multiqueue=True)
|
||||
|
||||
mock_execute.assert_has_calls([
|
||||
mock.call('ip', 'tuntap', 'add', 'tap42', 'mode', 'tap',
|
||||
'multi_queue',
|
||||
run_as_root=True, check_exit_code=[0, 2, 254])
|
||||
])
|
||||
mock_enabled.assert_called_once_with('tap42')
|
||||
|
||||
@mock.patch('nova.utils.execute')
|
||||
def test_create_tap_dev_multiqueue_tunctl_raises(self, mock_execute):
|
||||
# if creation of a tap by the means of ip command fails,
|
||||
# create_tap_dev() will try to do that by the means of tunctl
|
||||
mock_execute.side_effect = processutils.ProcessExecutionError
|
||||
# but tunctl can't create multiqueue taps, so the failure is expected
|
||||
self.assertRaises(processutils.ProcessExecutionError,
|
||||
net_utils.create_tap_dev,
|
||||
'tap42', multiqueue=True)
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
import mock
|
||||
|
||||
from oslo_concurrency import processutils
|
||||
|
||||
import nova.privsep.linux_net
|
||||
from nova import test
|
||||
|
||||
|
@ -28,3 +30,76 @@ class LinuxNetTestCase(test.NoDBTestCase):
|
|||
calls = []
|
||||
nova.privsep.linux_net._set_device_mtu_inner('fake-dev', None)
|
||||
mock_exec.assert_has_calls(calls)
|
||||
|
||||
@mock.patch('oslo_concurrency.processutils.execute')
|
||||
@mock.patch('nova.privsep.linux_net._set_device_enabled_inner')
|
||||
def test_create_tap_dev(self, mock_enabled, mock_execute):
|
||||
nova.privsep.linux_net._create_tap_dev_inner('tap42')
|
||||
|
||||
mock_execute.assert_has_calls([
|
||||
mock.call('ip', 'tuntap', 'add', 'tap42', 'mode', 'tap',
|
||||
check_exit_code=[0, 2, 254])
|
||||
])
|
||||
mock_enabled.assert_called_once_with('tap42')
|
||||
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
@mock.patch('oslo_concurrency.processutils.execute')
|
||||
def test_create_tap_skipped_when_exists(self, mock_execute, mock_exists):
|
||||
nova.privsep.linux_net._create_tap_dev_inner('tap42')
|
||||
|
||||
mock_exists.assert_called_once_with('/sys/class/net/tap42')
|
||||
mock_execute.assert_not_called()
|
||||
|
||||
@mock.patch('oslo_concurrency.processutils.execute')
|
||||
@mock.patch('nova.privsep.linux_net._set_device_enabled_inner')
|
||||
@mock.patch('nova.privsep.linux_net._set_device_macaddr_inner')
|
||||
def test_create_tap_dev_mac(self, mock_set_macaddr, mock_enabled,
|
||||
mock_execute):
|
||||
nova.privsep.linux_net._create_tap_dev_inner(
|
||||
'tap42', '00:11:22:33:44:55')
|
||||
|
||||
mock_execute.assert_has_calls([
|
||||
mock.call('ip', 'tuntap', 'add', 'tap42', 'mode', 'tap',
|
||||
check_exit_code=[0, 2, 254])
|
||||
])
|
||||
mock_enabled.assert_called_once_with('tap42')
|
||||
mock_set_macaddr.assert_has_calls([
|
||||
mock.call('tap42', '00:11:22:33:44:55')])
|
||||
|
||||
@mock.patch('oslo_concurrency.processutils.execute')
|
||||
@mock.patch('nova.privsep.linux_net._set_device_enabled_inner')
|
||||
def test_create_tap_dev_fallback_to_tunctl(self, mock_enabled,
|
||||
mock_execute):
|
||||
# ip failed, fall back to tunctl
|
||||
mock_execute.side_effect = [processutils.ProcessExecutionError, 0, 0]
|
||||
|
||||
nova.privsep.linux_net._create_tap_dev_inner('tap42')
|
||||
|
||||
mock_execute.assert_has_calls([
|
||||
mock.call('ip', 'tuntap', 'add', 'tap42', 'mode', 'tap',
|
||||
check_exit_code=[0, 2, 254]),
|
||||
mock.call('tunctl', '-b', '-t', 'tap42')
|
||||
])
|
||||
mock_enabled.assert_called_once_with('tap42')
|
||||
|
||||
@mock.patch('oslo_concurrency.processutils.execute')
|
||||
@mock.patch('nova.privsep.linux_net._set_device_enabled_inner')
|
||||
def test_create_tap_dev_multiqueue(self, mock_enabled, mock_execute):
|
||||
nova.privsep.linux_net._create_tap_dev_inner(
|
||||
'tap42', multiqueue=True)
|
||||
|
||||
mock_execute.assert_has_calls([
|
||||
mock.call('ip', 'tuntap', 'add', 'tap42', 'mode', 'tap',
|
||||
'multi_queue', check_exit_code=[0, 2, 254])
|
||||
])
|
||||
mock_enabled.assert_called_once_with('tap42')
|
||||
|
||||
@mock.patch('oslo_concurrency.processutils.execute')
|
||||
def test_create_tap_dev_multiqueue_tunctl_raises(self, mock_execute):
|
||||
# if creation of a tap by the means of ip command fails,
|
||||
# create_tap_dev() will try to do that by the means of tunctl
|
||||
mock_execute.side_effect = processutils.ProcessExecutionError
|
||||
# but tunctl can't create multiqueue taps, so the failure is expected
|
||||
self.assertRaises(processutils.ProcessExecutionError,
|
||||
nova.privsep.linux_net._create_tap_dev_inner,
|
||||
'tap42', multiqueue=True)
|
||||
|
|
|
@ -1026,7 +1026,8 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
|||
|
||||
@mock.patch('nova.privsep.linux_net.device_exists')
|
||||
@mock.patch('nova.privsep.libvirt.plug_plumgrid_vif')
|
||||
def test_plug_iovisor(self, mock_plug, device_exists):
|
||||
@mock.patch('nova.privsep.linux_net.create_tap_dev')
|
||||
def test_plug_iovisor(self, mock_create_tap_dev, mock_plug, device_exists):
|
||||
device_exists.return_value = True
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
d.plug(self.instance, self.vif_iovisor)
|
||||
|
@ -1119,7 +1120,9 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
|||
|
||||
@mock.patch('nova.privsep.linux_net.device_exists', return_value=True)
|
||||
@mock.patch('nova.privsep.linux_net.set_device_mtu')
|
||||
def test_plug_tap(self, mock_set_mtu, mock_device_exists):
|
||||
@mock.patch('nova.privsep.linux_net.create_tap_dev')
|
||||
def test_plug_tap(self, mock_create_tap_dev, mock_set_mtu,
|
||||
mock_device_exists):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
d.plug(self.instance, self.vif_tap)
|
||||
|
||||
|
|
|
@ -648,7 +648,7 @@ class LibvirtGenericVIFDriver(object):
|
|||
dev = self.get_vif_devname(vif)
|
||||
port_id = vif['id']
|
||||
try:
|
||||
linux_net_utils.create_tap_dev(dev)
|
||||
nova.privsep.linux_net.create_tap_dev(dev)
|
||||
nova.privsep.libvirt.plug_midonet_vif(port_id, dev)
|
||||
except processutils.ProcessExecutionError:
|
||||
LOG.exception(_("Failed while plugging vif"), instance=instance)
|
||||
|
@ -661,7 +661,7 @@ class LibvirtGenericVIFDriver(object):
|
|||
"""
|
||||
dev = self.get_vif_devname(vif)
|
||||
iface_id = vif['id']
|
||||
linux_net_utils.create_tap_dev(dev)
|
||||
nova.privsep.linux_net.create_tap_dev(dev)
|
||||
net_id = vif['network']['id']
|
||||
tenant_id = instance.project_id
|
||||
try:
|
||||
|
@ -674,7 +674,7 @@ class LibvirtGenericVIFDriver(object):
|
|||
"""Plug a VIF_TYPE_TAP virtual interface."""
|
||||
dev = self.get_vif_devname(vif)
|
||||
mac = vif['details'].get(network_model.VIF_DETAILS_TAP_MAC_ADDRESS)
|
||||
linux_net_utils.create_tap_dev(dev, mac)
|
||||
nova.privsep.linux_net.create_tap_dev(dev, mac)
|
||||
network = vif.get('network')
|
||||
mtu = network.get_meta('mtu') if network else None
|
||||
nova.privsep.linux_net.set_device_mtu(dev, mtu)
|
||||
|
|
Loading…
Reference in New Issue