diff -Nru neutron-8.3.0/debian/changelog neutron-8.3.0/debian/changelog --- neutron-8.3.0/debian/changelog 2016-10-20 16:24:10.000000000 +0000 +++ neutron-8.3.0/debian/changelog 2016-11-10 19:10:37.000000000 +0000 @@ -1,3 +1,11 @@ +neutron (2:8.3.0-0ubuntu1.2) xenial; urgency=medium + + * d/p/check-namespace-before-getting-devices.patch: Cherry-pick patch + from upstream stable/mitaka branch to check if router namespace exists + before getting devices (LP: #1573073). + + -- Corey Bryant Thu, 10 Nov 2016 14:10:37 -0500 + neutron (2:8.3.0-0ubuntu1.1) xenial; urgency=medium * Fix service config typo: diff -Nru neutron-8.3.0/debian/patches/check-namespace-before-getting-devices.patch neutron-8.3.0/debian/patches/check-namespace-before-getting-devices.patch --- neutron-8.3.0/debian/patches/check-namespace-before-getting-devices.patch 1970-01-01 00:00:00.000000000 +0000 +++ neutron-8.3.0/debian/patches/check-namespace-before-getting-devices.patch 2016-11-10 19:10:37.000000000 +0000 @@ -0,0 +1,89 @@ +From 4339740b931dbf4e44f487dfdc91acfb84992d4a Mon Sep 17 00:00:00 2001 +From: Saverio Proto +Date: Thu, 21 Apr 2016 16:50:07 +0200 +Subject: [PATCH] Check if namespace exists before getting devices + +If a neutron router has no ports defined, its namespace is deleted +by the cronjob /etc/cron.d/neutron-l3-agent-netns-cleanup. +It is required to check if the namespace exists before calling +iproute2 commands against the namespace. +It is not enough for the string of the namespace uuid to be defined, +the namespace must really exist on the network node. +This patch checks if the namespace exists when calling get_devices(). +Otherwise the agent log file will be flooded with messages like +Cannot open network namespace "qrouter-": No such file or directory +Failed to process compatible router '' + +Related-bug: 1573073 + +Change-Id: I744ef11529f9da5cbfdb812de0b35b95f9d078bb +(cherry picked from commit 7675495f260daf0174f4e04b36279513889df19a) +--- + neutron/agent/linux/ip_lib.py | 21 +++++++++++++++------ + neutron/tests/unit/agent/linux/test_ip_lib.py | 18 ++++++++++++++++++ + 2 files changed, 33 insertions(+), 6 deletions(-) + +diff --git a/neutron/agent/linux/ip_lib.py b/neutron/agent/linux/ip_lib.py +index aab9dab..3a6a409 100644 +--- a/neutron/agent/linux/ip_lib.py ++++ b/neutron/agent/linux/ip_lib.py +@@ -123,12 +123,21 @@ class IPWrapper(SubProcessBase): + # we call out manually because in order to avoid screen scraping + # iproute2 we use find to see what is in the sysfs directory, as + # suggested by Stephen Hemminger (iproute2 dev). +- output = utils.execute(['ip', 'netns', 'exec', self.namespace, +- 'find', SYS_NET_PATH, '-maxdepth', '1', +- '-type', 'l', '-printf', '%f '], +- run_as_root=True, +- log_fail_as_error=self.log_fail_as_error +- ).split() ++ try: ++ cmd = ['ip', 'netns', 'exec', self.namespace, ++ 'find', SYS_NET_PATH, '-maxdepth', '1', ++ '-type', 'l', '-printf', '%f '] ++ output = utils.execute( ++ cmd, ++ run_as_root=True, ++ log_fail_as_error=self.log_fail_as_error).split() ++ except RuntimeError: ++ # We could be racing with a cron job deleting namespaces. ++ # Just return a empty list if the namespace is deleted. ++ with excutils.save_and_reraise_exception() as ctx: ++ if not self.netns.exists(self.namespace): ++ ctx.reraise = False ++ return [] + else: + output = ( + i for i in os.listdir(SYS_NET_PATH) +diff --git a/neutron/tests/unit/agent/linux/test_ip_lib.py b/neutron/tests/unit/agent/linux/test_ip_lib.py +index 1a3b8c0..9400f70 100644 +--- a/neutron/tests/unit/agent/linux/test_ip_lib.py ++++ b/neutron/tests/unit/agent/linux/test_ip_lib.py +@@ -281,6 +281,24 @@ class TestIpWrapper(base.BaseTestCase): + self.assertTrue(fake_str.split.called) + self.assertEqual(retval, [ip_lib.IPDevice('lo', namespace='foo')]) + ++ @mock.patch('neutron.agent.common.utils.execute') ++ def test_get_devices_namespaces_ns_not_exists(self, mocked_execute): ++ mocked_execute.side_effect = RuntimeError( ++ "Cannot open network namespace") ++ with mock.patch.object(ip_lib.IpNetnsCommand, 'exists', ++ return_value=False): ++ retval = ip_lib.IPWrapper(namespace='foo').get_devices() ++ self.assertEqual([], retval) ++ ++ @mock.patch('neutron.agent.common.utils.execute') ++ def test_get_devices_namespaces_ns_exists(self, mocked_execute): ++ mocked_execute.side_effect = RuntimeError( ++ "Cannot open network namespace") ++ with mock.patch.object(ip_lib.IpNetnsCommand, 'exists', ++ return_value=True): ++ self.assertRaises(RuntimeError, ++ ip_lib.IPWrapper(namespace='foo').get_devices) ++ + def test_get_namespaces(self): + self.execute.return_value = '\n'.join(NETNS_SAMPLE) + retval = ip_lib.IPWrapper.get_namespaces() +-- +2.9.3 + diff -Nru neutron-8.3.0/debian/patches/series neutron-8.3.0/debian/patches/series --- neutron-8.3.0/debian/patches/series 2016-10-20 16:24:10.000000000 +0000 +++ neutron-8.3.0/debian/patches/series 2016-11-10 19:10:37.000000000 +0000 @@ -1,3 +1,4 @@ +check-namespace-before-getting-devices.patch skip-test-secure-client.patch skip-ryu-tests.patch skip-iptest.patch