Kaydet (Commit) 41f0d3d3 authored tarafından Tim Graham's avatar Tim Graham

Removed FastCGI support per deprecation timeline; refs #20766.

üst 37b7776a
......@@ -432,8 +432,8 @@ X_FRAME_OPTIONS = 'SAMEORIGIN'
USE_X_FORWARDED_HOST = False
# The Python dotted path to the WSGI application that Django's internal servers
# (runserver, runfcgi) will use. If `None`, the return value of
# The Python dotted path to the WSGI application that Django's internal server
# (runserver) will use. If `None`, the return value of
# 'django.core.wsgi.get_wsgi_application' is used, thus preserving the same
# behavior as previous versions of Django. Otherwise this should point to an
# actual WSGI application object.
......
......@@ -233,13 +233,8 @@ class ManagementUtility(object):
# special case: the 'help' subcommand has no options
elif cwords[0] in subcommands and cwords[0] != 'help':
subcommand_cls = self.fetch_command(cwords[0])
# special case: 'runfcgi' stores additional options as
# 'key=value' pairs
if cwords[0] == 'runfcgi':
from django.core.servers.fastcgi import FASTCGI_OPTIONS
options.extend((k, 1) for k in FASTCGI_OPTIONS)
# special case: add the names of installed apps to options
elif cwords[0] in ('dumpdata', 'sql', 'sqlall', 'sqlclear',
if cwords[0] in ('dumpdata', 'sql', 'sqlall', 'sqlclear',
'sqlcustom', 'sqlindexes', 'sqlmigrate', 'sqlsequencereset', 'test'):
try:
app_configs = apps.get_app_configs()
......
import argparse
import warnings
from django.core.management.base import BaseCommand
from django.utils.deprecation import RemovedInDjango19Warning
class Command(BaseCommand):
help = "Runs this project as a FastCGI application. Requires flup."
def add_arguments(self, parser):
parser.add_argument('args', nargs=argparse.REMAINDER,
help='Various KEY=val options.')
def handle(self, *args, **options):
warnings.warn(
"FastCGI support has been deprecated and will be removed in Django 1.9.",
RemovedInDjango19Warning)
from django.conf import settings
from django.utils import translation
# Activate the current language, because it won't get activated later.
try:
translation.activate(settings.LANGUAGE_CODE)
except AttributeError:
pass
from django.core.servers.fastcgi import runfastcgi
runfastcgi(args)
def usage(self, subcommand):
from django.core.servers.fastcgi import FASTCGI_HELP
return FASTCGI_HELP
......@@ -33,13 +33,11 @@ def get_internal_wsgi_application():
this will be the ``application`` object in ``projectname/wsgi.py``.
This function, and the ``WSGI_APPLICATION`` setting itself, are only useful
for Django's internal servers (runserver, runfcgi); external WSGI servers
should just be configured to point to the correct application object
directly.
for Django's internal server (runserver); external WSGI servers should just
be configured to point to the correct application object directly.
If settings.WSGI_APPLICATION is not set (is ``None``), we just return
whatever ``django.core.wsgi.get_wsgi_application`` returns.
"""
from django.conf import settings
app_path = getattr(settings, 'WSGI_APPLICATION')
......
"""
FastCGI (or SCGI, or AJP1.3 ...) server that implements the WSGI protocol.
Uses the flup python package: http://www.saddi.com/software/flup/
This is an adaptation of the flup package to add FastCGI server support
to run Django apps from Web servers that support the FastCGI protocol.
This module can be run standalone or from the django-admin / manage.py
scripts using the "runfcgi" directive.
Run with the extra option "help" for a list of additional options you can
pass to this server.
"""
import importlib
import os
import sys
__version__ = "0.1"
__all__ = ["runfastcgi"]
FASTCGI_OPTIONS = {
'protocol': 'fcgi',
'host': None,
'port': None,
'socket': None,
'method': 'fork',
'daemonize': None,
'workdir': '/',
'pidfile': None,
'maxspare': 5,
'minspare': 2,
'maxchildren': 50,
'maxrequests': 0,
'debug': None,
'outlog': None,
'errlog': None,
'umask': None,
}
FASTCGI_HELP = r"""
Run this project as a fastcgi (or some other protocol supported
by flup) application. To do this, the flup package from
http://www.saddi.com/software/flup/ is required.
runfcgi [options] [fcgi settings]
Optional Fcgi settings: (setting=value)
protocol=PROTOCOL fcgi, scgi, ajp, ... (default %(protocol)s)
host=HOSTNAME hostname to listen on.
port=PORTNUM port to listen on.
socket=FILE UNIX socket to listen on.
method=IMPL prefork or threaded (default %(method)s).
maxrequests=NUMBER number of requests a child handles before it is
killed and a new child is forked (0 = no limit).
maxspare=NUMBER max number of spare processes / threads (default %(maxspare)s).
minspare=NUMBER min number of spare processes / threads (default %(minspare)s).
maxchildren=NUMBER hard limit number of processes / threads (default %(maxchildren)s).
daemonize=BOOL whether to detach from terminal.
pidfile=FILE write the spawned process-id to this file.
workdir=DIRECTORY change to this directory when daemonizing (default %(workdir)s).
debug=BOOL set to true to enable flup tracebacks.
outlog=FILE write stdout to this file.
errlog=FILE write stderr to this file.
umask=UMASK umask to use when daemonizing, in octal notation (default 022).
Examples:
Run a "standard" fastcgi process on a file-descriptor
(for Web servers which spawn your processes for you)
$ manage.py runfcgi method=threaded
Run a scgi server on a TCP host/port
$ manage.py runfcgi protocol=scgi method=prefork host=127.0.0.1 port=8025
Run a fastcgi server on a UNIX domain socket (posix platforms only)
$ manage.py runfcgi method=prefork socket=/tmp/fcgi.sock
Run a fastCGI as a daemon and write the spawned PID in a file
$ manage.py runfcgi socket=/tmp/fcgi.sock method=prefork \
daemonize=true pidfile=/var/run/django-fcgi.pid
""" % FASTCGI_OPTIONS
def fastcgi_help(message=None):
print(FASTCGI_HELP)
if message:
print(message)
return False
def runfastcgi(argset=[], **kwargs):
options = FASTCGI_OPTIONS.copy()
options.update(kwargs)
for x in argset:
if "=" in x:
k, v = x.split('=', 1)
else:
k, v = x, True
options[k.lower()] = v
if "help" in options:
return fastcgi_help()
try:
import flup # NOQA
except ImportError as e:
sys.stderr.write("ERROR: %s\n" % e)
sys.stderr.write(" Unable to load the flup package. In order to run django\n")
sys.stderr.write(" as a FastCGI application, you will need to get flup from\n")
sys.stderr.write(" http://www.saddi.com/software/flup/ If you've already\n")
sys.stderr.write(" installed flup, then make sure you have it in your PYTHONPATH.\n")
return False
flup_module = 'server.' + options['protocol']
if options['method'] in ('prefork', 'fork'):
wsgi_opts = {
'maxSpare': int(options["maxspare"]),
'minSpare': int(options["minspare"]),
'maxChildren': int(options["maxchildren"]),
'maxRequests': int(options["maxrequests"]),
}
flup_module += '_fork'
elif options['method'] in ('thread', 'threaded'):
wsgi_opts = {
'maxSpare': int(options["maxspare"]),
'minSpare': int(options["minspare"]),
'maxThreads': int(options["maxchildren"]),
}
else:
return fastcgi_help("ERROR: Implementation must be one of prefork or "
"thread.")
wsgi_opts['debug'] = options['debug'] is not None
try:
module = importlib.import_module('.%s' % flup_module, 'flup')
WSGIServer = module.WSGIServer
except Exception:
print("Can't import flup." + flup_module)
return False
# Prep up and go
from django.core.servers.basehttp import get_internal_wsgi_application
if options["host"] and options["port"] and not options["socket"]:
wsgi_opts['bindAddress'] = (options["host"], int(options["port"]))
elif options["socket"] and not options["host"] and not options["port"]:
wsgi_opts['bindAddress'] = options["socket"]
elif not options["socket"] and not options["host"] and not options["port"]:
wsgi_opts['bindAddress'] = None
else:
return fastcgi_help("Invalid combination of host, port, socket.")
if options["daemonize"] is None:
# Default to daemonizing if we're running on a socket/named pipe.
daemonize = (wsgi_opts['bindAddress'] is not None)
else:
if options["daemonize"].lower() in ('true', 'yes', 't'):
daemonize = True
elif options["daemonize"].lower() in ('false', 'no', 'f'):
daemonize = False
else:
return fastcgi_help("ERROR: Invalid option for daemonize "
"parameter.")
daemon_kwargs = {}
if options['outlog']:
daemon_kwargs['out_log'] = options['outlog']
if options['errlog']:
daemon_kwargs['err_log'] = options['errlog']
if options['umask']:
daemon_kwargs['umask'] = int(options['umask'], 8)
if daemonize:
from django.utils.daemonize import become_daemon
become_daemon(our_home_dir=options["workdir"], **daemon_kwargs)
if options["pidfile"]:
with open(options["pidfile"], "w") as fp:
fp.write("%d\n" % os.getpid())
WSGIServer(get_internal_wsgi_application(), **wsgi_opts).run()
if __name__ == '__main__':
runfastcgi(sys.argv[1:])
import os
import sys
from . import six
buffering = int(six.PY3) # No unbuffered text I/O on Python 3 (#20815).
if os.name == 'posix':
def become_daemon(our_home_dir='.', out_log='/dev/null',
err_log='/dev/null', umask=0o022):
"Robustly turn into a UNIX daemon, running in our_home_dir."
# First fork
try:
if os.fork() > 0:
sys.exit(0) # kill off parent
except OSError as e:
sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
sys.exit(1)
os.setsid()
os.chdir(our_home_dir)
os.umask(umask)
# Second fork
try:
if os.fork() > 0:
os._exit(0)
except OSError as e:
sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
os._exit(1)
si = open('/dev/null', 'r')
so = open(out_log, 'a+', buffering)
se = open(err_log, 'a+', buffering)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
# Set custom file descriptors so that they get proper buffering.
sys.stdout, sys.stderr = so, se
else:
def become_daemon(our_home_dir='.', out_log=None, err_log=None, umask=0o022):
"""
If we're not running under a POSIX system, just simulate the daemon
mode by doing redirections and directory changing.
"""
os.chdir(our_home_dir)
os.umask(umask)
sys.stdin.close()
sys.stdout.close()
sys.stderr.close()
if err_log:
sys.stderr = open(err_log, 'a', buffering)
else:
sys.stderr = NullDevice()
if out_log:
sys.stdout = open(out_log, 'a', buffering)
else:
sys.stdout = NullDevice()
class NullDevice:
"A writeable object that writes to nowhere -- like /dev/null."
def write(self, s):
pass
This diff is collapsed.
......@@ -12,13 +12,6 @@ ways to easily deploy Django:
wsgi/index
checklist
FastCGI support is deprecated and will be removed in Django 1.9.
.. toctree::
:maxdepth: 1
fastcgi
If you're new to deploying Django and/or Python, we'd recommend you try
:doc:`mod_wsgi </howto/deployment/wsgi/modwsgi>` first. In most cases it'll be
the easiest, fastest, and most stable deployment choice.
......
......@@ -36,10 +36,10 @@ It's used both by Django's development server and in production WSGI
deployments.
WSGI servers obtain the path to the ``application`` callable from their
configuration. Django's built-in servers, namely the :djadmin:`runserver` and
:djadmin:`runfcgi` commands, read it from the :setting:`WSGI_APPLICATION`
setting. By default, it's set to ``<project_name>.wsgi.application``, which
points to the ``application`` callable in :file:`<project_name>/wsgi.py`.
configuration. Django's built-in server, namely the :djadmin:`runserver`
command, read it from the :setting:`WSGI_APPLICATION` setting. By default, it's
set to ``<project_name>.wsgi.application``, which points to the ``application``
callable in :file:`<project_name>/wsgi.py`.
Configuring the settings module
-------------------------------
......
......@@ -205,7 +205,6 @@ testing of Django applications:
* **Deployment:**
:doc:`Overview <howto/deployment/index>` |
:doc:`WSGI servers <howto/deployment/wsgi/index>` |
:doc:`FastCGI/SCGI/AJP <howto/deployment/fastcgi>` (deprecated) |
:doc:`Deploying static files <howto/static-files/deployment>` |
:doc:`Tracking code errors by email <howto/error-reporting>`
......
......@@ -64,11 +64,6 @@ Runs over the entire source tree of the current directory and pulls out all
strings marked for translation. It creates (or updates) a message file in the
conf/locale (in the django tree) or locale (for project and application) directory.
.TP
.BI "runfcgi [" "KEY=val" "] [" "KEY=val" "] " "..."
Runs this project as a FastCGI application. Requires flup. Use
.B runfcgi help
for help on the KEY=val pairs.
.TP
.BI "runserver [" "\-\-noreload" "] [" "\-\-nothreading" "] [" "\-\-nostatic" "] [" "\-\-insecure" "] [" "\-\-ipv6" "] [" "port|ipaddr:port" "]"
Starts a lightweight Web server for development.
.TP
......
......@@ -11,8 +11,7 @@ the deployment of a normal Django application. Please consult Django's
GeoDjango uses the GDAL geospatial library which is
not thread safe at this time. Thus, it is *highly* recommended
to not use threading when deploying -- in other words, use an
appropriate configuration of Apache or the prefork method
when using FastCGI through another Web server.
appropriate configuration of Apache.
For example, when configuring your application with ``mod_wsgi``,
set the ``WSGIDaemonProcess`` attribute ``threads`` to ``1``, unless
......
......@@ -775,133 +775,6 @@ run correctly.
The ``--list`` option has been moved to the :djadmin:`showmigrations`
command.
runfcgi [options]
-----------------
.. django-admin:: runfcgi
.. deprecated:: 1.7
FastCGI support is deprecated and will be removed in Django 1.9.
Starts a set of FastCGI processes suitable for use with any Web server that
supports the FastCGI protocol. See the :doc:`FastCGI deployment documentation
</howto/deployment/fastcgi>` for details. Requires the Python FastCGI module from
`flup`_.
Internally, this wraps the WSGI application object specified by the
:setting:`WSGI_APPLICATION` setting.
.. _flup: http://www.saddi.com/software/flup/
The options accepted by this command are passed to the FastCGI library and
don't use the ``'--'`` prefix as is usual for other Django management commands.
.. django-admin-option:: protocol
``protocol=PROTOCOL``
Protocol to use. *PROTOCOL* can be ``fcgi``, ``scgi``, ``ajp``, etc.
(default is ``fcgi``)
.. django-admin-option:: host
``host=HOSTNAME``
Hostname to listen on.
.. django-admin-option:: port
``port=PORTNUM``
Port to listen on.
.. django-admin-option:: socket
``socket=FILE``
UNIX socket to listen on.
.. django-admin-option:: method
``method=IMPL``
Possible values: ``prefork`` or ``threaded`` (default ``prefork``)
.. django-admin-option:: maxrequests
``maxrequests=NUMBER``
Number of requests a child handles before it is killed and a new child is
forked (0 means no limit).
.. django-admin-option:: maxspare
``maxspare=NUMBER``
Max number of spare processes / threads.
.. django-admin-option:: minspare
``minspare=NUMBER``
Min number of spare processes / threads.
.. django-admin-option:: maxchildren
``maxchildren=NUMBER``
Hard limit number of processes / threads.
.. django-admin-option:: daemonize
``daemonize=BOOL``
Whether to detach from terminal.
.. django-admin-option:: pidfile
``pidfile=FILE``
Write the spawned process-id to file *FILE*.
.. django-admin-option:: workdir
``workdir=DIRECTORY``
Change to directory *DIRECTORY* when daemonizing.
.. django-admin-option:: debug
``debug=BOOL``
Set to true to enable flup tracebacks.
.. django-admin-option:: outlog
``outlog=FILE``
Write stdout to the *FILE* file.
.. django-admin-option:: errlog
``errlog=FILE``
Write stderr to the *FILE* file.
.. django-admin-option:: umask
``umask=UMASK``
Umask to use when daemonizing. The value is interpreted as an octal number
(default value is ``0o22``).
Example usage::
django-admin runfcgi socket=/tmp/fcgi.sock method=prefork daemonize=true \
pidfile=/var/run/django-fcgi.pid
Run a FastCGI server as a daemon and write the spawned PID in a file.
runserver [port or address:port]
--------------------------------
......
......@@ -692,8 +692,7 @@ more flexible ``mod_wsgi`` backend.
If you are currently using the ``mod_python`` request handler, you
should redeploy your Django projects using another request handler.
:doc:`mod_wsgi </howto/deployment/wsgi/modwsgi>` is the request handler
recommended by the Django project, but :doc:`FastCGI
</howto/deployment/fastcgi>` is also supported. Support for
recommended by the Django project, but FastCGI is also supported. Support for
``mod_python`` deployment will be removed in Django 1.5.
Function-based generic views
......
......@@ -220,7 +220,7 @@ with the same WSGI configuration that is used for deployment. The new
:setting:`WSGI_APPLICATION` setting lets you configure which WSGI callable
:djadmin:`runserver` uses.
(The :djadmin:`runfcgi` management command also internally wraps the WSGI
(The ``runfcgi`` management command also internally wraps the WSGI
callable configured via :setting:`WSGI_APPLICATION`.)
``SELECT FOR UPDATE`` support
......
......@@ -199,9 +199,7 @@ Facebook
fallback
fallbacks
faq
fastcgi
FastCGI
fcgid
fieldset
fieldsets
filesizeformat
......@@ -540,7 +538,6 @@ rjust
roadmap
Roald
rss
runfcgi
runserver
SaaS
safeseq
......
[run]
omit = */django/contrib/*/tests*,*/django/core/servers/fastcgi.py,*/django/utils/autoreload.py
omit = */django/contrib/*/tests*,*/django/utils/autoreload.py
[report]
ignore_errors = True
......
......@@ -93,12 +93,6 @@ class BashCompletionTests(unittest.TestCase):
output = self._run_autocomplete()
self.assertEqual(output, [''])
def test_runfcgi(self):
"Command arguments will be autocompleted"
self._user_input('django-admin runfcgi h')
output = self._run_autocomplete()
self.assertEqual(output, ['host='])
def test_app_completion(self):
"Application names will be autocompleted for an AppCommand"
self._user_input('django-admin sqlmigrate a')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment