Make netns_cleanup to purge resources of selected agent only

A new option --agent-type is introduced into netns_cleanup. When it is set
the utility processes namespaces for selected agent only. Possible values
are 'dhcp', 'l3', 'lbaas'. When the option is not set the behaviour stays
unchanged - all namespaces are processed.

Change-Id: Idaaffce767654bf21701a5329742f10a241b2cbf
This commit is contained in:
Ilya Shakhat 2016-02-10 15:18:33 +03:00
parent 5888f79baf
commit ada05d657c
2 changed files with 38 additions and 8 deletions

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import itertools
import re
import time
@ -37,12 +38,11 @@ from neutron.common import config
LOG = logging.getLogger(__name__)
LB_NS_PREFIX = 'qlbaas-'
NS_MANGLING_PATTERN = ('(%s|%s|%s|%s|%s)' % (dhcp.NS_PREFIX,
l3_agent.NS_PREFIX,
dvr.SNAT_NS_PREFIX,
dvr_fip_ns.FIP_NS_PREFIX,
LB_NS_PREFIX) +
attributes.UUID_PATTERN)
NS_PREFIXES = {
'dhcp': [dhcp.NS_PREFIX],
'l3': [l3_agent.NS_PREFIX, dvr.SNAT_NS_PREFIX, dvr_fip_ns.FIP_NS_PREFIX],
'lbaas': [LB_NS_PREFIX],
}
class FakeDhcpPlugin(object):
@ -64,6 +64,9 @@ def setup_conf():
cfg.BoolOpt('force',
default=False,
help=_('Delete the namespace by removing all devices.')),
cfg.StrOpt('agent-type',
choices=['dhcp', 'l3', 'lbaas'],
help=_('Cleanup resources of a specific agent type only.')),
]
conf = cfg.CONF
@ -103,8 +106,15 @@ def eligible_for_deletion(conf, namespace, force=False):
is passed as a parameter.
"""
if conf.agent_type:
prefixes = NS_PREFIXES.get(conf.agent_type)
else:
prefixes = itertools.chain(*NS_PREFIXES.values())
ns_mangling_pattern = '(%s%s)' % ('|'.join(prefixes),
attributes.UUID_PATTERN)
# filter out namespaces without UUID as the name
if not re.match(NS_MANGLING_PATTERN, namespace):
if not re.match(ns_mangling_pattern, namespace):
return False
ip = ip_lib.IPWrapper(namespace=namespace)

View File

@ -48,13 +48,16 @@ class TestNetnsCleanup(base.BaseTestCase):
self.test_kill_dhcp(False)
def test_eligible_for_deletion_ns_not_uuid(self):
conf = mock.Mock()
conf.agent_type = None
ns = 'not_a_uuid'
self.assertFalse(util.eligible_for_deletion(mock.Mock(), ns))
self.assertFalse(util.eligible_for_deletion(conf, ns))
def _test_eligible_for_deletion_helper(self, prefix, force, is_empty,
expected):
ns = prefix + '6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d'
conf = mock.Mock()
conf.agent_type = None
with mock.patch('neutron.agent.linux.ip_lib.IPWrapper') as ip_wrap:
ip_wrap.return_value.namespace_is_empty.return_value = is_empty
@ -84,6 +87,23 @@ class TestNetnsCleanup(base.BaseTestCase):
def test_eligible_for_deletion_snat_namespace(self):
self._test_eligible_for_deletion_helper('snat-', False, True, True)
def test_eligible_for_deletion_filtered_by_agent_type(self):
ns_dhcp = 'qdhcp-' + '6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d'
ns_l3 = 'qrouter-' + '6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d'
conf = mock.Mock()
conf.agent_type = 'dhcp'
with mock.patch('neutron.agent.linux.ip_lib.IPWrapper') as ip_wrap:
ip_wrap.return_value.namespace_is_empty.return_value = True
self.assertEqual(True,
util.eligible_for_deletion(conf, ns_dhcp, False))
self.assertEqual(False,
util.eligible_for_deletion(conf, ns_l3, False))
expected_calls = [mock.call(namespace=ns_dhcp),
mock.call().namespace_is_empty()]
ip_wrap.assert_has_calls(expected_calls)
def test_unplug_device_regular_device(self):
conf = mock.Mock()
device = mock.Mock()