%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /opt/cloudlinux/venv/lib/python3.11/site-packages/xray/manager/
Upload File :
Create Path :
Current File : //opt/cloudlinux/venv/lib/python3.11/site-packages/xray/manager/custom.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/LICENSE.TXT

"""
This module contains classes implementing X-Ray Manager behaviour
for custom integration
"""

from collections import ChainMap
from typing import Optional

from clcommon.cpapi.plugins.vendors import PublicApi
from xray import gettext as _
from xray.internal import phpinfo_utils

from .base import BaseManager
from ..internal.exceptions import XRayManagerError, XRayMissingDomain
from ..internal.types import DomainInfo
from ..internal.user_plugin_utils import (
    user_mode_verification,
    with_fpm_reload_restricted
)


class CustomManager(BaseManager):
    """
    Manager supporting integration scripts
    """
    VERSIONS_CUSTOM = {
        '54': None,
        '55': None,
        '56': None,
        '70': None,
        '71': None,
        '72': None,
        '73': None,
        '74': None,
        '80': None,
        '81': None,
        '82': None,
        '83': None
    }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.api = PublicApi()
        if self.is_xray_integrated:
            self.all_domains = self.get_all_domains()
        else:
            raise XRayManagerError(
                _('X-Ray is not supported by control panel vendor'))

    def supported_versions(self) -> ChainMap:
        """
        Get supported PHP versions
        :return: dict with custom supported versions
        """
        return ChainMap(self.VERSIONS,
                        self.VERSIONS_CUSTOM)

    @property
    def is_xray_integrated(self):
        """
        Check the X-Ray feature status through the panel_info script
        """
        _info = self.api.panel_info()  # PanelInfo instance
        features = _info.supported_cl_features
        if features is None:
            return True

        return features.get('xray', False)

    def get_all_domains(self) -> dict:
        """
        Collect domains from integration script
        """
        return self.api.domains(with_php=True)

    @user_mode_verification
    @with_fpm_reload_restricted
    def get_domain_info(self, domain_name: str) -> DomainInfo:
        """
        Retrieve PHP setting for given domain_name
        """
        try:
            domain_conf = self.all_domains[domain_name]  # DomainData instance
        except KeyError:
            self.logger.warning(
                'Domain does not exist on the server',
                extra={'domain_name': domain_name})
            raise XRayMissingDomain(domain_name)

        if self.phpinfo_mode:
            config = phpinfo_utils.get_php_configuration(
                domain_conf.owner,
                domain=domain_name)

            return DomainInfo(
                name=domain_name,
                panel_php_version=config.get_full_php_version(''),
                php_ini_scan_dir=config.absolute_ini_scan_dir,
                # indicates that there is no need to apply selector
                # and try to resolve php version, the one given in
                # php_version is final one
                is_selector_applied=True,
                user=domain_conf.owner,
                panel_fpm=config.is_php_fpm,
            )
        else:
            domain_info = DomainInfo(
                name=domain_name,
                user=domain_conf.owner,
                panel_php_version=domain_conf.php.version,
                panel_fpm=domain_conf.php.fpm,
                is_native=domain_conf.php.is_native,
                ini_path=domain_conf.php.ini_path
            )

        self.logger.info(
            'Retrieved domain info: domain %s owned by %s uses php version %s',
            domain_name, domain_info.user, domain_info.panel_php_version)
        return domain_info

    def panel_specific_selector_enabled(self, domain_info: DomainInfo) -> bool:
        """
        Check if selector is enabled specifically for custom panels
        Required to be implemented by child classes
        :param domain_info: a DomainInfo object
        :return: True if yes, False otherwise
        """
        return domain_info.is_native and not domain_info.panel_fpm

    def fpm_service_name(self, dom_info: DomainInfo) -> Optional[str]:
        """
        Retrieve FPM service name
        """
        return dom_info.panel_fpm

    def _ini_path(self, domain_info: DomainInfo) -> str:
        """
        Path to additional .ini files specific custom panel getter
        """
        return domain_info.ini_path

    def get_ini_path(self, domain_info: DomainInfo) -> str:
        """
        Resolve a path to directory for additional ini file.
        It depends on version set for domain and on selector
        NOTE:
        This method is overrided to manage php.d.location=selector resolving.
        In custom integration we do not know if PHP version is alt or not,
        it is set as just two digits.
        Thus, we only could rely on resolved path -- if it is '/opt/alt'.
        :param domain_info: a DomainInfo object
        :return: path to directory for ini files
        """
        if domain_info.php_ini_scan_dir:
            return domain_info.php_ini_scan_dir

        # here follows the hack to resolve php.d.location=selector
        # for custom integration
        ini_path = super().get_ini_path(domain_info)
        if ini_path.startswith(
                '/opt/alt') and not domain_info.panel_php_version.startswith(
                'alt-php'):
            saved_panel_php = domain_info.panel_php_version
            domain_info.panel_php_version = f'alt-php{domain_info.panel_php_version}'
            try:
                ini_path = domain_info.phpd_location_ini_path or ini_path
            except ValueError:
                # failed to resolve CageFS prefix for user
                pass
            domain_info.panel_php_version = saved_panel_php
            self.logger.info('Ini path re-resolved as %s', ini_path)
        return ini_path

Zerion Mini Shell 1.0