]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Revert "Revert "Pecan WSGI: prevent plugins from opening AMQP connections""
authorKevin Benton <blak111@gmail.com>
Wed, 16 Sep 2015 10:33:05 +0000 (03:33 -0700)
committerKevin Benton <blak111@gmail.com>
Wed, 16 Sep 2015 10:33:47 +0000 (03:33 -0700)
This reverts commit 4f1fb05959b211c0edc52021af8774a163aa518c.
Merge of master went in so this can be re-applied and have the
conflict resovled.

Conflicts:
neutron/server/__init__.py

Change-Id: I917e89b2191b3d4646e66a7a313783a56cf0ace5

neutron/cmd/eventlet/server/__init__.py
neutron/common/rpc.py
neutron/server/__init__.py
neutron/server/wsgi_eventlet.py [new file with mode: 0644]
neutron/server/wsgi_pecan.py [new file with mode: 0755]
setup.cfg

index bfa2568628da7dea9bd906aa940367da9996e059..01c3b52c1ec98131c6ef4dbb9a2c8f486cc01093 100644 (file)
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from neutron import server
+from neutron.server import wsgi_eventlet
+from neutron.server import wsgi_pecan
 
 
-def main():
-    server.main()
+def main_wsgi_eventlet():
+    # This also starts the RPC server
+    wsgi_eventlet.main()
+
+
+def main_wsgi_pecan():
+    wsgi_pecan.main()
index 6fe39842b7eacb408b380a4ad7661f7777bec1e6..3037f5342f000f8ae1b31e6e4ec12ae318008e14 100644 (file)
@@ -47,6 +47,12 @@ TRANSPORT_ALIASES = {
     'neutron.rpc.impl_zmq': 'zmq',
 }
 
+# NOTE(salv-orlando): I am afraid this is a global variable. While not ideal,
+# they're however widely used throughout the code base. It should be set to
+# true if the RPC server is not running in the current process space. This
+# will prevent get_connection from creating connections to the AMQP server
+RPC_DISABLED = False
+
 
 def init(conf):
     global TRANSPORT, NOTIFIER
@@ -201,6 +207,25 @@ class Connection(object):
             server.wait()
 
 
+class VoidConnection(object):
+
+    def create_consumer(self, topic, endpoints, fanout=False):
+        pass
+
+    def consume_in_threads(self):
+        pass
+
+    def close(self):
+        pass
+
+
 # functions
 def create_connection(new=True):
+    # NOTE(salv-orlando): This is a clever interpreation of the factory design
+    # patter aimed at preventing plugins from initializing RPC servers upon
+    # initialization when they are running in the REST over HTTP API server.
+    # The educated reader will perfectly be able that this a fairly dirty hack
+    # to avoid having to change the initialization process of every plugin.
+    if RPC_DISABLED:
+        return VoidConnection()
     return Connection()
index 688b7542142c9bea80a67dd816c8e906c6d33ca4..3386fcfa6fe8070e93c7237eb9c12748be069c01 100644 (file)
 
 import sys
 
-import eventlet
 from oslo_config import cfg
-from oslo_log import log as logging
 
 from neutron.common import config
-from neutron.i18n import _LI
-from neutron import service
 
-LOG = logging.getLogger(__name__)
 
-
-def main():
+def boot_server(server_func):
     # the configuration will be read into the cfg.CONF global data structure
     config.init(sys.argv[1:])
+    config.setup_logging()
     if not cfg.CONF.config_file:
         sys.exit(_("ERROR: Unable to find configuration file via the default"
                    " search paths (~/.neutron/, ~/, /etc/neutron/, /etc/) and"
                    " the '--config-file' option!"))
     try:
-        pool = eventlet.GreenPool()
-
-        neutron_api = service.serve_wsgi(service.NeutronApiService)
-        api_thread = pool.spawn(neutron_api.wait)
-
-        try:
-            neutron_rpc = service.serve_rpc()
-        except NotImplementedError:
-            LOG.info(_LI("RPC was already started in parent process by "
-                         "plugin."))
-        else:
-            rpc_thread = pool.spawn(neutron_rpc.wait)
-
-            plugin_workers = service.start_plugin_workers()
-            for worker in plugin_workers:
-                pool.spawn(worker.wait)
-
-            # api and rpc should die together.  When one dies, kill the other.
-            rpc_thread.link(lambda gt: api_thread.kill())
-            api_thread.link(lambda gt: rpc_thread.kill())
-
-        pool.waitall()
+        server_func()
     except KeyboardInterrupt:
         pass
     except RuntimeError as e:
diff --git a/neutron/server/wsgi_eventlet.py b/neutron/server/wsgi_eventlet.py
new file mode 100644 (file)
index 0000000..02c9e19
--- /dev/null
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+#    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 eventlet
+
+from oslo_log import log
+
+from neutron.i18n import _LI
+from neutron import server
+from neutron import service
+
+LOG = log.getLogger(__name__)
+
+
+def _eventlet_wsgi_server():
+    pool = eventlet.GreenPool()
+
+    neutron_api = service.serve_wsgi(service.NeutronApiService)
+    api_thread = pool.spawn(neutron_api.wait)
+
+    try:
+        neutron_rpc = service.serve_rpc()
+    except NotImplementedError:
+        LOG.info(_LI("RPC was already started in parent process by "
+                     "plugin."))
+    else:
+        rpc_thread = pool.spawn(neutron_rpc.wait)
+
+        plugin_workers = service.start_plugin_workers()
+        for worker in plugin_workers:
+            pool.spawn(worker.wait)
+
+        # api and rpc should die together.  When one dies, kill the other.
+        rpc_thread.link(lambda gt: api_thread.kill())
+        api_thread.link(lambda gt: rpc_thread.kill())
+
+    pool.waitall()
+
+
+def main():
+    server.boot_server(_eventlet_wsgi_server)
diff --git a/neutron/server/wsgi_pecan.py b/neutron/server/wsgi_pecan.py
new file mode 100755 (executable)
index 0000000..91677cc
--- /dev/null
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+#    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 logging as std_logging
+from wsgiref import simple_server
+
+from oslo_config import cfg
+from oslo_log import log
+from six.moves import socketserver
+
+from neutron.common import rpc as n_rpc
+from neutron.i18n import _LI, _LW
+from neutron.pecan_wsgi import app as pecan_app
+from neutron import server
+
+LOG = log.getLogger(__name__)
+
+
+class ThreadedSimpleServer(socketserver.ThreadingMixIn,
+                           simple_server.WSGIServer):
+    pass
+
+
+def _pecan_wsgi_server():
+    LOG.info(_LI("Pecan WSGI server starting..."))
+    # No AMQP connection should be created within this process
+    n_rpc.RPC_DISABLED = True
+    application = pecan_app.setup_app()
+
+    host = cfg.CONF.bind_host
+    port = cfg.CONF.bind_port
+
+    wsgi = simple_server.make_server(
+        host,
+        port,
+        application,
+        server_class=ThreadedSimpleServer
+    )
+    # Log option values
+    cfg.CONF.log_opt_values(LOG, std_logging.DEBUG)
+    LOG.warning(
+        _LW("Development Server Serving on http://%(host)s:%(port)s"),
+        {'host': host, 'port': port}
+    )
+
+    wsgi.serve_forever()
+
+
+def main():
+    server.boot_server(_pecan_wsgi_server)
index 6ab349eb1e7ca36aad7b7bfc25f53788f28470e1..87480ad112399bdf81109b5222af4de47e768ebf 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -93,7 +93,8 @@ console_scripts =
     neutron-ovs-cleanup = neutron.cmd.ovs_cleanup:main
     neutron-pd-notify = neutron.cmd.pd_notify:main
     neutron-restproxy-agent = neutron.plugins.bigswitch.agent.restproxy_agent:main
-    neutron-server = neutron.cmd.eventlet.server:main
+    neutron-server = neutron.cmd.eventlet.server:main_wsgi_eventlet
+    neutron-dev-server = neutron.cmd.eventlet.server:main_wsgi_pecan
     neutron-rootwrap = oslo_rootwrap.cmd:main
     neutron-rootwrap-daemon = oslo_rootwrap.cmd:daemon
     neutron-usage-audit = neutron.cmd.usage_audit:main