Ticket #152: django-fcgi.py

File django-fcgi.py, 4.5 KB (added by hugo <gb@…>, 19 years ago)

FCGI server script

Line 
1#!/usr/bin/python2.3
2
3import os
4import sys
5
6if os.name == 'posix':
7
8 def become_daemon(ourHomeDir='.',outLog='/dev/null',errLog='/dev/null'):
9 """
10 Robustly turn us into a UNIX daemon, running in ourHomeDir.
11 Modelled after the original code of this module and some
12 sample code from the net.
13 """
14
15 # first fork
16 try:
17 if os.fork() > 0:
18 sys.exit(0) # kill off parent
19 except OSError, e:
20 sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
21 sys.exit(1)
22 os.setsid()
23 os.chdir(ourHomeDir)
24 os.umask(0)
25 # second fork
26 try:
27 if os.fork() > 0:
28 sys.exit(0)
29 except OSError, e:
30 sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
31 sys.exit(1)
32
33 si = open('/dev/null', 'r')
34 so = open(outLog, 'a+', 0)
35 se = open(errLog, 'a+', 0)
36 os.dup2(si.fileno(), sys.stdin.fileno())
37 os.dup2(so.fileno(), sys.stdout.fileno())
38 os.dup2(se.fileno(), sys.stderr.fileno())
39
40else:
41
42 def become_daemon(ourHomeDir='.',outLog=None,errLog=None):
43 """
44 If we are not running under a POSIX system, just simulate
45 the daemon mode by doing redirections and directory changeing
46 """
47
48 os.chdir(ourHomeDir)
49 os.umask(0)
50 sys.stdin.close()
51 sys.stdout.close()
52 sys.stderr.close()
53 if errLog and outLog:
54 sys.stderr=open (errLog, 'a', 0)
55 sys.stdout=open (outLog, 'a', 0)
56 elif errLog:
57 sys.stderr=open (errLog, 'a', 0)
58 sys.stdout=NullDevice ()
59 elif outLog:
60 sys.stdout=open (outLog, 'a', 0)
61 sys.stderr=NullDevice ()
62 else:
63 sys.stdout = NullDevice()
64 sys.stderr = NullDevice()
65
66 class NullDevice:
67 """
68 A substitute for stdout and stderr that writes to nowhere.
69 This is a substitute for /dev/null
70 """
71
72 def write(self, s):
73 pass
74
75def main():
76 from flup.server.fcgi_fork import WSGIServer
77 from django.core.handlers.wsgi import WSGIHandler
78
79 import getopt
80
81 (opts, args) = getopt.getopt(sys.argv[1:], 'f:s:h:p:',
82 ['settings=','socket=','host=','port=',
83 'minspare=', 'maxspare=', 'maxchildren=',
84 'daemon', 'etclog=', 'errorlog=', 'workdir='])
85
86 socket = None
87 host = None
88 port = None
89
90 minspare = 1
91 maxspare = 5
92 maxchildren = 50
93
94 daemon = None
95 workdir = '.'
96 etclog = '/dev/null'
97 errorlog = '/dev/null'
98
99 for (o, v) in opts:
100 if o in ('-s', '--socket'):
101 socket = v
102 elif o in ('-h', '--host'):
103 host = v
104 elif o in ('-p', '--port'):
105 port = int(v)
106 elif o in ('-f', '--settings'):
107 os.environ['DJANGO_SETTINGS_MODULE'] = v
108 elif o in ('--minspare',):
109 minspare = int(v)
110 elif o in ('--maxspare',):
111 maxspare = int(v)
112 elif o in ('--maxchildren',):
113 maxchildren = int(v)
114 elif o in ('--daemon',):
115 daemon = 1
116 elif o in ('--errorlog',):
117 errorlog = v
118 elif o in ('--etclog',):
119 etclog = v
120 elif o in ('--workdir',):
121 workdir = v
122
123 # if we should run as a daemon, use the above function to turn us
124 # into one reliably. This should correctly detach from the tty.
125 if daemon:
126 become_daemon(ourHomeDir=workdir,
127 outLog=etclog, errLog=errorlog)
128
129 if socket and not host and not port:
130 WSGIServer(WSGIHandler(), minSpare=minspare, maxSpare=maxspare, maxChildren=maxchildren, bindAddress=socket).run()
131 elif not socket and host and port:
132 WSGIServer(WSGIHandler(), minSpare=minspare, maxSpare=maxspare, maxChildren=maxchildren, bindAddress=(host, port)).run()
133 else:
134 print "usage: django-fcgi.py [--settings=<settingsmodule>] --socket=<socketname>"
135 print " or: django-fcgi.py [--settings=<settingsmodule>] --host==<hostname> --port=<portnumber>"
136 print
137 print " additional options are:"
138 print " --minspare=<minimum number of spare processes, default 1>"
139 print " --maxspare=<maximum number of spare processes, default 5>"
140 print " --maxchildren=<maximum number of child processes, default 50>"
141 print
142 print " --daemon"
143 print " --etclog=<path for stdout log, default /dev/null>"
144 print " --errorlog=<path for stderr log, default /dev/null>"
145 print " --workdir=<path for working directory, default .>"
146
147if __name__ == '__main__':
148
149 # first patch our own version of socketpair into the sockets module
150 # if we don't have it already (comes with Python 2.4)
151
152 import socket
153 if not hasattr(socket, 'socketpair'):
154 import eunuchs.socketpair
155
156 def socketpair():
157 (p,c) = eunuchs.socketpair.socketpair()
158 return (socket.fromfd(p,1,1), socket.fromfd(c,1,1))
159
160 socket.socketpair = socketpair
161
162 main()
163
Back to Top