1"""The CherryPy daemon.""" 2 3import sys 4 5import cherrypy 6from cherrypy.process import plugins, servers 7from cherrypy import Application 8 9 10def start(configfiles=None, daemonize=False, environment=None, 11 fastcgi=False, scgi=False, pidfile=None, imports=None, 12 cgi=False): 13 """Subscribe all engine plugins and start the engine.""" 14 sys.path = [''] + sys.path 15 for i in imports or []: 16 exec('import %s' % i) 17 18 for c in configfiles or []: 19 cherrypy.config.update(c) 20 # If there's only one app mounted, merge config into it. 21 if len(cherrypy.tree.apps) == 1: 22 for app in cherrypy.tree.apps.values(): 23 if isinstance(app, Application): 24 app.merge(c) 25 26 engine = cherrypy.engine 27 28 if environment is not None: 29 cherrypy.config.update({'environment': environment}) 30 31 # Only daemonize if asked to. 32 if daemonize: 33 # Don't print anything to stdout/sterr. 34 cherrypy.config.update({'log.screen': False}) 35 plugins.Daemonizer(engine).subscribe() 36 37 if pidfile: 38 plugins.PIDFile(engine, pidfile).subscribe() 39 40 if hasattr(engine, 'signal_handler'): 41 engine.signal_handler.subscribe() 42 if hasattr(engine, 'console_control_handler'): 43 engine.console_control_handler.subscribe() 44 45 if (fastcgi and (scgi or cgi)) or (scgi and cgi): 46 cherrypy.log.error('You may only specify one of the cgi, fastcgi, and ' 47 'scgi options.', 'ENGINE') 48 sys.exit(1) 49 elif fastcgi or scgi or cgi: 50 # Turn off autoreload when using *cgi. 51 cherrypy.config.update({'engine.autoreload.on': False}) 52 # Turn off the default HTTP server (which is subscribed by default). 53 cherrypy.server.unsubscribe() 54 55 addr = cherrypy.server.bind_addr 56 cls = ( 57 servers.FlupFCGIServer if fastcgi else 58 servers.FlupSCGIServer if scgi else 59 servers.FlupCGIServer 60 ) 61 f = cls(application=cherrypy.tree, bindAddress=addr) 62 s = servers.ServerAdapter(engine, httpserver=f, bind_addr=addr) 63 s.subscribe() 64 65 # Always start the engine; this will start all other services 66 try: 67 engine.start() 68 except Exception: 69 # Assume the error has been logged already via bus.log. 70 sys.exit(1) 71 else: 72 engine.block() 73 74 75def run(): 76 """Run cherryd CLI.""" 77 from optparse import OptionParser 78 79 p = OptionParser() 80 p.add_option('-c', '--config', action='append', dest='config', 81 help='specify config file(s)') 82 p.add_option('-d', action='store_true', dest='daemonize', 83 help='run the server as a daemon') 84 p.add_option('-e', '--environment', dest='environment', default=None, 85 help='apply the given config environment') 86 p.add_option('-f', action='store_true', dest='fastcgi', 87 help='start a fastcgi server instead of the default HTTP ' 88 'server') 89 p.add_option('-s', action='store_true', dest='scgi', 90 help='start a scgi server instead of the default HTTP server') 91 p.add_option('-x', action='store_true', dest='cgi', 92 help='start a cgi server instead of the default HTTP server') 93 p.add_option('-i', '--import', action='append', dest='imports', 94 help='specify modules to import') 95 p.add_option('-p', '--pidfile', dest='pidfile', default=None, 96 help='store the process id in the given file') 97 p.add_option('-P', '--Path', action='append', dest='Path', 98 help='add the given paths to sys.path') 99 options, args = p.parse_args() 100 101 if options.Path: 102 for p in options.Path: 103 sys.path.insert(0, p) 104 105 start(options.config, options.daemonize, 106 options.environment, options.fastcgi, options.scgi, 107 options.pidfile, options.imports, options.cgi) 108