Mini Shell

Direktori : /opt/cloudlinux/venv/lib64/python3.11/site-packages/clwizard/modules/
Upload File :
Current File : //opt/cloudlinux/venv/lib64/python3.11/site-packages/clwizard/modules/__init__.py

# 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)

Zerion Mini Shell 1.0