Revert "Revert "Pecan WSGI: prevent plugins from opening AMQP connections""
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
This commit is contained in:
parent
fdc3431ccd
commit
40151be9b3
@ -10,8 +10,14 @@
|
||||
# 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()
|
||||
|
@ -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()
|
||||
|
@ -18,47 +18,21 @@
|
||||
|
||||
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:
|
||||
|
51
neutron/server/wsgi_eventlet.py
Normal file
51
neutron/server/wsgi_eventlet.py
Normal file
@ -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)
|
60
neutron/server/wsgi_pecan.py
Executable file
60
neutron/server/wsgi_pecan.py
Executable file
@ -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)
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user