add the --paste option and deprecate gunicorn_paster

Instead of having multiple command line just use the gunicorn one.
gunicorn_django is deprecated as well.
This commit is contained in:
benoitc 2013-08-27 23:16:35 +02:00
parent f886d86b46
commit b6af364c79
3 changed files with 116 additions and 34 deletions

View File

@ -20,36 +20,49 @@ from gunicorn.config import Config, get_default_config_file
from gunicorn import util from gunicorn import util
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)
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', '')
if host and port:
cfg['bind'] = '%s:%s' % (host, port)
elif host:
cfg['bind'] = host.split(',')
cfg['workers'] = int(lc.get('workers', 1))
cfg['umask'] = int(lc.get('umask', 0))
cfg['default_proc_name'] = gc.get('__file__')
for k, v in gc.items():
if k not in gconfig.settings:
continue
cfg[k] = v
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): class PasterBaseApplication(Application):
gcfg = None gcfg = None
def app_config(self): def app_config(self):
cx = loadwsgi.loadcontext(SERVER, self.cfgurl, return paste_config(self.cfg, self.cfgurl, self.relpath,
relative_to=self.relpath, global_conf=self.gcfg) global_conf=self.gcfg)
gc, lc = cx.global_conf.copy(), cx.local_conf.copy()
cfg = {}
host, port = lc.pop('host', ''), lc.pop('port', '')
if host and port:
cfg['bind'] = '%s:%s' % (host, port)
elif host:
cfg['bind'] = host.split(',')
cfg['workers'] = int(lc.get('workers', 1))
cfg['umask'] = int(lc.get('umask', 0))
cfg['default_proc_name'] = gc.get('__file__')
for k, v in gc.items():
if k not in self.cfg.settings:
continue
cfg[k] = v
for k, v in lc.items():
if k not in self.cfg.settings:
continue
cfg[k] = v
return cfg
def load_config(self): def load_config(self):
super(PasterBaseApplication, self).load_config() super(PasterBaseApplication, self).load_config()
@ -91,7 +104,7 @@ class PasterApplication(PasterBaseApplication):
# default is the current dir # default is the current dir
os.chdir(self.cfg.chdir) os.chdir(self.cfg.chdir)
return loadapp(self.cfgurl, relative_to=self.relpath, global_conf=self.gcfg) return load_pasteapp(self.cfgurl, self.relpath, global_conf=self.gcfg)
class PasterServerApplication(PasterBaseApplication): class PasterServerApplication(PasterBaseApplication):
@ -151,6 +164,13 @@ def run():
The ``gunicorn_paster`` command for launcing Paster compatible The ``gunicorn_paster`` command for launcing Paster compatible
apllications like Pylons or Turbogears2 apllications 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 from gunicorn.app.pasterapp import PasterApplication
PasterApplication("%(prog)s [OPTIONS] pasteconfig.ini").run() PasterApplication("%(prog)s [OPTIONS] pasteconfig.ini").run()

View File

@ -6,21 +6,35 @@
import os import os
import sys import sys
from gunicorn import util from gunicorn.errors import ConfigError
from gunicorn.app.base import Application from gunicorn.app.base import Application
from gunicorn.app import djangoapp from gunicorn.app import djangoapp
from gunicorn import util
class WSGIApplication(Application): class WSGIApplication(Application):
def init(self, parser, opts, args): def init(self, parser, opts, args):
if opts.paste and opts.paste is not None:
path = os.path.abspath(os.path.normpath(
os.path.join(util.getcwd(), opts.paste)))
if not os.path.exists(path):
raise ConfigError("%r not found" % val)
# paste application, load the config
self.cfgurl = 'config:%s' % path
self.relpath = os.path.dirname(path)
from .pasterapp import paste_config
return paste_config(self.cfg, self.cfgurl, self.relpath)
if len(args) != 1: if len(args) != 1:
parser.error("No application module specified.") parser.error("No application module specified.")
self.cfg.set("default_proc_name", args[0]) self.cfg.set("default_proc_name", args[0])
self.app_uri = args[0] self.app_uri = args[0]
def load(self): def chdir(self):
# chdir to the configured path before loading, # chdir to the configured path before loading,
# default is the current dir # default is the current dir
os.chdir(self.cfg.chdir) os.chdir(self.cfg.chdir)
@ -28,17 +42,33 @@ class WSGIApplication(Application):
# add the path to sys.path # add the path to sys.path
sys.path.insert(0, self.cfg.chdir) sys.path.insert(0, self.cfg.chdir)
def load_wsgiapp(self):
self.chdir()
# load the app # load the app
return util.import_app(self.app_uri) return util.import_app(self.app_uri)
def load_pasteapp(self):
self.chdir()
# load the paste app
from .pasterapp import load_pasteapp
return load_pasteapp(self.cfgurl, self.relpath, global_conf=None)
def load(self):
if self.cfg.paste is not None:
return self.load_pasteapp()
else:
return self.load_wsgiapp
def run(): def run():
"""\ """\
The ``gunicorn`` command line runner for launching Gunicorn with The ``gunicorn`` command line runner for launching Ghunicorn with
generic WSGI applications. generic WSGI applications.
""" """
from gunicorn.app.wsgiapp import WSGIApplication from gunicorn.app.wsgiapp import WSGIApplication
WSGIApplication("%(prog)s [OPTIONS] APP_MODULE").run() WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -401,6 +401,24 @@ def validate_chdir(val):
return path return path
def validate_file(val):
if val is None:
return None
# valid if the value is a string
val = validate_string(val)
# transform relative paths
path = os.path.abspath(os.path.normpath(os.path.join(util.getcwd(), val)))
# test if the path exists
if not os.path.exists(path):
raise ConfigError("%r not found" % val)
return path
def get_default_config_file(): def get_default_config_file():
config_path = os.path.join(os.path.abspath(os.getcwd()), config_path = os.path.join(os.path.abspath(os.getcwd()),
'gunicorn.conf.py') 'gunicorn.conf.py')
@ -1128,10 +1146,12 @@ class DjangoSettings(Setting):
validator = validate_string validator = validate_string
default = None default = None
desc = """\ desc = """\
The Python path to a Django settings module. The Python path to a Django settings module. (deprecated)
e.g. 'myproject.settings.main'. If this isn't provided, the e.g. 'myproject.settings.main'. If this isn't provided, the
DJANGO_SETTINGS_MODULE environment variable will be used. DJANGO_SETTINGS_MODULE environment variable will be used.
**DEPRECATED**: use the --env argument instead.
""" """
@ -1143,13 +1163,25 @@ class PythonPath(Setting):
validator = validate_string validator = validate_string
default = None default = None
desc = """\ desc = """\
A directory to add to the Python path for Django. A directory to add to the Python path.
e.g. e.g.
'/home/djangoprojects/myproject'. '/home/djangoprojects/myproject'.
""" """
class Paste(Setting):
name = "paste"
section = "Server Mechanics"
cli = ["--paster"]
meta = "STRING"
validator = validate_string
default = None
desc = """\
Load a paste.deploy config file.
"""
class OnStarting(Setting): class OnStarting(Setting):
name = "on_starting" name = "on_starting"
section = "Server Hooks" section = "Server Hooks"