]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
only destroy single namespace if router_id is set
authorChristoph Thiel <c.thiel@telekom.de>
Mon, 11 Feb 2013 16:46:59 +0000 (17:46 +0100)
committerChristoph Thiel <c.thiel@telekom.de>
Tue, 12 Feb 2013 07:52:04 +0000 (08:52 +0100)
Fixes bug 1122206

If multiple instances of l3_agent are running on the same host, all qrouter-
namespaces will be destroyed as new l3_agents are started.  This fix allows
for multiple l3_agents to be running on the same host when router_id is set
for each agent.

Change-Id: I879cdc6faba94900f831232232d67e471c70d778

quantum/agent/l3_agent.py
quantum/tests/unit/test_l3_agent.py

index 886b39b7af1e7db2a535684f5f68887058360e72..129efcb942ce8409bfaa235e86d43831d1e1cbb5 100644 (file)
@@ -165,16 +165,23 @@ class L3NATAgent(manager.Manager):
         self.fullsync = True
         self.sync_sem = semaphore.Semaphore(1)
         if self.conf.use_namespaces:
-            self._destroy_all_router_namespaces()
+            self._destroy_router_namespaces(self.conf.router_id)
         super(L3NATAgent, self).__init__(host=self.conf.host)
 
-    def _destroy_all_router_namespaces(self):
-        """Destroy all router namespaces on the host to eliminate
-        all stale linux devices, iptables rules, and namespaces.
+    def _destroy_router_namespaces(self, only_router_id=None):
+        """Destroy router namespaces on the host to eliminate all stale
+        linux devices, iptables rules, and namespaces.
+
+        If only_router_id is passed, only destroy single namespace, to allow
+        for multiple l3 agents on the same host, without stepping on each
+        other's toes on init.  This only makes sense if router_id is set.
         """
         root_ip = ip_lib.IPWrapper(self.root_helper)
         for ns in root_ip.get_namespaces(self.root_helper):
             if ns.startswith(NS_PREFIX):
+                if only_router_id and not ns.endswith(only_router_id):
+                    continue
+
                 try:
                     self._destroy_router_namespace(ns)
                 except:
index d5dcf368c91f9065cbd41268909682ae25f36280..dcf3f466335c023aa70f19a809a937e9a76a7bbd 100644 (file)
@@ -290,9 +290,35 @@ class TestBasicRouterOperations(unittest2.TestCase):
             def __init__(self, name):
                 self.name = name
 
-        self.mock_ip.get_namespaces.return_value = ['qrouter-foo']
+        self.mock_ip.get_namespaces.return_value = ['qrouter-foo',
+                                                    'qrouter-bar']
         self.mock_ip.get_devices.return_value = [FakeDev('qr-aaaa'),
                                                  FakeDev('qgw-aaaa')]
 
         agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
-        agent._destroy_all_router_namespaces()
+
+        agent._destroy_router_namespace = mock.MagicMock()
+        agent._destroy_router_namespaces()
+
+        self.assertEqual(agent._destroy_router_namespace.call_count, 2)
+
+    def testDestroyNamespaceWithRouterId(self):
+
+        class FakeDev(object):
+            def __init__(self, name):
+                self.name = name
+
+        self.conf.router_id = _uuid()
+
+        namespaces = ['qrouter-foo', 'qrouter-' + self.conf.router_id]
+
+        self.mock_ip.get_namespaces.return_value = namespaces
+        self.mock_ip.get_devices.return_value = [FakeDev('qr-aaaa'),
+                                                 FakeDev('qgw-aaaa')]
+
+        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
+
+        agent._destroy_router_namespace = mock.MagicMock()
+        agent._destroy_router_namespaces(self.conf.router_id)
+
+        self.assertEqual(agent._destroy_router_namespace.call_count, 1)