Beispiel #1
0
from controllers.task import Task
from controllers.server import Server
from controllers.manager import Manager
from controllers.logger import Logger

LOGLEVEL = getattr(logging, os.environ.get('LOGLEVEL', 'INFO'), logging.INFO)

if __name__ == '__main__':
    logger = Logger(level=LOGLEVEL)
    try:
        try:
            logger.info('Parsing input configuration...', end='')
            parser = TaskmasterDaemonParser.from_command_line()
        except ParseError as e:
            print("")
            logger.error(e)
            sys.exit(-1)

        logger.success('')
        logger.debug('Configuration retrieved: %s' % parser.configuration)
        programs = list()

        if parser.configuration.get('programs', {}):
            for program_name, program_params in parser.configuration.get(
                    'programs', {}).items():
                params = copy.deepcopy(program_params)
                cmd = params.pop('cmd')
                task = Task(program_name, cmd, **params)
                programs.append(task)

        logger.success('Tasks initialized.')
Beispiel #2
0
class TaskmasterDaemonParser:
    """TaskmasterDeamonParser class.

    > See `supervisord`.
    """
    def __init__(self, conf_path):
        self.conf_path = conf_path

        self.log = Logger(LOGLEVEL)

        if not os.path.exists(conf_path):
            print("")
            self.log.error('Unknown file or directory %s.' % conf_path)
            sys.exit(-1)

        try:
            with open(conf_path) as conf:
                self.configuration = config = yaml.load(conf, Loader=Loader)
            self.log.debug('Configuration readed: %s' % self.configuration)
        except Exception:
            raise ParseError('Unable to read configuration file %s' %
                             conf_path)

        if 'programs' not in config or len(config) > 1:
            raise ParseError(
                ('config file is invalid, '
                 'bad indentation or "program" section not found.'))
        self.check_configuration()

    @classmethod
    def from_command_line(cls):
        parser = argparse.ArgumentParser()
        parser.add_argument(
            '--config_file',
            '-c',
            required=True,
            type=str,
        )
        args = parser.parse_args()
        return cls(args.config_file)

    def diff(self, parser):
        return diff_dict(self.configuration['programs'],
                         parser.configuration['programs'])

    def refresh(self):
        try:
            parser = TaskmasterDaemonParser(self.conf_path)
        except ParseError as e:
            self.log.error(e)
            os.kill(os.getpid(), signal.SIGKILL)
        diff = self.diff(parser)
        self.configuration = parser.configuration
        return diff

    def check_configuration(self):
        programs = self.configuration.get('programs', {})

        if not programs:
            self.configuration['programs'] = dict()
            self.log.warning('Any programs to be loaded')
            return

        for program_name, parameters in programs.items():

            for rparam in REQUIRED_PARAMS:
                if rparam not in parameters:
                    raise ParseError(
                        f'{program_name}: Missing required parameter {rparam}')

            for parameter_key, pvalue in parameters.items():

                if parameter_key not in CONFIGURATION_MAPPING:
                    raise ParseError(
                        f'Unknown parameter "{parameter_key}" in task {program_name}.'
                    )

                parameter_mapping = CONFIGURATION_MAPPING[parameter_key]
                expected_type = _to_list(parameter_mapping['expected_type'])
                handler = parameter_mapping.get('handler', _no_check)
                transform = parameter_mapping.get('transform')
                args = parameter_mapping.get('args', list())

                if not isinstance(pvalue, tuple(expected_type)):
                    actual_type = type(pvalue)
                    raise ParseError(
                        f'{program_name}: {parameter_key}: Incorrect type {actual_type} instead of {expected_type}.'
                    )

                handler_return, handler_msg = handler(pvalue, *args)
                if not handler_return:
                    raise ParseError(
                        f'{program_name}: {parameter_key}: {handler_msg}.')

                if transform is not None:
                    self.configuration['programs'][program_name][
                        parameter_key] = transform(pvalue)