Mark subnet deletion state during subnet deletion
1. What is the problem As reported in the bug page, local subnet will be recreated after central subnet is deleted 2. What is the solution for the problem The reason for the recreation is that DhcpAgentNotifyAPI subscribe the subnet deletion event and will call get_network during subnet deletion, get_network will call _ensure_subnet to create the subnet. So we need a way to distinguish the call from API and callback. A dict on_subnet_delete is added to local plugin in this patch. In delete_subnet, before calling real core pluing's delete_subnet method, we first add a new item (request_id, True) to this dict. After the calling, this item is removed. So in get_network, we can check whether the dict contains the request_id, if so, we know that we are in the subnet deletion stage, then we don't call _ensure_subnet. 3. What features need to be implemented to the Tricircle to realize the solution No new features Change-Id: Ie79460aa763918be7c522263d9865847fc0da828 Closes-Bug: #1680757
This commit is contained in:
parent
50067c3b4b
commit
af2cce9364
|
@ -73,6 +73,7 @@ class TricirclePlugin(plugin.Ml2Plugin):
|
|||
self.neutron_handle.endpoint_url = \
|
||||
cfg.CONF.tricircle.central_neutron_url
|
||||
self.on_trunk_create = {}
|
||||
self.on_subnet_delete = {}
|
||||
|
||||
def start_rpc_listeners(self):
|
||||
return self.core_plugin.start_rpc_listeners()
|
||||
|
@ -86,6 +87,22 @@ class TricirclePlugin(plugin.Ml2Plugin):
|
|||
def rpc_state_report_workers_supported(self):
|
||||
return self.core_plugin.rpc_state_report_workers_supported()
|
||||
|
||||
def _start_subnet_delete(self, context):
|
||||
if context.request_id:
|
||||
LOG.debug('subnet delete start for ' + context.request_id)
|
||||
self.on_subnet_delete[context.request_id] = True
|
||||
|
||||
def _end_subnet_delete(self, context):
|
||||
if context.request_id:
|
||||
LOG.debug('subnet delete end for ' + context.request_id)
|
||||
self.on_subnet_delete.pop(context.request_id, None)
|
||||
|
||||
def _in_subnet_delete(self, context):
|
||||
if context.request_id:
|
||||
LOG.debug('check subnet delete state for ' + context.request_id)
|
||||
return context.request_id in self.on_subnet_delete
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _adapt_network_body(network):
|
||||
network_type = network.get(provider_net.NETWORK_TYPE)
|
||||
|
@ -230,8 +247,13 @@ class TricirclePlugin(plugin.Ml2Plugin):
|
|||
def get_network(self, context, _id, fields=None):
|
||||
try:
|
||||
b_network = self.core_plugin.get_network(context, _id)
|
||||
subnet_ids = self._ensure_subnet(context, b_network, False)
|
||||
if not self._in_subnet_delete(context):
|
||||
subnet_ids = self._ensure_subnet(context, b_network, False)
|
||||
else:
|
||||
subnet_ids = []
|
||||
except q_exceptions.NotFound:
|
||||
if self._in_subnet_delete(context):
|
||||
raise
|
||||
t_ctx = t_context.get_context_from_neutron_context(context)
|
||||
if self._skip_non_api_query(t_ctx):
|
||||
raise q_exceptions.NetworkNotFound(net_id=_id)
|
||||
|
@ -386,6 +408,15 @@ class TricirclePlugin(plugin.Ml2Plugin):
|
|||
b_subnets.append(self._fields(b_subnet, fields))
|
||||
return b_subnets
|
||||
|
||||
def delete_subnet(self, context, _id):
|
||||
self._start_subnet_delete(context)
|
||||
try:
|
||||
self.core_plugin.delete_subnet(context, _id)
|
||||
except Exception:
|
||||
raise
|
||||
finally:
|
||||
self._end_subnet_delete(context)
|
||||
|
||||
def update_subnet(self, context, _id, subnet):
|
||||
"""update bottom subnet
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ class FakeContext(object):
|
|||
self.session = FakeSession()
|
||||
self.auth_token = 'token'
|
||||
self.project_id = ''
|
||||
self.request_id = 'abcdefg'
|
||||
self.request_id = 'req-' + uuidutils.generate_uuid()
|
||||
|
||||
|
||||
def fake_get_trunk_plugin(trunk):
|
||||
|
@ -259,6 +259,7 @@ class FakePlugin(plugin.TricirclePlugin):
|
|||
self.core_plugin = FakeCorePlugin()
|
||||
self.neutron_handle = FakeNeutronHandle()
|
||||
self.on_trunk_create = {}
|
||||
self.on_subnet_delete = {}
|
||||
|
||||
|
||||
class PluginTest(unittest.TestCase):
|
||||
|
|
Loading…
Reference in New Issue