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

import sys
import signal
import atexit
import time
import logging
import logging.config
from optparse import OptionParser
from os.path import isfile, abspath

from daemon import DaemonContext

from ccnode import __version__
from ccnode.node import Node
from ccnode.utils import signal_
from ccnode.config import NodeConfigParser


logger = logging.getLogger('ccnode')


DEFAULT_CONFIG_FILE = '/etc/cc-node.conf'


# command line arguments...
oparser = OptionParser(version='%%prog %s' % __version__)
oparser.add_option('-d', '--daemonize', default=False, action='store_true',
                  help=u'run as daemon and write pid file')
oparser.add_option('-c', '--config', metavar='FILE',
                  default=DEFAULT_CONFIG_FILE,
                  help=u'configuration file ABSOLUTE path (default: %default)')
oparser.add_option('-p', '--pidfile', metavar='FILE',
                  help=u'pid file path for daemon mode')
options, args = oparser.parse_args()
# check argument configuration
if options.daemonize and not options.pidfile:
    sys.exit(u'Please supply a pid file...')

options.config = abspath(options.config)
if not isfile(options.config):
    sys.exit(u'Please supply a valid path to configuration file...')


# globals
need_reload = False
node = None
config_file = NodeConfigParser(options.config)


# configure logging
logging.config.fileConfig(options.config)


@signal_(signal.SIGUSR1)
def reload_config(signum, frame):
    global need_reload

    need_reload = True


@signal_(signal.SIGTERM)
def exit_node(signum=None, frame=None):
    # clean all current jobs
    # TODO
    if node is not None:
        # clean node
        node.shutdown()
    # exit
    logger.info(u'Exiting node...')
    sys.exit()


def run_node():
    global need_reload, node

    try:
        node = Node(
          server_host=config_file.server_host,
          server_port=config_file.server_port,
          user_name=config_file.server_user,
          user_passwd=config_file.server_passwd,
        )
        node.start()
        while True:
            if need_reload:
                logger.info(u'Reloading logging configuration...')
                logging.config.fileConfig(options.config)
                need_reload = False

            signal.pause()
    except KeyboardInterrupt:
        exit_node()
    except Exception:
        logger.exception(u'Unknown error:')


# take care of pid file if daemon
if options.daemonize:
    pidfile = open(options.pidfile)
    files_preserve = [pidfile]
else:
    files_preserve = None


with DaemonContext(detach_process=options.daemonize,
                   files_preserve=files_preserve,
                   stderr=sys.stderr,
                   stdout=sys.stdout):
    # reload log config
    logging.config.fileConfig(options.config)

    # take care of pidfile
    if options.daemonize:
        pidfile.write('%s' % os.getpid())
        pidfile.flush()

        @atexit.register
        def clean_pidfile():
            pidfile.seek(0)
            pidfile.truncate()
            pidfile.flush()

    logger.debug(u'Starting node')
    while True:
        run_node()

        logger.critical(u'Restarting node...')
        time.sleep(2)