Skip to content
cc-server 3.52 KiB
Newer Older
Antoine Millet's avatar
Antoine Millet committed
#!/usr/bin/env python
#coding=utf8

import sys
import logging
import logging.handlers
import ConfigParser
import signal
from optparse import OptionParser
from ccserver.ccserver import CCServer
import os
try:
    import daemon
    DAEMONIZE = True
except ImportError:
    DAEMONIZE = False

Antoine Millet's avatar
Antoine Millet committed
__VERSION__ = 4
Antoine Millet's avatar
Antoine Millet committed

DEFAULT_CONFIG_FILE = '/etc/cc-server.conf'
DEFAULT_PID_FILE = '/var/run/cc-server.pid'
DEFAULT_CONFIGURATION = {
    'port': 1984,
    'verbosity': 0,
    'account_db': None, # None = mandatory option
    'interface': '127.0.0.1',
    'ssl_cert': None,
    'ssl_key': None,
}

def run_server(options):

    # Setup logging facility:
    level = logging.ERROR
    verb = int(options['verbosity'])
    if verb:
        if verb == 1:
            level = logging.WARNING
        elif verb == 2:
            level = logging.INFO
        else:
            level = logging.DEBUG

    logger = logging.getLogger()
    logger.setLevel(level)
    facility = logging.handlers.SysLogHandler.LOG_DAEMON
    handler = logging.handlers.SysLogHandler(address='/dev/log',
                                             facility=facility)
    fmt = logging.Formatter('cc-server: %(levelname)s %(message)s')
    handler.setFormatter(fmt)
    logger.addHandler(handler)

    server = CCServer(conf_dir=options['account_db'], port=int(options['port']),
                      address=options['interface'], keyfile=options['ssl_key'],
                      certfile=options['ssl_cert'])

    def shutdown_handler(signum, frame):
        '''
        Handler called when SIGINT is emitted.
        '''

        server.manager.shutdown()
        logging.info('Server properly exited by SIGINT')
        sys.exit(0)

    signal.signal(signal.SIGINT, shutdown_handler)

    try:
        server.run()
    except Exception as err:
        import traceback
        traceback.print_exc(file=sys.stdout)
        logging.critical('Server fail: %s' % err)
        sys.exit(3)

if __name__ == '__main__':

    op = OptionParser(version='%%prog %s' % __VERSION__)
    op.add_option('-c', '--config', default=DEFAULT_CONFIG_FILE,
                  help='configuration file (default: %default)')
    op.add_option('-d', '--daemonize', default=False, action='store_true',
                  help='run as daemon and write pid file')
    op.add_option('-p', '--pid-file', default=DEFAULT_PID_FILE,
                  help='pid file (default: %default)')

    cliopts, args = op.parse_args()

    # Reading the config file:
    config = ConfigParser.SafeConfigParser()
    config.read(cliopts.config)
    try:
        options = dict(config.items('server'))
    except ConfigParser.NoSectionError:
        sys.stderr.write("Configuration error: 'server' section must exist "
                         "in '%s'\n" % cliopts.config)
        sys.exit(1)

    # Applying default config file options:
    for opt, default in DEFAULT_CONFIGURATION.iteritems():
        if opt not in options or not options[opt]:
            if default is None:
                sys.stderr.write("Configuration error: you must specify '%s' "
                                 "option in '%s' !\n" % (opt, cliopts.config))
                sys.exit(1)
            else:
                options[opt] = default

    if cliopts.daemonize:
        if DAEMONIZE:
            with daemon.DaemonContext(stderr=sys.stderr):
                run_server(options)
        else:
            sys.stderr.write(('You must install python-daemon to handle the '
                              'daemonization of the process.\n'))
            sys.exit(2)
    else:
        run_server(options)