import os
import signal
from optparse import OptionParser, make_option
from django.core.management.base import BaseCommand
from django.core.handlers.wsgi import WSGIHandler
from django.conf import settings
try:
from cherrypy.wsgiserver import CherryPyWSGIServer
except ImportError:
from wsgiserver import CherryPyWSGIServer
DEFAULT_HOST = getattr(settings, "WSGI_HOST", "127.0.0.1")
DEFAULT_PORT = getattr(settings, "WSGI_PORT", 8001)
class Command(BaseCommand):
option_list = BaseCommand.option_list + (
make_option("-h", "--host", dest="host", default="127.0.0.1"),
make_option("-p", "--port", dest="port", default=8001),
make_option("-d", "--daemon", dest="daemonize", action="store_true"),
)
requires_model_validation = False
def handle(self, *args, **options):
self.server = CherryPyWSGIServer((options["host"], options["port"]), WSGIHandler())
self.pidfile = os.path.join(settings.PROJECT_ROOT, "logs/wsgi.pid")
try:
action = args[0]
except IndexError:
print "You must provide an action. Possible actions are start, stop and restart."
raise SystemExit
if options["daemonize"]:
daemonize()
if action == "start":
self.start()
elif action == "stop":
pid = open(self.pidfile, "r").read()
self.stop(pid)
elif action == "restart":
pid = open(self.pidfile, "r").read()
self.restart(pid)
def start(self):
writepid(self.pidfile)
try:
self.server.start()
except KeyboardInterrupt:
# likely not a daemon so make sure to shutdown properly.
self.server.stop()
def stop(self, pid):
os.kill(int(pid), signal.SIGHUP)
def restart(self, pid):
self.stop(pid)
self.start()
def create_parser(self, prog_name, subcommand):
"""
Create and return the ``OptionParser`` which will be used to
parse the arguments to this command.
"""
return OptionParser(prog=prog_name, usage=self.usage(subcommand),
version = self.get_version(),
option_list = self.option_list,
conflict_handler = "resolve")
def writepid(pid_file):
"""
Write the process ID to disk.
"""
fp = open(pid_file, "w")
fp.write(str(os.getpid()))
fp.close()
def daemonize():
"""
Detach from the terminal and continue as a daemon.
"""
# swiped from twisted/scripts/twistd.py
# See http://www.erlenstar.demon.co.uk/unix/faq_toc.html#TOC16
if os.fork(): # launch child and...
os._exit(0) # kill off parent
os.setsid()
if os.fork(): # launch child and...
os._exit(0) # kill off parent again.
os.umask(077)
null = os.open("/dev/null", os.O_RDWR)
for i in range(3):
try:
os.dup2(null, i)
except OSError, e:
if e.errno != errno.EBADF:
raise
os.close(null)