mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
Delete deprecated gunicorn_django command and --settings option
This commit is contained in:
parent
cb512715fe
commit
3da2f88dfe
@ -2,6 +2,17 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
19.7.0 / Not yet released
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Core
|
||||||
|
++++
|
||||||
|
|
||||||
|
- The previously deprecated ``gunicorn_django`` command has been deprecated.
|
||||||
|
Use the :ref:`gunicorn-cmd` command-line interface instead.
|
||||||
|
- The previously deprecated ``django_settings`` setting has been removed.
|
||||||
|
Use the :ref:`raw-env` setting instead.
|
||||||
|
|
||||||
19.6.0 / 2016/05/21
|
19.6.0 / 2016/05/21
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,8 @@ Commands
|
|||||||
After installing Gunicorn you will have access to the command line script
|
After installing Gunicorn you will have access to the command line script
|
||||||
``gunicorn``.
|
``gunicorn``.
|
||||||
|
|
||||||
|
.. _gunicorn-cmd:
|
||||||
|
|
||||||
gunicorn
|
gunicorn
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
|||||||
@ -805,24 +805,6 @@ default_proc_name
|
|||||||
|
|
||||||
Internal setting that is adjusted for each type of application.
|
Internal setting that is adjusted for each type of application.
|
||||||
|
|
||||||
Django
|
|
||||||
------
|
|
||||||
|
|
||||||
.. _django-settings:
|
|
||||||
|
|
||||||
django_settings
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
* ``--settings STRING``
|
|
||||||
* ``None``
|
|
||||||
|
|
||||||
The Python path to a Django settings module. (deprecated)
|
|
||||||
|
|
||||||
e.g. ``myproject.settings.main``. If this isn't provided, the
|
|
||||||
``DJANGO_SETTINGS_MODULE`` environment variable will be used.
|
|
||||||
|
|
||||||
**DEPRECATED**: use the ``--env`` argument instead.
|
|
||||||
|
|
||||||
Server Mechanics
|
Server Mechanics
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|||||||
@ -1,120 +0,0 @@
|
|||||||
# -*- coding: utf-8 -
|
|
||||||
#
|
|
||||||
# This file is part of gunicorn released under the MIT license.
|
|
||||||
# See the NOTICE for more information.
|
|
||||||
|
|
||||||
""" module used to build the django wsgi application """
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
try:
|
|
||||||
from StringIO import StringIO
|
|
||||||
except:
|
|
||||||
from io import StringIO
|
|
||||||
from imp import reload
|
|
||||||
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.core.management.validation import get_validation_errors
|
|
||||||
from django.utils import translation
|
|
||||||
|
|
||||||
try:
|
|
||||||
from django.core.servers.basehttp import get_internal_wsgi_application
|
|
||||||
django14 = True
|
|
||||||
except ImportError:
|
|
||||||
from django.core.handlers.wsgi import WSGIHandler
|
|
||||||
django14 = False
|
|
||||||
|
|
||||||
from gunicorn import util
|
|
||||||
|
|
||||||
|
|
||||||
def make_wsgi_application():
|
|
||||||
# validate models
|
|
||||||
s = StringIO()
|
|
||||||
if get_validation_errors(s):
|
|
||||||
s.seek(0)
|
|
||||||
error = s.read()
|
|
||||||
msg = "One or more models did not validate:\n%s" % error
|
|
||||||
print(msg, file=sys.stderr)
|
|
||||||
sys.stderr.flush()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
translation.activate(settings.LANGUAGE_CODE)
|
|
||||||
if django14:
|
|
||||||
return get_internal_wsgi_application()
|
|
||||||
return WSGIHandler()
|
|
||||||
|
|
||||||
|
|
||||||
def reload_django_settings():
|
|
||||||
mod = util.import_module(os.environ['DJANGO_SETTINGS_MODULE'])
|
|
||||||
|
|
||||||
# Reload module.
|
|
||||||
reload(mod)
|
|
||||||
|
|
||||||
# Reload settings.
|
|
||||||
# Use code from django.settings.Settings module.
|
|
||||||
|
|
||||||
# Settings that should be converted into tuples if they're mistakenly entered
|
|
||||||
# as strings.
|
|
||||||
tuple_settings = ("INSTALLED_APPS", "TEMPLATE_DIRS")
|
|
||||||
|
|
||||||
for setting in dir(mod):
|
|
||||||
if setting == setting.upper():
|
|
||||||
setting_value = getattr(mod, setting)
|
|
||||||
if setting in tuple_settings and type(setting_value) == str:
|
|
||||||
setting_value = (setting_value,) # In case the user forgot the comma.
|
|
||||||
setattr(settings, setting, setting_value)
|
|
||||||
|
|
||||||
# Expand entries in INSTALLED_APPS like "django.contrib.*" to a list
|
|
||||||
# of all those apps.
|
|
||||||
new_installed_apps = []
|
|
||||||
for app in settings.INSTALLED_APPS:
|
|
||||||
if app.endswith('.*'):
|
|
||||||
app_mod = util.import_module(app[:-2])
|
|
||||||
appdir = os.path.dirname(app_mod.__file__)
|
|
||||||
app_subdirs = os.listdir(appdir)
|
|
||||||
name_pattern = re.compile(r'[a-zA-Z]\w*')
|
|
||||||
for d in sorted(app_subdirs):
|
|
||||||
if (name_pattern.match(d) and
|
|
||||||
os.path.isdir(os.path.join(appdir, d))):
|
|
||||||
new_installed_apps.append('%s.%s' % (app[:-2], d))
|
|
||||||
else:
|
|
||||||
new_installed_apps.append(app)
|
|
||||||
setattr(settings, "INSTALLED_APPS", new_installed_apps)
|
|
||||||
|
|
||||||
if hasattr(time, 'tzset') and settings.TIME_ZONE:
|
|
||||||
# When we can, attempt to validate the timezone. If we can't find
|
|
||||||
# this file, no check happens and it's harmless.
|
|
||||||
zoneinfo_root = '/usr/share/zoneinfo'
|
|
||||||
if (os.path.exists(zoneinfo_root) and not
|
|
||||||
os.path.exists(os.path.join(zoneinfo_root,
|
|
||||||
*(settings.TIME_ZONE.split('/'))))):
|
|
||||||
raise ValueError("Incorrect timezone setting: %s" %
|
|
||||||
settings.TIME_ZONE)
|
|
||||||
# Move the time zone info into os.environ. See ticket #2315 for why
|
|
||||||
# we don't do this unconditionally (breaks Windows).
|
|
||||||
os.environ['TZ'] = settings.TIME_ZONE
|
|
||||||
time.tzset()
|
|
||||||
|
|
||||||
# Settings are configured, so we can set up the logger if required
|
|
||||||
if getattr(settings, 'LOGGING_CONFIG', False):
|
|
||||||
# First find the logging configuration function ...
|
|
||||||
logging_config_path, logging_config_func_name = settings.LOGGING_CONFIG.rsplit('.', 1)
|
|
||||||
logging_config_module = util.import_module(logging_config_path)
|
|
||||||
logging_config_func = getattr(logging_config_module, logging_config_func_name)
|
|
||||||
|
|
||||||
# ... then invoke it with the logging settings
|
|
||||||
logging_config_func(settings.LOGGING)
|
|
||||||
|
|
||||||
|
|
||||||
def make_command_wsgi_application(admin_mediapath):
|
|
||||||
reload_django_settings()
|
|
||||||
|
|
||||||
try:
|
|
||||||
from django.core.servers.basehttp import AdminMediaHandler
|
|
||||||
return AdminMediaHandler(make_wsgi_application(), admin_mediapath)
|
|
||||||
except ImportError:
|
|
||||||
return make_wsgi_application()
|
|
||||||
@ -1,160 +0,0 @@
|
|||||||
# -*- coding: utf-8 -
|
|
||||||
#
|
|
||||||
# This file is part of gunicorn released under the MIT license.
|
|
||||||
# See the NOTICE for more information.
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from gunicorn.app.base import Application
|
|
||||||
from gunicorn import util
|
|
||||||
|
|
||||||
|
|
||||||
def is_setting_mod(path):
|
|
||||||
return (os.path.isfile(os.path.join(path, "settings.py")) or
|
|
||||||
os.path.isfile(os.path.join(path, "settings.pyc")))
|
|
||||||
|
|
||||||
|
|
||||||
def find_settings_module(path):
|
|
||||||
path = os.path.abspath(path)
|
|
||||||
project_path = None
|
|
||||||
settings_name = "settings"
|
|
||||||
|
|
||||||
if os.path.isdir(path):
|
|
||||||
project_path = None
|
|
||||||
if not is_setting_mod(path):
|
|
||||||
for d in os.listdir(path):
|
|
||||||
if d in ('..', '.'):
|
|
||||||
continue
|
|
||||||
|
|
||||||
root = os.path.join(path, d)
|
|
||||||
if is_setting_mod(root):
|
|
||||||
project_path = root
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
project_path = path
|
|
||||||
elif os.path.isfile(path):
|
|
||||||
project_path = os.path.dirname(path)
|
|
||||||
settings_name, _ = os.path.splitext(os.path.basename(path))
|
|
||||||
|
|
||||||
return project_path, settings_name
|
|
||||||
|
|
||||||
|
|
||||||
def make_default_env(cfg):
|
|
||||||
if cfg.django_settings:
|
|
||||||
os.environ['DJANGO_SETTINGS_MODULE'] = cfg.django_settings
|
|
||||||
|
|
||||||
if cfg.pythonpath and cfg.pythonpath is not None:
|
|
||||||
paths = cfg.pythonpath.split(",")
|
|
||||||
for path in paths:
|
|
||||||
pythonpath = os.path.abspath(cfg.pythonpath)
|
|
||||||
if pythonpath not in sys.path:
|
|
||||||
sys.path.insert(0, pythonpath)
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.environ['DJANGO_SETTINGS_MODULE']
|
|
||||||
except KeyError:
|
|
||||||
# not settings env set, try to build one.
|
|
||||||
cwd = util.getcwd()
|
|
||||||
project_path, settings_name = find_settings_module(cwd)
|
|
||||||
|
|
||||||
if not project_path:
|
|
||||||
raise RuntimeError("django project not found")
|
|
||||||
|
|
||||||
pythonpath, project_name = os.path.split(project_path)
|
|
||||||
os.environ['DJANGO_SETTINGS_MODULE'] = "%s.%s" % (project_name,
|
|
||||||
settings_name)
|
|
||||||
if pythonpath not in sys.path:
|
|
||||||
sys.path.insert(0, pythonpath)
|
|
||||||
|
|
||||||
if project_path not in sys.path:
|
|
||||||
sys.path.insert(0, project_path)
|
|
||||||
|
|
||||||
|
|
||||||
class DjangoApplication(Application):
|
|
||||||
|
|
||||||
def init(self, parser, opts, args):
|
|
||||||
if args:
|
|
||||||
if ("." in args[0] and not (os.path.isfile(args[0])
|
|
||||||
or os.path.isdir(args[0]))):
|
|
||||||
self.cfg.set("django_settings", args[0])
|
|
||||||
else:
|
|
||||||
# not settings env set, try to build one.
|
|
||||||
project_path, settings_name = find_settings_module(
|
|
||||||
os.path.abspath(args[0]))
|
|
||||||
if project_path not in sys.path:
|
|
||||||
sys.path.insert(0, project_path)
|
|
||||||
|
|
||||||
if not project_path:
|
|
||||||
raise RuntimeError("django project not found")
|
|
||||||
|
|
||||||
pythonpath, project_name = os.path.split(project_path)
|
|
||||||
self.cfg.set("django_settings", "%s.%s" % (project_name,
|
|
||||||
settings_name))
|
|
||||||
self.cfg.set("pythonpath", pythonpath)
|
|
||||||
|
|
||||||
def load(self):
|
|
||||||
# chdir to the configured path before loading,
|
|
||||||
# default is the current dir
|
|
||||||
os.chdir(self.cfg.chdir)
|
|
||||||
|
|
||||||
# set settings
|
|
||||||
make_default_env(self.cfg)
|
|
||||||
|
|
||||||
# load wsgi application and return it.
|
|
||||||
mod = util.import_module("gunicorn.app.django_wsgi")
|
|
||||||
return mod.make_wsgi_application()
|
|
||||||
|
|
||||||
|
|
||||||
class DjangoApplicationCommand(Application):
|
|
||||||
|
|
||||||
def __init__(self, options, admin_media_path):
|
|
||||||
self.usage = None
|
|
||||||
self.prog = None
|
|
||||||
self.cfg = None
|
|
||||||
self.config_file = options.get("config") or ""
|
|
||||||
self.options = options
|
|
||||||
self.admin_media_path = admin_media_path
|
|
||||||
self.callable = None
|
|
||||||
self.project_path = None
|
|
||||||
self.do_load_config()
|
|
||||||
|
|
||||||
def init(self, *args):
|
|
||||||
if 'settings' in self.options:
|
|
||||||
self.options['django_settings'] = self.options.pop('settings')
|
|
||||||
|
|
||||||
cfg = {}
|
|
||||||
for k, v in self.options.items():
|
|
||||||
if k.lower() in self.cfg.settings and v is not None:
|
|
||||||
cfg[k.lower()] = v
|
|
||||||
return cfg
|
|
||||||
|
|
||||||
def load(self):
|
|
||||||
# chdir to the configured path before loading,
|
|
||||||
# default is the current dir
|
|
||||||
os.chdir(self.cfg.chdir)
|
|
||||||
|
|
||||||
# set settings
|
|
||||||
make_default_env(self.cfg)
|
|
||||||
|
|
||||||
# load wsgi application and return it.
|
|
||||||
mod = util.import_module("gunicorn.app.django_wsgi")
|
|
||||||
return mod.make_command_wsgi_application(self.admin_media_path)
|
|
||||||
|
|
||||||
|
|
||||||
def run():
|
|
||||||
"""\
|
|
||||||
The ``gunicorn_django`` command line runner for launching Django
|
|
||||||
applications.
|
|
||||||
"""
|
|
||||||
util.warn("""This command is deprecated.
|
|
||||||
|
|
||||||
You should now run your application with the WSGI interface
|
|
||||||
installed with your project. Ex.:
|
|
||||||
|
|
||||||
gunicorn myproject.wsgi:application
|
|
||||||
|
|
||||||
See https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/gunicorn/
|
|
||||||
for more info.""")
|
|
||||||
from gunicorn.app.djangoapp import DjangoApplication
|
|
||||||
DjangoApplication("%(prog)s [OPTIONS] [SETTINGS_PATH]").run()
|
|
||||||
@ -1411,23 +1411,6 @@ class DefaultProcName(Setting):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class DjangoSettings(Setting):
|
|
||||||
name = "django_settings"
|
|
||||||
section = "Django"
|
|
||||||
cli = ["--settings"]
|
|
||||||
meta = "STRING"
|
|
||||||
validator = validate_string
|
|
||||||
default = None
|
|
||||||
desc = """\
|
|
||||||
The Python path to a Django settings module. (deprecated)
|
|
||||||
|
|
||||||
e.g. ``myproject.settings.main``. If this isn't provided, the
|
|
||||||
``DJANGO_SETTINGS_MODULE`` environment variable will be used.
|
|
||||||
|
|
||||||
**DEPRECATED**: use the ``--env`` argument instead.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class PythonPath(Setting):
|
class PythonPath(Setting):
|
||||||
name = "pythonpath"
|
name = "pythonpath"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
|
|||||||
@ -1,113 +0,0 @@
|
|||||||
# -*- coding: utf-8 -
|
|
||||||
#
|
|
||||||
# This file is part of gunicorn released under the MIT license.
|
|
||||||
# See the NOTICE for more information.
|
|
||||||
|
|
||||||
from optparse import make_option
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
|
||||||
|
|
||||||
from gunicorn.app.djangoapp import DjangoApplicationCommand
|
|
||||||
from gunicorn.config import make_settings
|
|
||||||
from gunicorn import util
|
|
||||||
|
|
||||||
|
|
||||||
# monkey patch django.
|
|
||||||
# This patch make sure that we use real threads to get the ident which
|
|
||||||
# is going to happen if we are using gevent or eventlet.
|
|
||||||
try:
|
|
||||||
from django.db.backends import BaseDatabaseWrapper, DatabaseError
|
|
||||||
|
|
||||||
if "validate_thread_sharing" in BaseDatabaseWrapper.__dict__:
|
|
||||||
import thread
|
|
||||||
_get_ident = thread.get_ident
|
|
||||||
|
|
||||||
__old__init__ = BaseDatabaseWrapper.__init__
|
|
||||||
|
|
||||||
def _init(self, *args, **kwargs):
|
|
||||||
__old__init__(self, *args, **kwargs)
|
|
||||||
self._thread_ident = _get_ident()
|
|
||||||
|
|
||||||
def _validate_thread_sharing(self):
|
|
||||||
if (not self.allow_thread_sharing
|
|
||||||
and self._thread_ident != _get_ident()):
|
|
||||||
raise DatabaseError("DatabaseWrapper objects created in a "
|
|
||||||
"thread can only be used in that same thread. The object "
|
|
||||||
"with alias '%s' was created in thread id %s and this is "
|
|
||||||
"thread id %s."
|
|
||||||
% (self.alias, self._thread_ident, _get_ident()))
|
|
||||||
|
|
||||||
BaseDatabaseWrapper.__init__ = _init
|
|
||||||
BaseDatabaseWrapper.validate_thread_sharing = _validate_thread_sharing
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def make_options():
|
|
||||||
opts = [
|
|
||||||
make_option('--adminmedia', dest='admin_media_path', default='',
|
|
||||||
help='Specifies the directory from which to serve admin media.')
|
|
||||||
]
|
|
||||||
|
|
||||||
g_settings = make_settings(ignore=("version"))
|
|
||||||
keys = g_settings.keys()
|
|
||||||
for k in keys:
|
|
||||||
if k in ('pythonpath', 'django_settings',):
|
|
||||||
continue
|
|
||||||
|
|
||||||
setting = g_settings[k]
|
|
||||||
if not setting.cli:
|
|
||||||
continue
|
|
||||||
|
|
||||||
args = tuple(setting.cli)
|
|
||||||
|
|
||||||
kwargs = {
|
|
||||||
"dest": setting.name,
|
|
||||||
"metavar": setting.meta or None,
|
|
||||||
"action": setting.action or "store",
|
|
||||||
"type": setting.type or "string",
|
|
||||||
"default": None,
|
|
||||||
"help": "%s [%s]" % (setting.short, setting.default)
|
|
||||||
}
|
|
||||||
if kwargs["action"] != "store":
|
|
||||||
kwargs.pop("type")
|
|
||||||
|
|
||||||
opts.append(make_option(*args, **kwargs))
|
|
||||||
|
|
||||||
return tuple(opts)
|
|
||||||
|
|
||||||
GUNICORN_OPTIONS = make_options()
|
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
|
||||||
option_list = BaseCommand.option_list + GUNICORN_OPTIONS
|
|
||||||
help = "Starts a fully-functional Web server using gunicorn."
|
|
||||||
args = '[optional port number, or ipaddr:port or unix:/path/to/sockfile]'
|
|
||||||
|
|
||||||
# Validation is called explicitly each time the server is reloaded.
|
|
||||||
requires_model_validation = False
|
|
||||||
|
|
||||||
def handle(self, addrport=None, *args, **options):
|
|
||||||
|
|
||||||
# deprecation warning to announce future deletion in R21
|
|
||||||
util.warn("""This command is deprecated.
|
|
||||||
|
|
||||||
You should now run your application with the WSGI interface
|
|
||||||
installed with your project. Ex.:
|
|
||||||
|
|
||||||
gunicorn myproject.wsgi:application
|
|
||||||
|
|
||||||
See https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/gunicorn/
|
|
||||||
for more info.""")
|
|
||||||
|
|
||||||
if args:
|
|
||||||
raise CommandError('Usage is run_gunicorn %s' % self.args)
|
|
||||||
|
|
||||||
if addrport:
|
|
||||||
sys.argv = sys.argv[:-1]
|
|
||||||
options['bind'] = addrport
|
|
||||||
|
|
||||||
admin_media_path = options.pop('admin_media_path', '')
|
|
||||||
|
|
||||||
DjangoApplicationCommand(options, admin_media_path).run()
|
|
||||||
1
setup.py
1
setup.py
@ -94,7 +94,6 @@ setup(
|
|||||||
entry_points="""
|
entry_points="""
|
||||||
[console_scripts]
|
[console_scripts]
|
||||||
gunicorn=gunicorn.app.wsgiapp:run
|
gunicorn=gunicorn.app.wsgiapp:run
|
||||||
gunicorn_django=gunicorn.app.djangoapp:run
|
|
||||||
gunicorn_paster=gunicorn.app.pasterapp:run
|
gunicorn_paster=gunicorn.app.pasterapp:run
|
||||||
|
|
||||||
[paste.server_runner]
|
[paste.server_runner]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user