def do(self):
        """
        Install products by tornado  worker
        """

        parameters = None
        dm = DependencyManager()
        product_flat_list = [
            dm.get_dependencies(product_name)
            for product_name in self.product_names
        ]
        product_list = InstallCommand.flat_deps4products(
            product_flat_list, False)

        if self.args_parameters.yml_params:

            parameters = ParametersParserYmlFile(
                self.args_parameters.yml_params).get()

        elif self.args_parameters.json_params:

            parameters = ParametersParserJsonFile(
                self.args_parameters.json_params).get()

        elif self.args_parameters.parameters:

            parameters = ParametersParserStr(
                self.args_parameters.parameters).get()

        else:
            # then fill with empty params
            parameters = EmptyParameters().get(product_list)

        # добывает список продуктов из списка имён
        products = ProductCollection(product_list,
                                     feeds=(self.core.feed, self.core.current),
                                     ready_json=True)
        # парсим параметры установки из запроса
        # создаём менеджер параметров
        parameter_manager = ParametersManager(self.core, products, parameters)
        # все ли параметры заполнены?
        if parameter_manager.are_all_parameters_filled():

            # TODO move TornadoWorker to core
            # create tornado worker
            web.taskqueue.tornado_worker.TornadoWorker.create_instance()

            # всё ок, создаём задание на установку
            task = TaskFactory.create_task("install", products,
                                           parameter_manager)
            task_id = TaskManager.queue_task(task)
            callback_exit = lambda job, exit_code: InstallCommand.console_exit(
                self, job, exit_code)
            TornadoWorker.start_new_task(task, callback_exit, False)
            core.core.core_event_loop_start()
        else:
            raise InstallCommandError("Not all parameters specified")
def upgrade(request):
    """
    Обрабатывает запросы на апгрейд продуктов.
    Форматы входных запросов и выходных ответов такие же как для install()
    """
    if request.method != 'POST':
        # принимаем только пост-запросы
        return HttpResponseNotAllowed(['POST'])

    # парсим джейсон запрос
    req = json_request(request)
    initial = 'initial' in req
    dm = DependencyManager()
    requested_products = req['requested_products']
    core = Core.get_instance()
    if initial:
        # если это начальный запрос, то отдаем дерево зависимостей
        resp = {
            'task':
            None,
            'items': [
                dm.get_dependencies(product_name)
                for product_name in requested_products
            ]
        }
    else:
        # это запрос на апгрейд
        # список имён продуктов, которые нужно апгрейдить (с зависимостями)
        product_list = [item['product'] for item in req['install_products']]
        product_list.reverse()
        # добывает спсисоко продуктов из списка имён
        products = ProductCollection(product_list)
        parsed_parameters = ParametersParserJson(req['install_products']).get()
        # создаём менеджер параметров
        parameter_manager = ParametersManager(core, products,
                                              parsed_parameters)
        # создаёт задачу на апгрейд
        task = TaskFactory.create_task("upgrade", products, parameter_manager)
        task_id = TaskManager.queue_task(task)
        TornadoWorker.start_new_task(task)
        resp = {
            'task': {
                'id': task_id,
            },
            'items': None
        }

    return resp
Beispiel #3
0
    def get_dependencies(self, product_name):
        """
        найти зависомости для продукта

        :param product_name:
        :return: :raise Exception:
        """
        if not isinstance(product_name, str):
            raise Exception("Expected string. got '{0}'".format(product_name))

        product = Core.get_instance().feed.get_product(product_name)
        result = dict()
        if product is None:
            raise DependencyException(
                "We cant't find the product '{0}'".format(product_name),
                product_name)

        result["product"] = product.to_dict(True)

        parameter_manager = ParametersManager(self.core, [product])
        result['parameters'] = [
            product_parameter.to_dict()
            for product_parameter in parameter_manager.get_for_product(product)
        ]
        if product.is_installed():
            result['can_upgrade'] = bool(product.upgrade_command)
            result[
                'last_version'] = product.version == product.get_installed_version(
                )
        else:
            result['can_upgrade'] = True
            result['last_version'] = False

        dependencies = product.get_dependencies()
        if isinstance(product, Application):
            # if application we generate dependency from spec params
            engines = []
            databases = []
            dependencies = []
            for i in product.engines:
                engines.append(i['engine'])

            if product.database_type is not None:
                for i in product.database_type:
                    databases.append(i)
                databases_deps = databases[0]
                if len(databases) > 1:
                    databases_deps = OrderedDict()
                    databases_deps["or"] = databases

                dependencies.append(databases_deps)

            engines_deps = engines[0]
            if len(engines) > 1:
                engines_deps = OrderedDict()
                engines_deps["or"] = engines

            dependencies.append(engines_deps)

        if dependencies is None or len(dependencies) == 0:
            return result

        result["and"] = self._get_dependencies_for_node(dependencies)

        return result
def install(request):
    """
    Этот вызов используется для передать в веб-интерфейс дерево зависимостей
    и принять от него запрос на установку.
    Примеры запросов и ответов:

    начальный запрос:
    command: "start"
    requested_products: [JavaJettyTemplate]

    ответ:
    task:
      id: 168
      url: /task/168/
    items:
      paramters: [...]
      product:
        name: ...
        title: ...
      and:
      - item 1...
      - item 2...
    """
    # TODO do not give ability to install application through this function
    if request.method != 'POST':
        # принимаем только пост-запросы
        resp = HttpResponseNotAllowed(['POST'])
        return resp

    # джейсон запрос в питоний словарь
    req = json_request(request)
    # это начальный запрос?
    dm = DependencyManager()
    core = Core.get_instance()

    # продукты, которые запрошены на установку (без зависимостей)
    requested_products = req['requested_products']

    if req["command"] == "start":
        # если это начальный запрос, то отдаем дерево зависимостей
        resp = {
            'task':
            None,
            "state":
            "requirements",
            'items': [
                dm.get_dependencies(product_name)
                for product_name in requested_products
            ]
        }
    else:
        # это запрос на установку
        # список имён продуктов, которые нужно установить
        # ВАЖНЫЙ МОМЕНТ (с зависимостями)
        product_list = [item['product'] for item in req['install_products']]
        # переворачиваем его
        product_list.reverse()
        # добывает спсисоко продуктов из списка имён
        products = ProductCollection(product_list,
                                     feeds=(core.feed, core.current))
        # парсим параметры установки из запроса
        parsed_parameters = ParametersParserJson(req['install_products']).get()
        # создаём менеджер параметров
        parameter_manager = ParametersManager(core, products,
                                              parsed_parameters)
        # все ли параметры заполнены?
        if parameter_manager.are_all_parameters_filled():
            # всё ок, создаём задание на установку
            task = TaskFactory.create_task("install", products,
                                           parameter_manager)
            task_id = TaskManager.queue_task(task)
            TornadoWorker.start_new_task(task)
            # и готовим ответ веб-интерфейсу, что уставнока началась
            resp = {
                'task': {
                    'id': task_id,
                },
            }
        else:
            # что-то не так с параметрами, возвращаем в веб морду ошибку
            resp = {
                'task':
                None,
                'items': [
                    dm.get_dependencies(product_name)
                    for product_name in req['requested_products']
                ],
                'error':
                [parameter_manager.get_error(product) for product in products]
            }

    return resp