# 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()
'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
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()
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:
--- /dev/null
+#!/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)
--- /dev/null
+#!/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)
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