|
|
|
@ -14,7 +14,6 @@
|
|
|
|
|
# limitations under the License. |
|
|
|
|
|
|
|
|
|
import json |
|
|
|
|
from multiprocessing import Queue |
|
|
|
|
|
|
|
|
|
from neutron_lib.api.definitions import portbindings |
|
|
|
|
from neutron_lib import constants as n_const |
|
|
|
@ -32,6 +31,45 @@ from networking_arista.ml2 import arista_sync
|
|
|
|
|
from networking_arista.ml2 import arista_trunk |
|
|
|
|
from networking_arista.ml2.rpc.arista_eapi import AristaRPCWrapperEapi |
|
|
|
|
|
|
|
|
|
# When used as a Neutron plugin, neutron-lib imports this code. However earlier |
|
|
|
|
# neutron-lib has already imported 'multiprocessing'. This means the python |
|
|
|
|
# module cache (sys.modules) contains a version of 'multiprocessing' where |
|
|
|
|
# select.poll() exists. |
|
|
|
|
# |
|
|
|
|
# Further down we import arista_sync, which spawns a greenthread. This |
|
|
|
|
# greenthread then uses a green version of 'multiprocessing' where |
|
|
|
|
# select.poll() has been removed. |
|
|
|
|
# |
|
|
|
|
# Doing here multiprocessing.Queue.put() and in the greenthread |
|
|
|
|
# multiprocessing.Queue.get(timeout=...) leads to: |
|
|
|
|
# AttributeError: module 'select' has no attribute 'poll' |
|
|
|
|
# |
|
|
|
|
# We can't do eventlet.monkey_patch() early enough (before the first |
|
|
|
|
# 'mutiprocessing' import) as we would have to do it in neutron-lib and it's |
|
|
|
|
# forbidden, see https://review.opendev.org/#/c/333017/ |
|
|
|
|
# |
|
|
|
|
# The solution is to let the python module cache here forget the already |
|
|
|
|
# imported 'multiprocessing' and re-import a green one. Here again |
|
|
|
|
# eventlet.monkey_patch() doesn't seem to help as it doesn't seem to touch |
|
|
|
|
# 'multiprocessing'. Thus we use eventlet.import_patched() instead: |
|
|
|
|
import eventlet |
|
|
|
|
import sys |
|
|
|
|
modules_to_forget = [] |
|
|
|
|
for imported_module_name in sys.modules: |
|
|
|
|
if imported_module_name.startswith('multiprocessing'): |
|
|
|
|
modules_to_forget.append(imported_module_name) |
|
|
|
|
for module_to_forget in modules_to_forget: |
|
|
|
|
del sys.modules[module_to_forget] |
|
|
|
|
|
|
|
|
|
for module_to_forget in modules_to_forget: |
|
|
|
|
try: |
|
|
|
|
eventlet.import_patched(module_to_forget) |
|
|
|
|
except ImportError: |
|
|
|
|
pass |
|
|
|
|
|
|
|
|
|
# import a green 'multiprocessing': |
|
|
|
|
multiprocessing = eventlet.import_patched('multiprocessing') |
|
|
|
|
from networking_arista.ml2 import arista_sync # noqa: E402 |
|
|
|
|
|
|
|
|
|
LOG = logging.getLogger(__name__) |
|
|
|
|
cfg.CONF.import_group('ml2_arista', 'networking_arista.common.config') |
|
|
|
@ -70,7 +108,7 @@ class AristaDriver(driver_api.MechanismDriver):
|
|
|
|
|
self.eapi = AristaRPCWrapperEapi() |
|
|
|
|
self.mlag_pairs = dict() |
|
|
|
|
|
|
|
|
|
self.provision_queue = Queue() |
|
|
|
|
self.provision_queue = multiprocessing.Queue() |
|
|
|
|
self.trunk_driver = None |
|
|
|
|
self.vif_details = {portbindings.VIF_DETAILS_CONNECTIVITY: |
|
|
|
|
portbindings.CONNECTIVITY_L2} |
|
|
|
|