Commit f01fb457 authored by Thibault VINCENT's avatar Thibault VINCENT
Browse files

more solid handling of sjrpc disconnection and critical errors

parent 37c841f5
Loading
Loading
Loading
Loading
+65 −43
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ MAX_AUTH_TIMEOUT = 10
def run_node(options):
    '''
    '''
    # Setup logging facility:
    # setup logging facility:
    level = logging.ERROR
    verb = int(options['verbosity'])
    if verb:
@@ -60,26 +60,35 @@ def run_node(options):
    logger.handlers = []
    logger.addHandler(handler)
    
    logging.debug('Connecting to server')
    
    # setup SIGINT handler
    def shutdown_handler(signum, frame):
        '''
        Handler called when SIGINT emited
        '''
        logging.info('SIGINT received, node shutdown in progress')
        try:
        node = CCNode(options['address'], int(options['port']),
                      options['detect_hypervisor'] == 'yes',
                      options['command_execution'] == 'yes')
    except Exception as err:
        logging.critical('Starting fail: %s' % err)
        return
    else:
        logging.info('Connected to server %s' % options['address'])

    def authentication():
            '''
            #FIXME REGRESSION
            if node:
                logging.debug('Closing server connection')
                node.manager.shutdown()
            '''
            pass
        except:
            pass
        sys.exit(0)
    
    signal.signal(signal.SIGINT, shutdown_handler)
    
    # re-authentication thread
    def authentication(node):
        timeout = 1
        while node.manager.is_running():
        while node:
            if node.manager.is_running():
                logging.debug('Sending authentication request')
                result = node.authentify(options['login'], options['password'])
                if result:
                logging.info('Authentication suscessfull.')
                    logging.info('Authentication suscessfull')
                    return
                else:
                    timeout += 0.1
@@ -88,26 +97,39 @@ def run_node(options):
                        timeout = maxtimeout
                    sleep(exp(timeout))
    
    
    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()

    # start node
    none = None
    auth_thread = None
    try:
        logging.info('Initializing node client')
        try:
            node = CCNode(options['address'], int(options['port']),
                          options['detect_hypervisor'] == 'yes',
                          options['command_execution'] == 'yes')
        except Exception as err:
            logging.critical('Client initialization failure: `%s`' % err)
            raise err
        
        # start main loop and auth thread
        logging.debug('Starting authentication thread')
        auth_thread = threading.Thread(target=authentication, args=(node,),
                                                                    name="Auth")
        auth_thread.start()
        logging.debug('Starting node main loop')
        node.run()
    
    except Exception as err:
        if auth_thread:
            auth_thread.cancel()
            del auth_thread
            auth_thread = None
        if node:
            node.manager.shutdown()
        logging.critical('Node failed: %s' % err)
            del node
            node = None
    finally:
        return


if __name__ == '__main__':
    
    usage = 'usage: %prog [OPTION...]'
@@ -127,21 +149,21 @@ if __name__ == '__main__':
    try:
        options = dict(config.items('node'))
    except ConfigParser.NoSectionError:
        sys.stderr.write("Configuration error: 'node' section must exist "
                         "in '%s'\n" % cliopts.config)
        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.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')
       logging.warning('Critical error, restarting node !')
       sleep(2)
 No newline at end of file