diff --git a/gunicorn/app/pasterapp.py b/gunicorn/app/pasterapp.py index 0f9de435..4c9fc7de 100644 --- a/gunicorn/app/pasterapp.py +++ b/gunicorn/app/pasterapp.py @@ -3,206 +3,73 @@ # This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. -# pylint: skip-file - +import configparser import os -import pkg_resources -import sys -try: - import configparser as ConfigParser -except ImportError: - import ConfigParser +from paste.deploy import loadapp -from paste.deploy import loadapp, loadwsgi -SERVER = loadwsgi.SERVER - -from gunicorn.app.base import Application -from gunicorn.config import Config, get_default_config_file -from gunicorn import util +from gunicorn.app.wsgiapp import WSGIApplication +from gunicorn.config import get_default_config_file -def _has_logging_config(paste_file): - cfg_parser = ConfigParser.ConfigParser() - cfg_parser.read([paste_file]) - return cfg_parser.has_section('loggers') +def get_wsgi_app(config_uri, name=None, defaults=None): + if ':' not in config_uri: + config_uri = "config:%s" % config_uri + + return loadapp( + config_uri, + name=name, + relative_to=os.getcwd(), + global_conf=defaults, + ) -def paste_config(gconfig, config_url, relative_to, global_conf=None): - # add entry to pkg_resources - sys.path.insert(0, relative_to) - pkg_resources.working_set.add_entry(relative_to) +def has_logging_config(config_file): + parser = configparser.ConfigParser() + parser.read([config_file]) + return parser.has_section('loggers') - config_url = config_url.split('#')[0] - cx = loadwsgi.loadcontext(SERVER, config_url, relative_to=relative_to, - global_conf=global_conf) - gc, lc = cx.global_conf.copy(), cx.local_conf.copy() - cfg = {} - host, port = lc.pop('host', ''), lc.pop('port', '') +def serve(app, global_conf, **local_conf): + """\ + A Paste Deployment server runner. + + Example configuration: + + [server:main] + use = egg:gunicorn#main + host = 127.0.0.1 + port = 5000 + """ + config_file = global_conf['__file__'] + gunicorn_config_file = local_conf.pop('config', None) + + host = local_conf.pop('host', '') + port = local_conf.pop('port', '') if host and port: - cfg['bind'] = '%s:%s' % (host, port) + local_conf['bind'] = '%s:%s' % (host, port) elif host: - cfg['bind'] = host.split(',') + local_conf['bind'] = host.split(',') - cfg['default_proc_name'] = gc.get('__file__') + class PasterServerApplication(WSGIApplication): + def load_config(self): + self.cfg.set("default_proc_name", config_file) - # init logging configuration - config_file = config_url.split(':')[1] - if _has_logging_config(config_file): - cfg.setdefault('logconfig', config_file) + if has_logging_config(config_file): + self.cfg.set("logconfig", config_file) - for k, v in gc.items(): - if k not in gconfig.settings: - continue - cfg[k] = v + if gunicorn_config_file: + self.load_config_from_file(gunicorn_config_file) + else: + default_gunicorn_config_file = get_default_config_file() + if default_gunicorn_config_file is not None: + self.load_config_from_file(default_gunicorn_config_file) - for k, v in lc.items(): - if k not in gconfig.settings: - continue - cfg[k] = v - - return cfg - - -def load_pasteapp(config_url, relative_to, global_conf=None): - return loadapp(config_url, relative_to=relative_to, - global_conf=global_conf) - -class PasterBaseApplication(Application): - gcfg = None - - def app_config(self): - return paste_config(self.cfg, self.cfgurl, self.relpath, - global_conf=self.gcfg) - - def load_config(self): - super(PasterBaseApplication, self).load_config() - - # reload logging conf - if hasattr(self, "cfgfname"): - parser = ConfigParser.ConfigParser() - parser.read([self.cfgfname]) - if parser.has_section('loggers'): - from logging.config import fileConfig - config_file = os.path.abspath(self.cfgfname) - fileConfig(config_file, dict(__file__=config_file, - here=os.path.dirname(config_file))) - - -class PasterApplication(PasterBaseApplication): - - def init(self, parser, opts, args): - if len(args) != 1: - parser.error("No application name specified.") - - cwd = util.getcwd() - cfgfname = os.path.normpath(os.path.join(cwd, args[0])) - cfgfname = os.path.abspath(cfgfname) - if not os.path.exists(cfgfname): - parser.error("Config file not found: %s" % cfgfname) - - self.cfgurl = 'config:%s' % cfgfname - self.relpath = os.path.dirname(cfgfname) - self.cfgfname = cfgfname - - sys.path.insert(0, self.relpath) - pkg_resources.working_set.add_entry(self.relpath) - - return self.app_config() - - def load(self): - # chdir to the configured path before loading, - # default is the current dir - os.chdir(self.cfg.chdir) - - return load_pasteapp(self.cfgurl, self.relpath, global_conf=self.gcfg) - - -class PasterServerApplication(PasterBaseApplication): - - def __init__(self, app, gcfg=None, host="127.0.0.1", port=None, **kwargs): - # pylint: disable=super-init-not-called - self.cfg = Config() - self.gcfg = gcfg # need to hold this for app_config - self.app = app - self.callable = None - - gcfg = gcfg or {} - cfgfname = gcfg.get("__file__") - if cfgfname is not None: - self.cfgurl = 'config:%s' % cfgfname - self.relpath = os.path.dirname(cfgfname) - self.cfgfname = cfgfname - - cfg = kwargs.copy() - - if port and not host.startswith("unix:"): - bind = "%s:%s" % (host, port) - else: - bind = host - cfg["bind"] = bind.split(',') - - if gcfg: - for k, v in gcfg.items(): - cfg[k] = v - cfg["default_proc_name"] = cfg['__file__'] - - try: - for k, v in cfg.items(): - if k.lower() in self.cfg.settings and v is not None: + for k, v in local_conf.items(): + if v is not None: self.cfg.set(k.lower(), v) - except Exception as e: - print("\nConfig error: %s" % str(e), file=sys.stderr) - sys.stderr.flush() - sys.exit(1) - if cfg.get("config"): - self.load_config_from_file(cfg["config"]) - else: - default_config = get_default_config_file() - if default_config is not None: - self.load_config_from_file(default_config) + def load(self): + return app - def load(self): - return self.app - - -def run(): - """\ - The ``gunicorn_paster`` command for launching Paster compatible - applications like Pylons or Turbogears2 - """ - util.warn("""This command is deprecated. - - You should now use the `--paste` option. Ex.: - - gunicorn --paste development.ini - """) - - from gunicorn.app.pasterapp import PasterApplication - PasterApplication("%(prog)s [OPTIONS] pasteconfig.ini").run() - - -def paste_server(app, gcfg=None, host="127.0.0.1", port=None, **kwargs): - """\ - A paster server. - - Then entry point in your paster ini file should looks like this: - - [server:main] - use = egg:gunicorn#main - host = 127.0.0.1 - port = 5000 - - """ - - util.warn("""This command is deprecated. - - You should now use the `--paste` option. Ex.: - - gunicorn --paste development.ini - """) - - from gunicorn.app.pasterapp import PasterServerApplication - PasterServerApplication(app, gcfg=gcfg, host=host, port=port, **kwargs).run() + PasterServerApplication().run() diff --git a/gunicorn/app/wsgiapp.py b/gunicorn/app/wsgiapp.py index 916a2b1d..c8501e5f 100644 --- a/gunicorn/app/wsgiapp.py +++ b/gunicorn/app/wsgiapp.py @@ -13,22 +13,21 @@ from gunicorn import util class WSGIApplication(Application): def init(self, parser, opts, args): if opts.paste: - app_name = 'main' - path = opts.paste - if '#' in path: - path, app_name = path.split('#') - path = os.path.abspath(os.path.normpath( - os.path.join(util.getcwd(), path))) + from .pasterapp import has_logging_config - if not os.path.exists(path): - raise ConfigError("%r not found" % path) + config_uri = os.path.abspath(opts.paste) + config_file = config_uri.split('#')[0] - # paste application, load the config - self.cfgurl = 'config:%s#%s' % (path, app_name) - self.relpath = os.path.dirname(path) + if not os.path.exists(config_file): + raise ConfigError("%r not found" % config_file) - from .pasterapp import paste_config - return paste_config(self.cfg, self.cfgurl, self.relpath) + self.cfg.set("default_proc_name", config_file) + self.app_uri = config_uri + + if has_logging_config(config_file): + self.cfg.set("logconfig", config_file) + + return if not args: parser.error("No application module specified.") @@ -37,13 +36,11 @@ class WSGIApplication(Application): self.app_uri = args[0] def load_wsgiapp(self): - # load the app return util.import_app(self.app_uri) def load_pasteapp(self): - # load the paste app - from .pasterapp import load_pasteapp - return load_pasteapp(self.cfgurl, self.relpath, global_conf=self.cfg.paste_global_conf) + from .pasterapp import get_wsgi_app + return get_wsgi_app(self.app_uri, defaults=self.cfg.paste_global_conf) def load(self): if self.cfg.paste is not None: diff --git a/setup.py b/setup.py index 19e85c94..fd24c0df 100644 --- a/setup.py +++ b/setup.py @@ -104,10 +104,9 @@ setup( entry_points=""" [console_scripts] gunicorn=gunicorn.app.wsgiapp:run - gunicorn_paster=gunicorn.app.pasterapp:run [paste.server_runner] - main=gunicorn.app.pasterapp:paste_server + main=gunicorn.app.pasterapp:serve """, extras_require=extra_require, )