153 lines
5.6 KiB
Python
153 lines
5.6 KiB
Python
# w.c.s. - web application for online forms
|
|
# Copyright (C) 2005-2010 Entr'ouvert
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import os
|
|
import socket
|
|
import sys
|
|
import qommon.scgi_server
|
|
import quixote
|
|
import quixote.server.simple_server
|
|
|
|
from qommon.ctl import Command, make_option
|
|
|
|
class CmdStart(Command):
|
|
name = 'start'
|
|
|
|
def __init__(self):
|
|
Command.__init__(self, [
|
|
make_option('--port', metavar='PORT', action='store',
|
|
dest='port', default=3001),
|
|
make_option('--handler-connection-limit', metavar='LIMIT',
|
|
action='store',
|
|
dest='handler_connection_limit', default=None),
|
|
make_option('--script-name', metavar='NAME', action='store',
|
|
dest='script_name', default=None),
|
|
make_option('--http', action='store_true',
|
|
dest='http', default=False),
|
|
make_option('--silent', action='store_true',
|
|
dest='silent', default=False),
|
|
make_option('--daemonize', action='store_true',
|
|
dest='daemonize', default=False),
|
|
make_option('--pidfile', metavar='FILENAME',
|
|
dest='pidfile'),
|
|
make_option('--max-children', metavar='MAX_CHILDREN',
|
|
type='int', action='store', dest='max_children')
|
|
])
|
|
|
|
def make_silent(self):
|
|
sys.stdout.flush()
|
|
sys.stderr.flush()
|
|
si = file('/dev/null', 'r')
|
|
so = file('/dev/null', 'a+')
|
|
se = file('/dev/null', 'a+', 0)
|
|
os.dup2(si.fileno(), sys.stdin.fileno())
|
|
os.dup2(so.fileno(), sys.stdout.fileno())
|
|
os.dup2(se.fileno(), sys.stderr.fileno())
|
|
|
|
def del_pid(self):
|
|
if not hasattr(self, 'pidfile'):
|
|
return
|
|
try:
|
|
os.remove(self.pidfile)
|
|
except OSError:
|
|
pass
|
|
|
|
def execute(self, base_options, sub_options, args):
|
|
import publisher
|
|
|
|
run_kwargs = {}
|
|
run_kwargs['port'] = int(sub_options.port)
|
|
run_kwargs['spawn_cron'] = True
|
|
run_function = qommon.scgi_server.run
|
|
publisher.WcsPublisher.configure(self.config)
|
|
if sub_options.handler_connection_limit:
|
|
run_kwargs['handler_connection_limit'] = int(sub_options.handler_connection_limit)
|
|
elif self.config.has_option('main', 'handler_connection_limit'):
|
|
run_kwargs['handler_connection_limit'] = self.config.getint('main', 'handler_connection_limit')
|
|
if sub_options.script_name:
|
|
run_kwargs['script_name'] = sub_options.script_name
|
|
if sub_options.max_children:
|
|
run_kwargs['max_children'] = sub_options.max_children
|
|
elif self.config.has_option('main', 'max_children'):
|
|
run_kwargs['max_children'] = self.config.getint('main', 'max_children')
|
|
if sub_options.http:
|
|
run_function = qommon.scgi_server.http_run
|
|
if sub_options.silent:
|
|
self.make_silent()
|
|
|
|
# iterate over all tenants to execute required SQL migrations
|
|
# beforehand.
|
|
pub = publisher.WcsPublisher.create_publisher(register_cron=False)
|
|
quixote.cleanup()
|
|
base_app_dir = pub.app_dir
|
|
for hostname in publisher.WcsPublisher.get_tenants():
|
|
tenant_path = os.path.join(base_app_dir, hostname)
|
|
if not os.path.exists(os.path.join(tenant_path, 'config.pck')):
|
|
continue
|
|
pub = publisher.WcsPublisher.create_publisher(register_cron=False)
|
|
pub.app_dir = tenant_path
|
|
pub.set_config()
|
|
if pub.is_using_postgresql():
|
|
pub.migrate_sql()
|
|
pub.cleanup()
|
|
quixote.cleanup()
|
|
|
|
if sub_options.daemonize:
|
|
try:
|
|
pid = os.fork()
|
|
if pid > 0: # exit first parent
|
|
sys.exit(0)
|
|
except OSError, e:
|
|
print >> sys.stderr, 'failure in first fork (%s)' % e.strerror
|
|
sys.exit(1)
|
|
|
|
os.chdir("/")
|
|
os.setsid()
|
|
os.umask(0)
|
|
|
|
# do second fork
|
|
try:
|
|
pid = os.fork()
|
|
if pid > 0: # exit from second parent
|
|
sys.exit(0)
|
|
except OSError, e:
|
|
print >> sys.stderr, 'failure in second fork (%s)' % e.strerror
|
|
sys.exit(1)
|
|
|
|
if not sub_options.silent:
|
|
self.make_silent()
|
|
|
|
if sub_options.pidfile:
|
|
self.pidfile = sub_options.pidfile
|
|
file(self.pidfile, 'w+').write("%s\n" % os.getpid())
|
|
|
|
try:
|
|
run_function(publisher.WcsPublisher.create_publisher, **run_kwargs)
|
|
except socket.error, e:
|
|
self.del_pid()
|
|
if e[0] == 98:
|
|
print >> sys.stderr, 'address already in use'
|
|
sys.exit(1)
|
|
raise
|
|
except KeyboardInterrupt:
|
|
self.del_pid()
|
|
sys.exit(1)
|
|
|
|
self.del_pid()
|
|
|
|
CmdStart.register()
|
|
|