Skip to content
cc-node 3.98 KiB
Newer Older
Benziane Chakib's avatar
Benziane Chakib committed
#!/usr/bin/env python
#coding=utf8

from optparse import OptionParser
from sjrpc.core import RpcError
from ccnode.ccnode import CCNode
import ConfigParser
import sys
import logging
import logging.handlers
import signal
import threading
from time import sleep
Benziane Chakib's avatar
Benziane Chakib committed

try:
    import daemon
    DAEMONIZE = True
except ImportError:
    DAEMONIZE = False

Antoine Millet's avatar
Antoine Millet committed
__VERSION__ = 3
Benziane Chakib's avatar
Benziane Chakib committed

DEFAULT_CONFIG_FILE = '/etc/cc-node.conf'
DEFAULT_PID_FILE = '/var/run/cc-node.pid'
DEFAULT_CONFIGURATION = {
    'address': None,
Benziane Chakib's avatar
Benziane Chakib committed
    'password': None,
    'port': 1984,
    'verbosity': 0,
    #'ssl_cert': '',
}

MAX_AUTH_TIMEOUT = 10

Benziane Chakib's avatar
Benziane Chakib committed
def run_node(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-node: %(levelname)s %(message)s')
    handler.setFormatter(fmt)
    logger.handlers = []
    logger.addHandler(handler)

    logging.debug('Connecting to server')
    
    try:
        node = CCNode(options['address'], int(options['port']))
    except Exception as err:
        logging.critical('Starting fail: %s' % err)
        return
    else:
        logging.info('Connected to server %s' % options['address'])

    def authentication():
Benziane Chakib's avatar
Benziane Chakib committed
        while node.manager.is_running():
            result = node.authentify(options['login'], options['password'])
            if result:
                logging.info('Authentication suscessfull.')
                return
Benziane Chakib's avatar
Benziane Chakib committed
            else:
                maxtimeout = MAX_AUTH_TIMEOUT
                if timeout == maxtimeout:
                    timeout = maxtimeout
Benziane Chakib's avatar
Benziane Chakib committed
    
    def shutdown_handler(signum, frame):
        '''
        Handler called when SIGINT emited
        '''
        
        node.manager.shutdown()
        logging.info('Node properly exited by SIGINT')
        sys.exit(0)

    signal.signal(signal.SIGINT, shutdown_handler)

    threading.Thread(target=authentication).start()

    try:
        node.run()
    except Exception as err:
        node.manager.shutdown()
        logging.critical('Node failed: %s' % err)
        return

if __name__ == '__main__':

    usage = 'usage: %prog [OPTION...]'
    op = OptionParser(usage, 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('node'))
    except ConfigParser.NoSectionError:
        sys.stderr.write("Configuration error: 'node' 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

    while True:
       run_node(options)
       logging.warning('Critical error, restarting node')
       sleep(2)