Esempio n. 1
0
 def __init__(self, config: MasterConfig) -> None:
     self.config = config
     self.backend = MasterBackends(config.plugins.backends_dir).construct_backend(config.backend,
                                                                                  config.backend_config)
     self.engine = Engine(self.backend)
     self.scheduler = Scheduler(self.backend, self.engine)
Esempio n. 2
0
class MasterApp:
    def __init__(self, config: MasterConfig) -> None:
        self.config = config
        self.backend = MasterBackends(config.plugins.backends_dir).construct_backend(config.backend,
                                                                                     config.backend_config)
        self.engine = Engine(self.backend)
        self.scheduler = Scheduler(self.backend, self.engine)

    def shutdown(self):
        self.scheduler.shutdown()

    @staticmethod
    def ping(*args):
        return ResultOk('pong')

    def list_graphs(self, args: dict, request: Request):
        graph_name = args.get('graph_name', None)
        with_info = (args.get('with_info', '1') == '1')
        limit = int(args.get('limit', '-1'))
        offset = int(args.get('offset', '0'))
        it = islice(self.backend.list_graph_struct(graph_name=graph_name, with_info=with_info),
                    offset, offset + limit if limit >= 0 else None)
        return ResultOk([
            graph_struct.to_json() if graph_struct else {'graph_name': graph_name, 'revision': revision}
            for graph_name, revision, graph_struct in it
        ])

    def create_graph(self, args: dict, request: Request):
        graph_name = request.match_info.get('graph_name', args.get('graph_name', None))
        if not graph_name:
            return ResultError(error='Graph name should be non-empty string')
        rev = self.engine.add_graph_struct(graph_name=graph_name, graph_struct=args)
        return ResultOk({'graph_name': graph_name, 'revision': rev})

    def read_graph(self, args: dict, request: Request):
        graph_name = request.match_info.get('graph_name', None)
        revision = int(request.match_info.get('revision', args.get('revision', -1)))
        if not graph_name:
            return ResultError(error='graph_name should be set')
        try:
            graph_struct = self.backend.read_graph_struct(graph_name, revision)
            return ResultOk(graph_struct.to_json())
        except KeyError:
            return ResultNotFound(error='Graph with revision not found', name=graph_name, revision=revision)
        except GraphStructureNotFound as ex:
            return ResultNotFound(error=str(ex), name=graph_name)

    def launch_graph(self, args: dict, request: Request):
        graph_name = request.match_info.get('graph_name', None)
        revision = int(request.match_info.get('revision', -1))
        if not graph_name:
            return ResultError(error='graph_name should be set')
        graph_struct = self.backend.read_graph_struct(graph_name, revision)
        return ResultOk(self.engine.add_graph_instance(uuid4().hex, graph_struct).to_json())

    def list_instances(self, args: dict, request: Request):
        with_info = (args.get('with_info', '1') == '1')
        limit = int(args.get('limit', '-1'))
        offset = int(args.get('offset', '0'))
        it = islice(self.backend.list_graph_instance_info(with_info=with_info),
                    offset, offset + limit if limit >= 0 else None)
        return ResultOk([
            instance_info.to_json() if instance_info else {'instance_id': instance_id}
            for instance_id, instance_info in it
        ])

    def read_instance(self, args: dict, request: Request):
        instance_id = request.match_info.get('instance_id', None)
        if not instance_id:
            return ResultError(error='Instance id should be set')
        try:
            return ResultOk(self.backend.read_graph_instance_info(instance_id).to_json())
        except KeyError:
            return ResultNotFound(error='Instance with needed id is not found', instance_id=instance_id)

    def start_instance(self, args: dict, request: Request):
        instance_id = request.match_info.get('instance_id', None)
        if not instance_id:
            return ResultError(error='instance_id field should be set')
        return self._set_instance_state(instance_id, GraphInstanceState.running)

    def stop_instance(self, args: dict, request: Request):
        instance_id = request.match_info.get('instance_id', None)
        if not instance_id:
            return ResultError(error='instance_id field should be set')
        return self._set_instance_state(instance_id, GraphInstanceState.stopped)

    def _set_instance_state(self, instance_id: str, instance_state_name: str):
        prev_state = self.engine.set_graph_instance_state(instance_id, instance_state_name)
        return ResultOk(prev_state=prev_state, new_state=instance_state_name)

    # TODO: move this proxy to storage layer
    def instance_logs(self, args: dict, request: Request):
        instance_id = request.match_info.get('instance_id', None)
        task_name = request.match_info.get('task_name', None)
        host = request.match_info.get('host', None)
        log_type = request.match_info.get('log_type', None)
        if not instance_id or not task_name or not host or not log_type:
            return ResultError(error='All fields from (instance_id, task_name, host, log_type) should be set')
        if log_type not in ('err', 'out'):
            return ResultError(error='Log type can be only from (err, out)')
        info = self.backend.read_graph_instance_info(instance_id)
        task_info = info.exec_stats.per_task_execution_info.get(task_name)
        if not task_info:
            return ResultNotFound(error='Graph instance doesn\'t have task with this name',
                                  instance_id=instance_id, task_name=task_name)
        host_info = task_info.per_host_info.get(host)
        if not host_info or not host_info.task_id:
            return ResultNotFound(error='Specified task doesn\'t have an execution entry on specified host',
                                  instance_id=instance_id, task_name=task_name, host=host)
        # FIXME: Port is not passed
        return ResultOk(instance_id=instance_id, task_name=task_name, host=host, log_type=log_type,
                        data=WorkerApiClient(worker_host=host).get_task_log(host_info.task_id, log_type))