Revert "Use wrappers instead of direct calls to ip route."

This commit somehow broken floating ips with the l3 agent so we should revert
it till we figure out why.

This reverts commit f80f06a71d.

Change-Id: Ic93eec0d95ad20baf53cc97476fcdff1b308ae91
This commit is contained in:
Aaron Rosen 2013-04-03 15:13:20 -07:00
parent a6bb8f2916
commit 55f2bc05a0
5 changed files with 115 additions and 181 deletions

View File

@ -566,7 +566,7 @@ class DeviceManager(object):
if namespace is None:
device = ip_lib.IPDevice(interface_name,
self.root_helper)
device.route.pullup_route()
device.route.pullup_route(interface_name)
if self.conf.enable_metadata_network:
meta_cidr = netaddr.IPNetwork(METADATA_DEFAULT_IP)

View File

@ -416,8 +416,14 @@ class L3NATAgent(manager.Manager):
gw_ip = ex_gw_port['subnet']['gateway_ip']
if ex_gw_port['subnet']['gateway_ip']:
ip = ip_lib.IPWrapper(self.root_helper, ri.ns_name())
ip.route.add_gateway(gw_ip)
cmd = ['route', 'add', 'default', 'gw', gw_ip]
if self.conf.use_namespaces:
ip_wrapper = ip_lib.IPWrapper(self.root_helper,
namespace=ri.ns_name())
ip_wrapper.netns.execute(cmd, check_exit_code=False)
else:
utils.execute(cmd, check_exit_code=False,
root_helper=self.root_helper)
for (c, r) in self.external_gateway_nat_rules(ex_gw_ip,
internal_cidrs,
@ -639,9 +645,19 @@ class L3NATAgent(manager.Manager):
def after_start(self):
LOG.info(_("L3 agent started"))
def routes_updated(self, ri):
ip = ip_lib.IPWrapper(self.conf.root_helper, ri.ns_name())
def _update_routing_table(self, ri, operation, route):
cmd = ['ip', 'route', operation, 'to', route['destination'],
'via', route['nexthop']]
#TODO(nati) move this code to iplib
if self.conf.use_namespaces:
ip_wrapper = ip_lib.IPWrapper(self.conf.root_helper,
namespace=ri.ns_name())
ip_wrapper.netns.execute(cmd, check_exit_code=False)
else:
utils.execute(cmd, check_exit_code=False,
root_helper=self.conf.root_helper)
def routes_updated(self, ri):
new_routes = ri.router['routes']
old_routes = ri.routes
adds, removes = common_utils.diff_list_of_dict(old_routes,
@ -652,11 +668,11 @@ class L3NATAgent(manager.Manager):
for del_route in removes:
if route['destination'] == del_route['destination']:
removes.remove(del_route)
ip.route.add(route['destination'], route['nexthop'])
#replace success even if there is no existing route
self._update_routing_table(ri, 'replace', route)
for route in removes:
LOG.debug(_("Removed route entry is '%s'"), route)
ip.route.delete(route['destination'], route['nexthop'])
self._update_routing_table(ri, 'delete', route)
ri.routes = new_routes

View File

@ -63,7 +63,6 @@ class IPWrapper(SubProcessBase):
super(IPWrapper, self).__init__(root_helper=root_helper,
namespace=namespace)
self.netns = IpNetnsCommand(self)
self.route = IpRouteCommand(self)
def device(self, name):
return IPDevice(name, self.root_helper, self.namespace)
@ -135,7 +134,7 @@ class IPDevice(SubProcessBase):
self.name = name
self.link = IpLinkCommand(self)
self.addr = IpAddrCommand(self)
self.route = IpRouteDeviceCommand(self)
self.route = IpRouteCommand(self)
def __eq__(self, other):
return (other is not None and self.name == other.name
@ -301,37 +300,35 @@ class IpAddrCommand(IpDeviceCommandBase):
return retval
class IpRouteCommand(IpCommandBase):
class IpRouteCommand(IpDeviceCommandBase):
COMMAND = 'route'
def add_gateway(self, gw, metric=None, dev=None):
"""Adds a default gateway or replaces an existing one."""
args = ['replace', 'default', 'via', gw]
def add_gateway(self, gateway, metric=None):
args = ['replace', 'default', 'via', gateway]
if metric:
args += ['metric', metric]
if dev:
args += ['dev', dev]
args += ['dev', self.name]
self._as_root(*args)
def delete_gateway(self, gw, dev=None):
args = ['delete', 'default', 'via', gw]
if dev:
args += ['dev', dev]
def delete_gateway(self, gateway):
self._as_root('del',
'default',
'via',
gateway,
'dev',
self.name)
self._as_root(*args)
def get_gateway(self, scope=None, filters=None):
if filters is None:
filters = []
retval = None
def get_gateway(self, scope=None, filters=None, dev=None):
args = ['list']
if dev:
args += ['dev', self.name]
if scope:
args += ['scope', scope]
if filters:
args += filters
filters += ['scope', scope]
route_list_lines = self._run(*args).split('\n')
route_list_lines = self._run('list', 'dev', self.name,
*filters).split('\n')
default_route_line = next((x.strip() for x in
route_list_lines if
x.strip().startswith('default')), None)
@ -344,7 +341,7 @@ class IpRouteCommand(IpCommandBase):
if parts_has_metric:
retval.update(metric=int(parts[metric_index]))
return retval
return retval
def pullup_route(self, interface_name):
"""
@ -386,49 +383,6 @@ class IpRouteCommand(IpCommandBase):
self._as_root('append', subnet, 'proto', 'kernel',
'dev', device)
def add(self, destination, nexthop, dev=None):
"""Adds a new route or replaces an existing one."""
args = ['replace', 'to', destination, 'via', nexthop]
if dev:
args += ['dev', dev]
self._as_root(*args)
def delete(self, destination, nexthop, dev=None):
args = ['delete', 'to', destination, 'via', nexthop]
if dev:
args += ['dev', dev]
self._as_root(*args)
class IpRouteDeviceCommand(IpDeviceCommandBase):
"""Wrapper for ip route actions which are bound to a specific device"""
def __init__(self, parent):
super(IpRouteDeviceCommand, self).__init__(parent)
self._route = IpRouteCommand(parent)
def add_gateway(self, gw, metric=None):
return self._route.add_gateway(gw, metric, self.name)
def delete_gateway(self, gw):
return self._route.delete_gateway(gw, self.name)
def get_gateway(self, scope=None, filters=None):
return self._route.get_gateway(scope, filters, self.name)
def pullup_route(self):
return self._route.pullup_route(self.name)
def add(self, destination, nexthop):
return self._route.add(destination, nexthop, self.name)
def delete(self, destination, nexthop):
return self._route.delete(destination, nexthop, self.name)
class IpNetnsCommand(IpCommandBase):
COMMAND = 'netns'

View File

@ -66,9 +66,9 @@ class TestBasicRouterOperations(base.BaseTestCase):
driver_cls.return_value = self.mock_driver
self.ip_cls_p = mock.patch('quantum.agent.linux.ip_lib.IPWrapper')
self.ip_cls = self.ip_cls_p.start()
ip_cls = self.ip_cls_p.start()
self.mock_ip = mock.MagicMock()
self.ip_cls.return_value = self.mock_ip
ip_cls.return_value = self.mock_ip
self.l3pluginApi_cls_p = mock.patch(
'quantum.agent.l3_agent.L3PluginApi')
@ -210,15 +210,57 @@ class TestBasicRouterOperations(base.BaseTestCase):
def testAgentRemoveFloatingIP(self):
self._test_floating_ip_action('remove')
def _check_route_calls(self, action, calls, namespace):
mocks = {
'replace': self.mock_ip.route.add,
'delete': self.mock_ip.route.delete
}
def _check_agent_method_called(self, agent, calls, namespace):
if namespace:
self.mock_ip.netns.execute.assert_has_calls(
[mock.call(call, check_exit_code=False) for call in calls],
any_order=True)
else:
self.utils_exec.assert_has_calls([
mock.call(call, root_helper='sudo',
check_exit_code=False) for call in calls],
any_order=True)
m = mocks[action]
m.assert_has_calls([mock.call(*call) for call in calls],
any_order=True)
def _test_routing_table_update(self, namespace):
if not namespace:
self.conf.set_override('use_namespaces', False)
router_id = _uuid()
ri = l3_agent.RouterInfo(router_id, self.conf.root_helper,
self.conf.use_namespaces,
None)
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
fake_route1 = {'destination': '135.207.0.0/16',
'nexthop': '1.2.3.4'}
fake_route2 = {'destination': '135.207.111.111/32',
'nexthop': '1.2.3.4'}
agent._update_routing_table(ri, 'replace', fake_route1)
expected = [['ip', 'route', 'replace', 'to', '135.207.0.0/16',
'via', '1.2.3.4']]
self._check_agent_method_called(agent, expected, namespace)
agent._update_routing_table(ri, 'delete', fake_route1)
expected = [['ip', 'route', 'delete', 'to', '135.207.0.0/16',
'via', '1.2.3.4']]
self._check_agent_method_called(agent, expected, namespace)
agent._update_routing_table(ri, 'replace', fake_route2)
expected = [['ip', 'route', 'replace', 'to', '135.207.111.111/32',
'via', '1.2.3.4']]
self._check_agent_method_called(agent, expected, namespace)
agent._update_routing_table(ri, 'delete', fake_route2)
expected = [['ip', 'route', 'delete', 'to', '135.207.111.111/32',
'via', '1.2.3.4']]
self._check_agent_method_called(agent, expected, namespace)
def testAgentRoutingTableUpdated(self):
self._test_routing_table_update(namespace=True)
def testAgentRoutingTableUpdatedNoNameSpace(self):
self._test_routing_table_update(namespace=False)
def testRoutesUpdated(self):
self._test_routes_updated(namespace=True)
@ -246,24 +288,28 @@ class TestBasicRouterOperations(base.BaseTestCase):
ri.router['routes'] = fake_new_routes
agent.routes_updated(ri)
expected = [['110.100.30.0/24', '10.100.10.30'],
['110.100.31.0/24', '10.100.10.30']]
expected = [['ip', 'route', 'replace', 'to', '110.100.30.0/24',
'via', '10.100.10.30'],
['ip', 'route', 'replace', 'to', '110.100.31.0/24',
'via', '10.100.10.30']]
self._check_route_calls('replace', expected, ri.ns_name())
self._check_agent_method_called(agent, expected, namespace)
fake_new_routes = [{'destination': "110.100.30.0/24",
'nexthop': "10.100.10.30"}]
ri.router['routes'] = fake_new_routes
agent.routes_updated(ri)
expected = [['110.100.31.0/24', '10.100.10.30']]
expected = [['ip', 'route', 'delete', 'to', '110.100.31.0/24',
'via', '10.100.10.30']]
self._check_route_calls('delete', expected, ri.ns_name())
self._check_agent_method_called(agent, expected, namespace)
fake_new_routes = []
ri.router['routes'] = fake_new_routes
agent.routes_updated(ri)
expected = [['110.100.30.0/24', '10.100.10.30']]
self._check_route_calls('delete', expected, ri.ns_name())
expected = [['ip', 'route', 'delete', 'to', '110.100.30.0/24',
'via', '10.100.10.30']]
self._check_agent_method_called(agent, expected, namespace)
def testProcessRouter(self):

View File

@ -549,54 +549,25 @@ class TestIpAddrCommand(TestIPCmdBase):
class TestIpRouteCommand(TestIPCmdBase):
def setUp(self):
super(TestIpRouteCommand, self).setUp()
self.parent.name = 'eth0'
self.command = 'route'
self.route_cmd = ip_lib.IpRouteCommand(self.parent)
def test_add(self):
dst = '10.0.1.0/24'
nexthop = '192.168.1.1'
self.route_cmd.add(dst, nexthop)
self._assert_sudo([], ('replace', 'to', dst, 'via', nexthop))
def test_delete(self):
dst = '10.0.1.0/24'
nexthop = '192.168.1.1'
self.route_cmd.delete(dst, nexthop)
self._assert_sudo([], ('delete', 'to', dst, 'via', nexthop))
def test_add_gateway(self):
gw = '10.0.1.1'
self.route_cmd.add_gateway(gw)
self._assert_sudo([], ('replace', 'default', 'via', gw))
def test_delete_gateway(self):
gw = '10.0.1.1'
self.route_cmd.delete_gateway(gw)
self._assert_sudo([], ('delete', 'default', 'via', gw))
def test_add_gateway_with_metric_dev(self):
gateway = '192.168.45.100'
metric = 100
dev = 'eth0'
self.route_cmd.add_gateway(gateway, metric, dev)
self.route_cmd.add_gateway(gateway, metric)
self._assert_sudo([],
('replace', 'default', 'via', gateway,
'metric', metric,
'dev', dev))
'dev', self.parent.name))
def test_delete_gateway_with_dev(self):
def test_del_gateway(self):
gateway = '192.168.45.100'
dev = 'eth0'
self.route_cmd.delete_gateway(gateway, dev)
self.route_cmd.delete_gateway(gateway)
self._assert_sudo([],
('delete', 'default', 'via', gateway,
'dev', dev))
('del', 'default', 'via', gateway,
'dev', self.parent.name))
def test_get_gateway(self):
test_cases = [{'sample': GATEWAY_SAMPLE1,
@ -643,59 +614,6 @@ class TestIpRouteCommand(TestIPCmdBase):
self.assertEqual(len(self.parent._run.mock_calls), 2)
class TestIpRouteDeviceCommand(TestIPCmdBase):
def setUp(self):
super(TestIpRouteDeviceCommand, self).setUp()
self.parent.name = 'eth0'
self.command = 'route'
self.route_cmd = ip_lib.IpRouteDeviceCommand(self.parent)
route_p = mock.patch.object(self.route_cmd, '_route')
self._route = route_p.start()
def test_add_gateway(self):
gw = '10.0.0.1'
metric = 100
self.route_cmd.add_gateway(gw, metric)
self._route.add_gateway.assert_called_once_with(gw, metric,
self.route_cmd.name)
def test_delete_gateway(self):
gw = '10.0.0.1'
self.route_cmd.delete_gateway(gw)
self._route.delete_gateway.assert_called_once_with(gw,
self.route_cmd.name)
def test_get_gateway(self):
scope = 'scope'
filters = []
self.route_cmd.get_gateway(scope, filters)
self._route.get_gateway.assert_called_once_with(scope, filters,
self.route_cmd.name)
def test_add(self):
dst = '8.8.8.8'
via = '10.0.1.4'
self.route_cmd.add(dst, via)
self._route.add.assert_called_once_with(dst, via, self.route_cmd.name)
def test_delete(self):
dst = '8.8.8.8'
via = '10.0.1.4'
self.route_cmd.delete(dst, via)
self._route.delete.assert_called_once_with(dst, via,
self.route_cmd.name)
def test_pullup_route(self):
self.route_cmd.pullup_route()
self._route.pullup_route.assert_called_once_with(self.route_cmd.name)
class TestIpNetnsCommand(TestIPCmdBase):
def setUp(self):
super(TestIpNetnsCommand, self).setUp()