/
opt
/
cloudlinux
/
venv
/
lib
/
python3.11
/
site-packages
/
clwizard
/
modules
/
Upload Filee
HOME
# coding=utf-8 # # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2021 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENCE.TXT # import os from collections import OrderedDict from typing import Dict # NOQA from clwizard.config import NoSuchModule, acquire_config_access from clwizard.constants import ModuleStatus, MAIN_LOG_PATH from clwizard.exceptions import InstallationFailedException, UserInterventionNeededError from clwizard.utils import setup_logger from .base import WizardInstaller # NOQA from .cagefs import CagefsInstaller from .governor import GovernorInstaller from .nodejs import NodejsInstaller from .php import PhpInstaller from .python import PythonInstaller from .ruby import RubyInstaller from .lsapi import LsapiInstaller # order of modules is important # add new modules in correct order ALL_MODULES = OrderedDict([ ('cagefs', CagefsInstaller), ('mysql_governor', GovernorInstaller), ('nodejs', NodejsInstaller), ('php', PhpInstaller), ('python', PythonInstaller), ('ruby', RubyInstaller), ('mod_lsapi', LsapiInstaller), # add other modules here ]) log = setup_logger('wizard.runner', MAIN_LOG_PATH) def get_supported_modules(): """Get list of supported modules on current control panel""" return { name: module for name, module in ALL_MODULES.items() if module.is_supported_by_control_panel() } def run_installation(): """Install modules according to settings in status file""" log.info('~' * 60) log.info('> Start new modules installation in process with pid %s', os.getpid()) for name, installer_class in get_supported_modules().items(): installer = installer_class() # we should re-read config each time in order to be able to 'cancel' with acquire_config_access() as config: try: options = config.get_module_options(module_name=name) state = config.get_module_status(module_name=name) except NoSuchModule: log.info( "Module %s is not set for installation, skip it", name) continue # 'resume case' when we should skip already installed modules if state == ModuleStatus.INSTALLED: log.info( "Module %s is already installed, skip it", name) continue if state == ModuleStatus.CANCELLED: log.info( "Module %s has been cancelled, skip it", name) continue if state == ModuleStatus.AUTO_SKIPPED: log.info( "Module %s requires a manual installation. " "Skipping it and continuing installation", name) continue config.set_module_status( module_name=name, new_state=ModuleStatus.INSTALLING) _install_module(name, installer, options=options) log.info('> Process with pid %s successfully finished work', os.getpid()) log.info('-' * 60) def _install_module(module, installer, options): # type: (str, WizardInstaller, Dict) -> None log.info("Installing module: %s", module) try: installer.run_installation(options) except InstallationFailedException: _write_module_state_atomic( module_name=module, new_state=ModuleStatus.FAILED) log.error( "Installation failed for module %s", module, extra={ 'fingerprint': ['{{ default }}', module], # Used to group and break up events 'data': {'options': str(options)}}) # Additional data for sentry event raise except UserInterventionNeededError: _write_module_state_atomic( module_name=module, new_state=ModuleStatus.AUTO_SKIPPED) log.warning("Automatic installation was skipped for module %s", module) except Exception as err: _write_module_state_atomic( module_name=module, new_state=ModuleStatus.FAILED) log.error("Installation failed for module %s", module) installer.app_logger.exception( "Unknown error occurred, please, retry " "or contact CloudLinux support if it happens again." "\n\nError: %s", str(err), extra={ # Used to group and break up events 'fingerprint': ['{{ default }}', module, str(err)[:25]], # Additional data for sentry event 'data': {'options': str(options)} }) raise InstallationFailedException() from err else: _write_module_state_atomic( module_name=module, new_state=ModuleStatus.INSTALLED) log.info("Module '%s' successfully installed " "using options '%s'", module, options) def _write_module_state_atomic(module_name, new_state): # type: (str, str) -> None with acquire_config_access() as config_access: config_access.set_module_status(module_name=module_name, new_state=new_state)