Fix delete_subnet patching regression

The change:
I04fb4b323029772bf417a8548ae43e2c93647b65

introduced conditional patching of the delete_subnet
method of the ML2 plugin. On account of this conditional
logic, the delete_subnet method is not patched with RH OSP9,
and consequently the transaction guard decorated version
of the delete_subnet method gets used and prevents
calling the method from within a GBP method's transaction.

This patch enhances the conditional logic by removing
the transaction guard when the delete_subnet method is not
patched.

Change-Id: Ib44f432623a06220ffee8e6bf47568c56f952be9
This commit is contained in:
Sumit Naiksatam 2017-07-24 21:49:51 -07:00 committed by Thomas Bachman
parent 3f154614e5
commit 4d8f512092
1 changed files with 58 additions and 0 deletions

View File

@ -275,8 +275,66 @@ def delete_subnet(self, context, id):
LOG.error(_LE("mechanism_manager.delete_subnet_postcommit failed"))
from inspect import isclass
from inspect import isfunction
from inspect import ismethod
# The undecorated() and looks_like_a_decorator() functions have been
# borrowed from the undecorated python library since RPM or Debian
# packages are not readily available.
def looks_like_a_decorator(a):
return (
isfunction(a) or ismethod(a) or isclass(a)
)
def undecorated(o):
"""Remove all decorators from a function, method or class"""
# class decorator
if type(o) is type:
return o
try:
# python2
closure = o.func_closure
except AttributeError:
pass
try:
# python3
closure = o.__closure__
except AttributeError:
return
if closure:
for cell in closure:
# avoid infinite recursion
if cell.cell_contents is o:
continue
# check if the contents looks like a decorator; in that case
# we need to go one level down into the dream, otherwise it
# might just be a different closed-over variable, which we
# can ignore.
# Note: this favors supporting decorators defined without
# @wraps to the detriment of function/method/class closures
if looks_like_a_decorator(cell.cell_contents):
undecd = undecorated(cell.cell_contents)
if undecd:
return undecd
else:
return o
else:
return o
# Red Hat OSP9 uses basically the stable/newton version of
# neutron.plugins.ml2.plugin.ML2Plugin.delete_subnet, which does
# not have a retry loop, and therefore does not need monkey-patching
if hasattr(plugin.Ml2Plugin, '_subnet_check_ip_allocations'):
plugin.Ml2Plugin.delete_subnet = delete_subnet
else:
f = plugin.Ml2Plugin.delete_subnet
plugin.Ml2Plugin.delete_subnet = undecorated(f)