LOG.exception(_LE('Error unable to destroy namespace: %s'), namespace)
+def cleanup_network_namespaces(conf):
+ # Identify namespaces that are candidates for deletion.
+ candidates = [ns for ns in
+ ip_lib.IPWrapper.get_namespaces()
+ if eligible_for_deletion(conf, ns, conf.force)]
+
+ if candidates:
+ time.sleep(2)
+
+ for namespace in candidates:
+ destroy_namespace(conf, namespace, conf.force)
+
+
def main():
"""Main method for cleaning up network namespaces.
conf = setup_conf()
conf()
config.setup_logging()
-
- # Identify namespaces that are candidates for deletion.
- candidates = [ns for ns in
- ip_lib.IPWrapper.get_namespaces()
- if eligible_for_deletion(conf, ns, conf.force)]
-
- if candidates:
- time.sleep(2)
-
- for namespace in candidates:
- destroy_namespace(conf, namespace, conf.force)
+ cleanup_network_namespaces(conf)
MARKED_BLOCK_RULE = '-m mark --mark %s -j DROP' % MARK_VALUE
ICMP_BLOCK_RULE = '-p icmp -j DROP'
VETH_PREFIX = 'tst-vth'
+NS_PREFIX = 'func-'
#TODO(jschwarz): Move these two functions to neutron/tests/common/
self.skipTest(skip_msg)
raise
- def _create_namespace(self):
+ @staticmethod
+ def _cleanup_namespace(namespace):
+ if namespace.netns.exists(namespace.namespace):
+ namespace.netns.delete(namespace.namespace)
+
+ def _create_namespace(self, prefix=NS_PREFIX):
ip_cmd = ip_lib.IPWrapper()
- name = "func-%s" % uuidutils.generate_uuid()
+ name = prefix + uuidutils.generate_uuid()
namespace = ip_cmd.ensure_namespace(name)
- self.addCleanup(namespace.netns.delete, namespace.namespace)
+ self.addCleanup(BaseLinuxTestCase._cleanup_namespace, namespace)
return namespace
device.addr.add(cidr)
device.link.set_up()
- def prepare_veth_pairs(self):
+ def prepare_veth_pairs(self, src_ns_prefix=NS_PREFIX,
+ dst_ns_prefix=NS_PREFIX):
src_addr = self.SRC_ADDRESS
dst_addr = self.DST_ADDRESS
src_veth = get_rand_veth_name()
dst_veth = get_rand_veth_name()
- src_ns = self._create_namespace()
- dst_ns = self._create_namespace()
+ src_ns = self._create_namespace(src_ns_prefix)
+ dst_ns = self._create_namespace(dst_ns_prefix)
src_veth, dst_veth = src_ns.add_veth(src_veth,
dst_veth,
--- /dev/null
+# Copyright (c) 2015 Red Hat, Inc.
+# 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 neutron.agent.l3 import agent as l3_agent
+from neutron.agent.linux import dhcp
+from neutron.agent.linux import ip_lib
+from neutron.cmd import netns_cleanup
+from neutron.tests.functional.agent.linux import base
+
+GET_NAMESPACES = 'neutron.agent.linux.ip_lib.IPWrapper.get_namespaces'
+TEST_INTERFACE_DRIVER = 'neutron.agent.linux.interface.OVSInterfaceDriver'
+
+
+class NetnsCleanupTest(base.BaseIPVethTestCase):
+ def setUp(self):
+ super(NetnsCleanupTest, self).setUp()
+
+ self.get_namespaces_p = mock.patch(GET_NAMESPACES)
+ self.get_namespaces = self.get_namespaces_p.start()
+
+ def setup_config(self, args=None):
+ if args is None:
+ args = []
+ # force option enabled to make sure non-empty namespaces are
+ # cleaned up and deleted
+ args.append('--force')
+
+ self.conf = netns_cleanup.setup_conf()
+ self.conf.set_override('interface_driver', TEST_INTERFACE_DRIVER)
+ self.config_parse(conf=self.conf, args=args)
+
+ def test_cleanup_network_namespaces_cleans_dhcp_and_l3_namespaces(self):
+ l3_ns, dhcp_ns = self.prepare_veth_pairs(l3_agent.NS_PREFIX,
+ dhcp.NS_PREFIX)
+ # we scope the get_namespaces to our own ones not to affect other
+ # tests, as otherwise cleanup will kill them all
+ self.get_namespaces.return_value = [l3_ns.namespace,
+ dhcp_ns.namespace]
+
+ netns_cleanup.cleanup_network_namespaces(self.conf)
+
+ self.get_namespaces_p.stop()
+ namespaces_now = ip_lib.IPWrapper.get_namespaces()
+ self.assertNotIn(l3_ns.namespace, namespaces_now)
+ self.assertNotIn(dhcp_ns.namespace, namespaces_now)