def has_upgrade(request): """ Возвращает новую версию зу инсталера, на которую можно обновиться. """ return { 'version': Core.get_instance().has_upgrade() if Core.get_instance() else None }
def logs_clear(request): """ Очищает директорию логов. """ Core.get_instance().clear_logs() return { 'size': Core.get_instance().get_logs_size() }
def sync_core(): """ После каждой установки выполнить sync чтобы current.yaml был в актуальном сосотоянии """ logging.debug('start core updating after install process finished') Core.get_instance().set_expired(True) Core.get_instance().update()
def cache_clear(request): """ Очищает директорию кеша. """ Core.get_instance().clear_cache() return { 'size': Core.get_instance().get_cache_size() }
def command_upgrade(params): state = params["params"] # check self upgrading if "product" in state["products"][0] and state["products"][0]["product"] == core.version.NAME: Core.get_instance().upgrade(state['products'], state.get('parameters'), True) raise SelfUpgradeException("Helicon Zoo is upgrading yourself", params["parent_pid"]) else: return Core.get_instance().upgrade(state['products'], state.get('parameters'), True)
def command_upgrade(params): state = params["params"] # check self upgrading if "product" in state["products"][0] and state["products"][0][ "product"] == core.version.NAME: Core.get_instance().upgrade(state['products'], state.get('parameters'), True) raise SelfUpgradeException("Helicon Zoo is upgrading yourself", params["parent_pid"]) else: return Core.get_instance().upgrade(state['products'], state.get('parameters'), True)
def create_uninstall_task(self, products: ProductCollection): """ фабричный метод: создать такс с переданными параметрами, с типом COMMAND_UNINSTALL сохранить в базе данных зхапустить воркер :param requested_products: :param products: :param parameter_manager: :return: """ title = 'Uninstalling products: {0}'.format(', '.join([product.title for product in products])) state = { 'products': products.get_names_list(), } settings = Core.get_instance().settings.get_state() task = Task( command=Task.COMMAND_UNINSTALL, title=title, params=json.dumps(state, sort_keys=True, indent=1), settings=json.dumps(settings, sort_keys=True, indent=1)) task.save() self.task = task self.run_worker(task.id) return task.id
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: result["product"] = "None" return result result["product"] = product.to_dict(True) parameter_manager = ParametersManager([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 dependencies is None or len(dependencies) == 0: return result result["and"] = self._get_dependencies_for_node(dependencies) return result
def create_upgrade_task(self, requested_products: list, products: ProductCollection): """ фабричный метод: создать такс с переданными параметрами, с типом COMMAND_UPGRADE сохранить в базе данных зхапустить воркер :param requested_products: :param products: :param parameter_manager: :return: """ title = 'Upgrading products: {0}'.format(', '.join([product_name for product_name in requested_products])) state = { 'requested_products': requested_products, 'products': products.get_names_list(), 'parameters': {} } settings = Core.get_instance().settings.get_state() logging.debug('state: {0}'.format(state)) task = Task( command=Task.COMMAND_UPGRADE, title=title, params=json.dumps(state, sort_keys=True, indent=1), settings=json.dumps(settings, sort_keys=True, indent=1) ) task.save() # production # For debug worker uncomment this #self.task.execute() return task.id
def logs(request): """ Возвращает размер директории логов. """ return { 'size': Core.get_instance().get_logs_size() }
def __init__(self, path, engine, callback_exit): """ подготовить окружение к запуску дочернего процесса нужно - загрузить .zoo - найти на каком энжайне он работает - найти энжайн - взять текущие переменные окружения - взять переменные окружения энжайна - взять переменные окружения .zoo - раскрыть все переменные окружения запустить дочерний процесс :param path: """ self.updated = None self.path = path self.core = Core.get_instance() self.buffer = [] self.env = os.environ.copy() self.physical_path = self.core.api.os.web_server.map_webserver_path(self.path) if self.physical_path: self.site_root = self.core.api.os.web_server.siteroot4path(self.physical_path) self.app_physical_path = self.core.api.os.web_server.find_app_physical_path(self.physical_path, self.site_root) if self.app_physical_path: self.zoo_config = self.core.api.os.web_server.get_zoo_config(self.app_physical_path) # emulate zoo module variables self.env["INSTANCE_ID"] = "0" self.env["APPL_PHYSICAL_PATH"] = self.app_physical_path self.env["APPL_PHYSICAL_SHORT_PATH"] = self.core.api.os.shell.get_short_path_name(self.app_physical_path) self.env["APPL_VIRTUAL_PATH"] = self.app_physical_path self.env["APPL_ID"] = self.env["APPL_VIRTUAL_PATH"].replace("/", "") std_console = self.env.copy() if self.zoo_config: try: zoo_env = self.core.api.os.web_server.create_environment(self.zoo_config, std_console, engine) self.env = zoo_env except Exception as e: logging.debug(" cant create environment from zoo file") logging.debug(e) logging.debug(traceback.format_exc()) notes = str(e) + "\n" # we try to create console porcess in any case of errors else: # IT'S IMPORTANT FRO SECURITY REASONS raise Exception("There is no settings for this path {0}".format(path)) self.pipe_stdin = None self.pipe_stdout = None self.pipe_stderr = None self.proc = None self.connection = None self.callback_exit=callback_exit self.on_callback_exit=None self.__start_process()
def cache(request): """ Возвращает размер директории кеша. """ return { 'size': Core.get_instance().get_cache_size() }
def icon(request, product_name): """ Возвращает иконку (бинарное содерживое файла) для продукта """ # находим путь к иконке core = Core.get_instance() product = core.feed.get_product(product_name) icon_path = product.icon if not icon_path: raise Http404() # если путь урл — отсылаеи редирект if icon_path.startswith('http'): return HttpResponseRedirect(icon_path) if not os.path.exists(icon_path): # такого пути нет - 404 raise Http404() # получаем миме-тип иконки mimetype = mimetypes.guess_type(os.path.basename(icon_path))[0] # читаем содержимое файла иконки with open(icon_path, 'rb') as fh: response = HttpResponse(body=fh.read()) # ставим кеширующий хидер response["Content-Type"] = mimetype response['Cache-Control'] = 'public,max-age=3600' return response
def __init__(self, product_names: list=None, feed=None, feeds=None, ready_json=False, fail_on_product_not_found=True ): """ :type feed: Feed :param product_names: string list of product names :param feed: core.storage.feed for installed products (uninstall process), core.feed for all products """ from core.core import Core self.core = Core.get_instance() self.feeds = [] if feed: self.feeds.append(feed) if feeds: self.feeds.extend(feeds) if len(self.feeds) == 0: self.feeds.append(self.core.feed) self.fail_on_product_not_found = fail_on_product_not_found self.coll = [] if ready_json: for dict_product in product_names: self.add_product_from_json(dict_product) else: if product_names : for name in product_names: self.add_by_name(name)
def create_install_task(products: ProductCollection, parameter_manager: ParametersManager): """ фабричный метод: создать такс с переданными параметрами, с типом COMMAND_INSTALL сохранить в базе данных зхапустить воркер :param products: продукты для установки (продукты которые выбрал пользователь + зависимости) :param parameter_manager: :return: номер таска """ settings = json_encode(Core.get_instance().settings.get_state()) job_array = [] task_object = TaskDataModel(command="install", settings=settings) for product in products: title = product.title state = { 'products': [product.to_dict()], 'parameters': parameter_manager.get_state() } state2save = json_encode(state) job = JobDataModel( command=JobDataModel.COMMAND_INSTALL, title=title, params=state2save, task=task_object, settings=settings ) job_array.append(job) task = Task(task_model=task_object, jobs=job_array) return task
def create_uninstall_task(products: ProductCollection): """ фабричный метод: создать такс с переданными параметрами, с типом COMMAND_UNINSTALL сохранить в базе данных зхапустить воркер :param requested_products: :param products: :param parameter_manager: :return: """ job_array = [] settings = json_encode(Core.get_instance().settings.get_state()) task_object = TaskDataModel(command="uninstall", settings=settings) for product in products: state = { 'products': [product.name], } job = JobDataModel( command=JobDataModel.COMMAND_UNINSTALL, title=product.title, params=json_encode(state), settings=settings) job_array.append(job) task = Task(task_model=task_object, jobs=job_array) return task
def create_upgrade_task(products: ProductCollection, parameter_manager: ParametersManager): """ фабричный метод: создать такс с переданными параметрами, с типом COMMAND_UPGRADE сохранить в базе данных зхапустить воркер :param products: :param parameter_manager: :return: """ settings = json_encode(Core.get_instance().settings.get_state()) job_array = [] task_object = TaskDataModel(command="upgrade", settings=settings) for product in products: title = product.title state = { 'products': [product.to_dict()], 'parameters': parameter_manager.get_state() } state2save = json_encode(state) job = JobDataModel( command=JobDataModel.COMMAND_UPGRADE, title=title, params=state2save, task=task_object, settings=settings ) job_array.append(job) task = Task(task_model=task_object, jobs=job_array) return task
def start_new_task(task, user_proc_exit_cb=None, save_buffer=True): worker = TornadoWorker.get_instance() logging.debug("we have new job to start %s" % str(task)) core = Core.get_instance() new_job = Job.create_job(task, core) logging.debug(new_job) if new_job.task_id not in worker.pool["buffer"]: worker.pool["buffer"][new_job.task_id] = [] task.update(status=JobDataModel.STATUS_RUNNING) proc_exit_cb = None if user_proc_exit_cb: proc_exit_cb = lambda job, exit_code: TornadoWorker.process_finished( worker, job, exit_code, user_proc_exit_cb) else: proc_exit_cb = lambda job, exit_code: TornadoWorker.process_finished( worker, job, exit_code) read_logs = None if save_buffer: read_logs = lambda lines, log_level: TornadoWorker.async_read_logs( worker, new_job, lines, log_level) else: read_logs = lambda lines, log_level: TornadoWorker.async_write_logs2stdout( worker, new_job, lines, log_level) job_log_manager = LogManager(core) new_job.start_job_async(job_log_manager, proc_exit_cb, read_logs)
def install_application(request, app_name): """ Этот вызов используется для передать в веб-интерфейс дерево зависимостей для первого шага install application Возвращает продукты необходимые для установки Application для запуска инсталяции используется стандартный вызов install Примеры запросов и ответов: начальный запрос: """ req = json_request(request) # это начальный запрос? dm = DependencyManager() core = Core.get_instance() # продукты, которые запрошены на установку (без зависимостей) requested_products = [app_name] if len(requested_products) > 1: raise RuntimeError("You are able to install only one application") application_item = [ dm.get_dependencies(product_name) for product_name in requested_products ] resp = {'task': None, "state": "requirements", 'items': application_item} return resp
def product_list(request): """ Получить список продуктов с учетом фильтров filter - тип продукта, product, application, engine installed - установлен или нет q - строка поиска :param request: :return: """ product_filter = request.GET.get('filter', None) installed_filter = request.GET.get('installed', None) if installed_filter is not None: installed_filter = int(installed_filter) q = request.GET.get('q', None) core = Core.get_instance() core.update() if q: q = urllib.parse.unquote_plus(q) products = core.feed.dump_products(core.feed.search_products(q)) else: products = core.feed.dump_products( core.feed.filter_products(product_filter, installed_filter)) return products
def __init__(self, product_names, args_parameters=None): if not product_names: raise UninstallCommandError('no products specified') self.core = Core.get_instance() self.product_names = product_names self.args_parameters = args_parameters
def uninstall_program(program, log_path, version=None, ignore_exit_code=False, no_wait=False): """ Uninstall MSI by program name :param program: object of type InstalledProductInfo() :param version: program version to uninstall :param log_path: :param ignore_exit_code: :return: """ if program.guid is None: raise Exception("Can't uninstall program. No program.guid.") command = r'msiexec.exe /norestart /q /X{0} /l! "{1}"'.format( program.guid, log_path) exit_code = Core.get_instance().api.os.shell.cmd(command, ignore_exit_code=True, no_wait=no_wait) if exit_code == 3010: # Reboot required code logging.warning( 'WARNING: Installation requested a system reboot.\nYou may need to reboot the system manually to complete this installation.' ) elif exit_code != 0 and not ignore_exit_code: # Other errors rise exception raise RuntimeError('Installation "{0}" failed: ({1}) {2}'.format( program.name, exit_code, win32api.FormatMessageW(exit_code))) return exit_code
def install(filename, log_path, optional_parameters: dict = None, ignore_exit_code=False, no_wait=False): """ Install MSI with options :param filename: :param log_path: :param optional_parameters: :param ignore_exit_code: :param no_wait: """ command = r'msiexec.exe /norestart /q /i "{0}" /l! "{1}" ALLUSERS=1'.format( filename, log_path) if optional_parameters: for k, v in optional_parameters.items(): if v and v != "": command += ' {0}="{1}"'.format(k, v) exit_code = Core.get_instance().api.os.shell.cmd(command, ignore_exit_code=True, no_wait=no_wait) if exit_code == 3010: # Reboot required code logging.warning( 'WARNING: Installation requested a system reboot.\nYou may need to reboot the system manually to complete this installation.' ) elif exit_code != 0 and not ignore_exit_code: # Other errors rise exception raise RuntimeError('Installation "{0}" failed: ({1}) {2}'.format( filename, exit_code, win32api.FormatMessageW(exit_code))) return exit_code
def create_upgrade_task(products: ProductCollection, parameter_manager: ParametersManager): """ фабричный метод: создать такс с переданными параметрами, с типом COMMAND_UPGRADE сохранить в базе данных зхапустить воркер :param products: :param parameter_manager: :return: """ settings = json_encode(Core.get_instance().settings.get_state()) job_array = [] task_object = TaskDataModel(command="upgrade", settings=settings) for product in products: title = product.title state = { 'products': [product.to_dict()], 'parameters': parameter_manager.get_state() } state2save = json_encode(state) job = JobDataModel(command=JobDataModel.COMMAND_UPGRADE, title=title, params=state2save, task=task_object, settings=settings) job_array.append(job) task = Task(task_model=task_object, jobs=job_array) return task
def website_create(request): """ хендлер для запроса, создать сайт создает и возвращает сайт, или ошибка :param request: :return: """ if request.method != 'POST': return HttpResponseNotAllowed(['POST']) req = json_request(request) name = req['name'] ip_address = req['ip_address'] port = req['port'] hostname = req['hostname'] # 127.0.0.1:8085:localhost1.helicontech.com binding = 'http/{0}:{1}:{2}'.format(ip_address, port, hostname) core = Core.get_instance() try: path = core.api.os.web_server.create_physical_path_for_virtual_path( name) core.api.os.web_server.site_create(name, path, binding) website_object = core.api.os.web_server.get_site(name) response = {'error': None, 'website': website_object.to_dict()} except Exception as e: response = {'error': str(e), 'website': None} return response
def load_yaml(self): logging.debug("Loading from '{0}'".format(self.url)) try: headers = { 'User-Agent': 'Zoo Agent {0}; {1}'.format( VERSION, Core.get_instance().settings.get_platform().__repr__()) } req = request.Request(self.url, headers=headers) stream = request.urlopen(req) # stream = request.urlopen(self.url, headers = headers) except Exception as ex: raise RuntimeError('Could not load url {0}'.format( self.url)) from ex # TODO move to yaml_helper items = yaml.load( stream, # TODO: read Last-Modified header yaml_loader.YamlLoader) self.patch_file_path(items) if items is None: items = [] return items
def install_application(request, app_name): """ Этот вызов используется для передать в веб-интерфейс дерево зависимостей для первого шага install application Возвращает продукты необходимые для установки Application для запуска инсталяции используется стандартный вызов install Примеры запросов и ответов: начальный запрос: """ req = json_request(request) # это начальный запрос? dm = DependencyManager() core = Core.get_instance() # продукты, которые запрошены на установку (без зависимостей) requested_products = [app_name] if len(requested_products) > 1: raise RuntimeError("You are able to install only one application") application_item = [dm.get_dependencies(product_name) for product_name in requested_products] resp = {'task': None, "state": "requirements", 'items': application_item} return resp
def test_match_product(self): p = Product(core=Core.get_instance()) p.merge(product="Zoo", version="4.0") self.assertTrue(ProductComparer("zoo>3.0.0.1").match('zoo', '4.0')) self.assertFalse(ProductComparer("zoo>4.0").match('zoo', '4.0')) self.assertFalse(ProductComparer("foo>3.0").match('zoo', '4.0'))
def __init__(self, product_names: list = None, feed=None, feeds=None, ready_json=False, fail_on_product_not_found=True): """ :type feed: Feed :param product_names: string list of product names :param feed: core.storage.feed for installed products (uninstall process), core.feed for all products """ from core.core import Core self.core = Core.get_instance() self.feeds = [] if feed: self.feeds.append(feed) if feeds: self.feeds.extend(feeds) if len(self.feeds) == 0: self.feeds.append(self.core.feed) self.fail_on_product_not_found = fail_on_product_not_found self.coll = [] if ready_json: for dict_product in product_names: self.add_product_from_json(dict_product) else: if product_names: for name in product_names: self.add_by_name(name)
def __init__(self, *args): self.web_frontend_url = "http://127.0.0.1:7799/api/1/core/sync/" self.process = None self.logger = None self.timer_read_log = None self.timer_check_logdir = None self.check_new_tasks = None self.decoder = OutputDecoder() # TODO remove port from code self.port = 7798 self.logger = logging.getLogger() self.log_reader = None # remove all handlers self.logger.handlers = [] # add only db handler self.core = Core.get_instance() self.configs = { 'max_messages_per': 100, "queue": Queue(), 'buffer': 1, 'sessions': {}, "state": "reading", 'status_done': False, 'task': None } self.application = tornado.web.Application([ (r"/socket/log", WebSocketHandler, {"configs": self.configs}), (r"/test", MainHandler, {"configs": self.configs}) ])
def cmd(command, ignore_exit_code=False, envs=None, no_wait=False): """ Run command via subprocess and return exit code """ logging.info('> {0}'.format(command)) # This code is needed to start 64-bit version of cmd.exe on 64-bit os. # Not sure yet which version is correct if platform.machine().find('64') > 0 and not sys.maxsize > 2**32: executable = '{0}\Sysnative\cmd.exe /C "{1}"'.format(os.getenv('SystemRoot'), command) else: executable = '{0}\System32\cmd.exe /C "{1}"'.format(os.getenv('SystemRoot'), command) if not envs: envs = os.environ envs['PATH'] = Core.get_instance().expandvars(envs['PATH']) # exit_code = subprocess.check_call(executable, env=envs, stdout=sys.stdout, stderr=sys.stderr, shell=True) process = subprocess.Popen(executable, env=envs, stdout=sys.stdout, stderr=sys.stderr) # exit if do not need to wait process if no_wait: return 0 process.wait() exit_code = process.returncode if exit_code != 0 and not ignore_exit_code: try: str_error = os.strerror(exit_code) except (OverflowError, ValueError): str_error = "" # raise error if exit code is not 0 raise RuntimeError('Execute of command "{0}" failed: ({1}) {2}'.format(command, exit_code, str_error )) return exit_code
def create_install_task(products: ProductCollection, parameter_manager: ParametersManager): """ фабричный метод: создать такс с переданными параметрами, с типом COMMAND_INSTALL сохранить в базе данных зхапустить воркер :param products: продукты для установки (продукты которые выбрал пользователь + зависимости) :param parameter_manager: :return: номер таска """ settings = json_encode(Core.get_instance().settings.get_state()) job_array = [] task_object = TaskDataModel(command="install", settings=settings) for product in products: title = product.title state = { 'products': [product.to_dict()], 'parameters': parameter_manager.get_state() } state2save = json_encode(state) job = JobDataModel(command=JobDataModel.COMMAND_INSTALL, title=title, params=state2save, task=task_object, settings=settings) job_array.append(job) task = Task(task_model=task_object, jobs=job_array) return task
def create_uninstall_task(products: ProductCollection): """ фабричный метод: создать такс с переданными параметрами, с типом COMMAND_UNINSTALL сохранить в базе данных зхапустить воркер :param requested_products: :param products: :param parameter_manager: :return: """ job_array = [] settings = json_encode(Core.get_instance().settings.get_state()) task_object = TaskDataModel(command="uninstall", settings=settings) for product in products: state = { 'products': [product.name], } job = JobDataModel(command=JobDataModel.COMMAND_UNINSTALL, title=product.title, params=json_encode(state), settings=settings) job_array.append(job) task = Task(task_model=task_object, jobs=job_array) return task
def update(request): """ Запускает апгрейд ядра и редиректит на главную, где показывает процесс создания нового ядра. """ core = Core.get_instance() core_loader = CoreLoader.get_instance() core_loader.restart(core.settings) return HttpResponseRedirect("/")
def check_webserver_installed(req): core = Core.get_instance() server = core.platform.web_server if not isinstance(core.api.os.web_server, NoWebServer): if server == "iisexpress" or server == "iis": if os.path.exists(core.api.os.web_server.APP_CMD): return {"status": True, "server": server} return {"status": False, "server": server}
def pool_list(request): """ Хендлер. Получить список пулов ииса :param request: :return: """ core = Core.get_instance() pools = core.api.os.web_server.get_app_pool_list() return [pool.to_dict() for pool in pools]
def __init__(self, *kargs, **kargws): self.path = kargws["path"] self.task_id = kargws["task_id"] self.working_path = InstallLogReader.generate_path_name(self.path, self.task_id) self.watching_list = {} self.last_modified = None self.core = Core.get_instance() if not self.core.api.os.shell.ensure_exists(self.working_path): self.core.api.os.shell.make_dir(self.working_path)
def __init__(self, path): """ подготовить окружение к запуску дочернего процесса нужно - загрузить .zoo - найти на каком энжайне он работает - найти энжайн - взять текущие переменные окружения - взять переменные окружения энжайна - взять переменные окружения .zoo - раскрыть все переменные окружения запустить дочерний процесс :param path: """ self.path = path self.core = Core.get_instance() self.physical_path = self.core.api.os.web_server.map_webserver_path(self.path) self.zoo_config = self.core.api.os.web_server.get_zoo_config(self.physical_path) self.env = os.environ.copy() # emulate zoo module variables self.env["INSTANCE_ID"] = "0" self.env["APPL_PHYSICAL_PATH"] = self.physical_path self.env["APPL_PHYSICAL_SHORT_PATH"] = self.core.api.os.shell.get_short_path_name(self.physical_path) self.env["APPL_VIRTUAL_PATH"] = self.path self.env["APPL_ID"] = self.env["APPL_VIRTUAL_PATH"].replace("/","") #self.env["IIS_BINDNGS"] = self.core.api.os.web_server.get_site() if self.zoo_config: if self.zoo_config['engine']: engine_config = self.core.engine_storage.get_product(self.zoo_config['engine']).config if engine_config: if 'environment_variables' in engine_config: engine_env = engine_config.get('environment_variables') self.update_env(self.env, engine_env) if 'environment_variables' in self.zoo_config: app_env = self.zoo_config.get('environment_variables') self.update_env(self.env, app_env) self.env = self.expand_variables_in_dict(self.env) self.process = None self.std_out = "" self.std_err = "" self.stdout_reader = None self.stderr_reader = None self.timestamp = 0 self.start()
def uninstall(filename, log_path, ignore_exit_code=False): """ Uninstall MSI with options :param filename: :param log_path: :param ignore_exit_code: :return: """ command = 'msiexec.exe /norestart /q /X "{0}" /log "{1}"'.format(filename, log_path) return Core.get_instance().api.os.shell.cmd(command, ignore_exit_code=ignore_exit_code)
def website_launch(request): core = Core.get_instance() sites = core.api.os.web_server.get_list_of_sites() req = json_request(request) name = req['sitename'] url = req['url'] if core.platform.web_server == "iisexpress": core.api.os.web_server.launch_iis_express(name) return {"status": True}
def website_list(request): """ хендлер для запроса, показать список сайтов. :param request: :return: """ core = Core.get_instance() sites = core.api.os.web_server.get_list_of_sites() return [site.to_dict() for site in sites]
def pool_list(request): """ Хендлер. Получить список пулов ииса :param request: :return: """ core = Core.get_instance() if hasattr(core.api.os.web_server, 'APP_CMD') and os.path.exists(core.api.os.web_server.APP_CMD): pools = core.api.os.web_server.get_app_pool_list() return [pool.to_dict() for pool in pools] return []
def pool_list(request): """ Хендлер. Получить список пулов ииса :param request: :return: """ core = Core.get_instance() if hasattr(core.api.os.web_server, 'APP_CMD') and os.path.exists( core.api.os.web_server.APP_CMD): pools = core.api.os.web_server.get_app_pool_list() return [pool.to_dict() for pool in pools] return []
def engine_list(request): """ Получить список энжайнов. :param request: :return: """ core = Core.get_instance() core.engine_storage.update() engines = core.engine_storage.feed.dump_products( core.engine_storage.feed.get_products()) return engines
def setUpClass(cls): cls.core = Core.get_instance() cls.core.feed.raw_collection.append(dict(product='x', os='windows', title='X')) cls.core.feed.raw_collection.append(dict(product='x', os='windows', bitness='64', version='1.3.5')) cls.core.feed.raw_collection.append(dict(product='x', os='windows', bitness='64', version='1.3.7')) cls.core.feed.raw_collection.append(dict(product='x', os='windows', bitness='64', version='1.3.9')) cls.core.feed.raw_collection.append(dict(product='y')) cls.core.feed.raw_collection.append(dict(product='y', os='windows', bitness='64', version='1.5.0')) cls.core.feed.raw_collection.append(dict(product='y', os='windows', bitness='64', version='1.5.2')) cls.core.feed.raw_collection.append(dict(product='y', os='windows', bitness='64', version='1.5.4'))
def server_root(request): """ хендлер для запроса, показать дочерние узлы для корня сервера, т.е. список сайтов :param request: :return: """ core = Core.get_instance() # list of sites return { 'node': core.api.os.web_server.get_server_node(), 'children': core.api.os.web_server.get_directories(None, None) }
def tag_list(request): """ Хендлер. получить список тегов. с учетом фильра 'q' и типа продукта 'filter' :param request: :return: """ product_filter = request.GET.get('filter', None) q = request.GET.get('q', None) core = Core.get_instance() if q: tags = core.feed.get_tags(core.feed.search_products(q)) else: tags = core.feed.get_tags(core.feed.filter_products(product_filter)) return tags
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
def website_list(request): """ хендлер для запроса, показать список сайтов. :param request: :return: """ core = Core.get_instance() if isinstance(core.api.os.web_server, NoWebServer): return [] if os.path.exists(core.api.os.web_server.APP_CMD): sites = core.api.os.web_server.get_list_of_sites() return [site.to_dict() for site in sites] else: return []
def uninstall(request): """ Обрабатывает запросы на деинсталляцию продуктов. """ if request.method != 'POST': # принимаем только пост-запросы return HttpResponseNotAllowed(['POST']) # парсим джейсон запрос req = json_request(request) # это начальный запрос ? # список имён продуктов для деинсталляции requested_products = req['requested_products'] # добываем список продуктов из списка имён products = ProductCollection( [product_name for product_name in requested_products], feed=Core.get_instance().current_storage.feed, # feed=Core.get_instance().feed, fail_on_product_not_found=False) if req["command"] == "start": # для начального запроса отдает список продуктов resp = { 'task': None, 'state': 'product_list', 'items': [{ 'product': product.to_dict(True), 'parameters': [], 'error': None } for product in products] } else: # создаём задачу на деинсталляцию task = TaskFactory.create_task("uninstall", products) task_id = TaskManager.queue_task(task) TornadoWorker.start_new_task(task) # и готовим ответ веб-интерфейсу, что уставнока началась resp = {'task': {'id': task_id}, "state": "uninstalling"} return resp
def __init__(self, path): """ подготовить окружение к запуску дочернего процесса нужно - загрузить .zoo - найти на каком энжайне он работает - найти энжайн - взять текущие переменные окружения - взять переменные окружения энжайна - взять переменные окружения .zoo - раскрыть все переменные окружения запустить дочерний процесс :param path: """ self.path = path self.core = Core.get_instance() self.physical_path = self.core.api.os.web_server.map_webserver_path(self.path) self.zoo_config = self.core.api.os.web_server.get_zoo_config(self.physical_path) self.env = os.environ.copy() # emulate zoo module variables self.env["INSTANCE_ID"] = "0" self.env["APPL_PHYSICAL_PATH"] = self.physical_path self.env["APPL_PHYSICAL_SHORT_PATH"] = self.core.api.os.shell.get_short_path_name(self.physical_path) self.env["APPL_VIRTUAL_PATH"] = self.path self.env["APPL_ID"] = self.env["APPL_VIRTUAL_PATH"].replace("/", "") if self.zoo_config: zoo_env = self.core.api.os.web_server.create_environment(self.zoo_config, self.env) self.env = zoo_env self.process = None self.pipe_stdin = None self.pipe_stdout = None self.pipe_stderr = None self.std_out = "" self.std_err = "" self.stdout_reader = None self.stderr_reader = None self.timestamp = 0 self.start()
def website_item(request, name): """ хендлер для запроса, узла дерева - сайт GET - получить дочерние узлы POST - обновить zoo_config с переданными значаниями :param request: :param name: :return: """ core = Core.get_instance() if request.method == 'POST': req = json_request(request) core.api.os.web_server.update_zoo_config(name, "/", req) return { 'node': core.api.os.web_server.get_site_node(name), 'children': core.api.os.web_server.get_directories(name, "/") }
def cmd(command, ignore_exit_code=False, envs=None, no_wait=False): """ Run command via subprocess and return exit code """ logging.info('> {0}'.format(command)) # This code is needed to start 64-bit version of cmd.exe on 64-bit os. # Not sure yet which version is correct if platform.machine().find('64') > 0 and not sys.maxsize > 2**32: executable = '{0}\Sysnative\cmd.exe /C "{1}"'.format( os.getenv('SystemRoot'), command) else: executable = '{0}\System32\cmd.exe /C "{1}"'.format( os.getenv('SystemRoot'), command) if not envs: envs = os.environ envs['PATH'] = Core.get_instance().expandvars(envs['PATH']) # exit_code = subprocess.check_call(executable, env=envs, stdout=sys.stdout, stderr=sys.stderr, shell=True) process = subprocess.Popen(executable, env=envs, stdout=sys.stdout, stderr=sys.stderr) # exit if do not need to wait process if no_wait: return 0 process.wait() exit_code = process.returncode if exit_code != 0 and not ignore_exit_code: try: str_error = os.strerror(exit_code) except (OverflowError, ValueError): str_error = "" # raise error if exit code is not 0 raise RuntimeError( 'Execute of command "{0}" failed: ({1}) {2}'.format( command, exit_code, str_error)) return exit_code