Ticket #152: django-fcgi.py

File django-fcgi.py, 4.5 KB (added by hugo <gb@…>, 14 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