def create(self):
# TODO(Carl) Get this functionality from mlavelle's namespace baseclass
- LOG.debug("add fip-namespace(%s)", self.name)
+ LOG.debug("DVR: add fip namespace: %s", self.name)
ip_wrapper_root = ip_lib.IPWrapper()
- ip_wrapper_root.netns.execute(['sysctl',
- '-w',
- 'net.ipv4.ip_nonlocal_bind=1'],
- run_as_root=True)
ip_wrapper = ip_wrapper_root.ensure_namespace(self.get_name())
+ # Somewhere in the 3.19 kernel timeframe ip_nonlocal_bind was
+ # changed to be a per-namespace attribute. To be backwards
+ # compatible we need to try both if at first we fail.
+ try:
+ ip_wrapper.netns.execute(['sysctl',
+ '-w',
+ 'net.ipv4.ip_nonlocal_bind=1'],
+ log_fail_as_error=False,
+ run_as_root=True)
+ except RuntimeError:
+ LOG.debug('DVR: fip namespace (%s) does not support setting '
+ 'net.ipv4.ip_nonlocal_bind, trying in root namespace',
+ self.name)
+ ip_wrapper_root.netns.execute(['sysctl',
+ '-w',
+ 'net.ipv4.ip_nonlocal_bind=1'],
+ run_as_root=True)
+
ip_wrapper.netns.execute(['sysctl', '-w', 'net.ipv4.ip_forward=1'])
if self.use_ipv6:
ip_wrapper.netns.execute(['sysctl', '-w',
self.agent_gateway_port = None
# TODO(mrsmith): add LOG warn if fip count != 0
- LOG.debug('DVR: destroy fip ns: %s', self.name)
+ LOG.debug('DVR: destroy fip namespace: %s', self.name)
super(FipNamespace, self).delete()
def create_gateway_port(self, agent_gateway_port):
self._as_root([], ('delete', name), use_root_namespace=True)
def execute(self, cmds, addl_env=None, check_exit_code=True,
- extra_ok_codes=None, run_as_root=False):
+ log_fail_as_error=True, extra_ok_codes=None,
+ run_as_root=False):
ns_params = []
kwargs = {'run_as_root': run_as_root}
if self._parent.namespace:
['%s=%s' % pair for pair in addl_env.items()])
cmd = ns_params + env_params + list(cmds)
return utils.execute(cmd, check_exit_code=check_exit_code,
- extra_ok_codes=extra_ok_codes, **kwargs)
+ extra_ok_codes=extra_ok_codes,
+ log_fail_as_error=log_fail_as_error, **kwargs)
def exists(self, name):
if not cfg.CONF.AGENT.use_helper_for_ns_read:
import mock
from oslo_utils import uuidutils
+from neutron.agent.common import utils
from neutron.agent.l3 import dvr_fip_ns
from neutron.agent.l3 import link_local_allocator as lla
from neutron.agent.linux import ip_lib
+from neutron.agent.linux import iptables_manager
from neutron.tests import base
_uuid = uuidutils.generate_uuid
'20.0.0.30',
mock.ANY)
+ @mock.patch.object(iptables_manager, 'IptablesManager')
+ @mock.patch.object(utils, 'execute')
+ @mock.patch.object(ip_lib.IpNetnsCommand, 'exists')
+ def _test_create(self, old_kernel, exists, execute, IPTables):
+ exists.return_value = True
+ # There are up to four sysctl calls - two for ip_nonlocal_bind,
+ # and two to enable forwarding
+ execute.side_effect = [RuntimeError if old_kernel else None,
+ None, None, None]
+
+ self.fip_ns._iptables_manager = IPTables()
+ self.fip_ns.create()
+
+ ns_name = self.fip_ns.get_name()
+
+ netns_cmd = ['ip', 'netns', 'exec', ns_name]
+ bind_cmd = ['sysctl', '-w', 'net.ipv4.ip_nonlocal_bind=1']
+ expected = [mock.call(netns_cmd + bind_cmd, check_exit_code=True,
+ extra_ok_codes=None, log_fail_as_error=False,
+ run_as_root=True)]
+
+ if old_kernel:
+ expected.append(mock.call(bind_cmd, check_exit_code=True,
+ extra_ok_codes=None,
+ log_fail_as_error=True,
+ run_as_root=True))
+
+ execute.assert_has_calls(expected)
+
+ def test_create_old_kernel(self):
+ self._test_create(True)
+
+ def test_create_new_kernel(self):
+ self._test_create(False)
+
@mock.patch.object(ip_lib, 'IPWrapper')
def test_destroy(self, IPWrapper):
ip_wrapper = IPWrapper()
self.execute.assert_called_once_with(['the', 'cmd'],
check_exit_code=True,
extra_ok_codes=None,
- run_as_root=False)
+ run_as_root=False,
+ log_fail_as_error=True)
def test_enable_with_namespace(self):
callback = mock.Mock()
execute.assert_called_once_with(
['ip', 'netns', 'exec', 'ns',
'sysctl', '-w', 'net.ipv4.conf.all.promote_secondaries=1'],
- run_as_root=True, check_exit_code=True, extra_ok_codes=None)
+ run_as_root=True, check_exit_code=True, extra_ok_codes=None,
+ log_fail_as_error=True)
def test_delete_namespace(self):
with mock.patch('neutron.agent.common.utils.execute'):
'link', 'list'],
run_as_root=True,
check_exit_code=True,
- extra_ok_codes=None)
+ extra_ok_codes=None,
+ log_fail_as_error=True)
def test_execute_env_var_prepend(self):
self.parent.namespace = 'ns'
['ip', 'netns', 'exec', 'ns', 'env'] +
['%s=%s' % (k, v) for k, v in env.items()] +
['ip', 'link', 'list'],
- run_as_root=True, check_exit_code=True, extra_ok_codes=None)
+ run_as_root=True, check_exit_code=True, extra_ok_codes=None,
+ log_fail_as_error=True)
def test_execute_nosudo_with_no_namespace(self):
with mock.patch('neutron.agent.common.utils.execute') as execute:
execute.assert_called_once_with(['test'],
check_exit_code=True,
extra_ok_codes=None,
- run_as_root=False)
+ run_as_root=False,
+ log_fail_as_error=True)
class TestDeviceExists(base.BaseTestCase):