%PDF- %PDF-
Direktori : /opt/cloudlinux/venv/lib/python3.11/site-packages/clwpos/object_cache/ |
Current File : //opt/cloudlinux/venv/lib/python3.11/site-packages/clwpos/object_cache/enable_redis_for_alt_php.py |
#!/opt/cloudlinux/venv/bin/python3 -bb # -*- 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 from __future__ import absolute_import import argparse import os import sys import logging from typing import List, Optional from cllimits.cagefs_lib import CageFs from clwpos.constants import ALT_PHP_PREFIX, CLWPOS_VAR_DIR from clwpos.php.base import PHP from clwpos.php.alt_php import ( create_generic_php, get_alt_php_versions, update_selector_built_in_extensions, disable_selector_extensions ) from clwpos.logsetup import setup_logging from clwpos.optimization_features import OBJECT_CACHE_FEATURE from clwpos.feature_suites import is_module_visible_for_user from clwpos.utils import ( PhpIniConfig, create_pid_file, acquire_lock, ) from clwpos.object_cache.redis_utils import ( filter_php_versions_with_not_loaded_redis ) logger = setup_logging( caller_name='enable_redis_for_alt_php', file_level=logging.DEBUG, logfile_path='/var/log/clwpos/enable_redis_for_alt_php.log', ) awp_ini = 'acceleratewp.ini' # marker for those clients, who do not want us modifying global ini DO_NOT_MODIFY_PHP_GLOBAL_MARKER = f'{CLWPOS_VAR_DIR}/admin/do_not_modify_global_php.flag' def remove_custom_ini(version: Optional[str], all_ini: Optional[bool]): if not os.path.exists(DO_NOT_MODIFY_PHP_GLOBAL_MARKER): logger.debug('Nothing to do') return supported_version = supported_alt_php(version) for php_version in supported_version: php_ini_config = PhpIniConfig(php_version, custom_logger=logger) php_ini_config.remove_custom_ini(f'etc/php.d/{awp_ini}', all_ini) def update_user_ini(php_version: PHP): php_ini_config = PhpIniConfig(php_version, custom_logger=logger) modules_to_sync = php_ini_config.get_ini_content(f'etc/php.d/{awp_ini}') php_ini_config.update_user_ini('acceleratewp.ini', modules_to_sync) def enable_redis_extension(php_version: PHP): """ Enable 'redis' extension for specified alt-php version by adding 'extension=redis.so' into php.ini file. Also enable 'json' and 'igbinary' extensions if exist which are reqired by 'redis' extension. At the same time: - disable extension in 'php.d.all/<extension>.ini' to deny user to enable extension via PHP Selector. - disable extensions in 'php.d/default.ini' to eliminate duplicate loading of extensions. """ php_ini_config = PhpIniConfig(php_version, custom_logger=logger) redis_required_modules = php_ini_config.get_required_modules('etc/php.d.all/redis.ini') if not redis_required_modules: logger.debug('Redis extension is not present in the system, skip') return modules = ['json'] + redis_required_modules modules.sort(key=lambda x: x.endswith('redis')) module_status_map = {} for module in modules: if module == 'redis': module_status_map['redis'] = php_ini_config.disable_modules(f'etc/php.d.all/redis.ini', redis_required_modules) else: module_status_map[module] = php_ini_config.disable_modules(f'etc/php.d.all/{module}.ini', [module]) logger.debug(f'Final current modules status: {module_status_map}') existing_modules = [ module for module, exists in module_status_map.items() if exists ] logger.debug(f'Existing extensions: {existing_modules}') php_ini_config.disable_modules('etc/php.d/default.ini', existing_modules) non_loaded_modules = [ module for module in existing_modules if not php_version.is_extension_loaded(module) ] if not os.path.exists(DO_NOT_MODIFY_PHP_GLOBAL_MARKER): php_ini_config.enable_modules('etc/php.ini', non_loaded_modules) else: logger.debug('Marker exists: %s, adding those modules to custom awp ini: %s', DO_NOT_MODIFY_PHP_GLOBAL_MARKER, str(non_loaded_modules)) php_ini_config.create_custom_ini(f'etc/php.d/{awp_ini}', non_loaded_modules) disable_selector_extensions(non_loaded_modules, php_version.version, logger) def supported_alt_php(version: Optional[str]): alt_php_versions = [create_generic_php(f'{ALT_PHP_PREFIX}{version}')] if version else get_alt_php_versions() supported_alt_php_versions = [ version for version in alt_php_versions if OBJECT_CACHE_FEATURE.is_php_supported(version) ] return supported_alt_php_versions def get_php_versions_to_enable_redis(version: Optional[str]) -> List[PHP]: """ Return list of php version supported by AccelerateWP and on which redis is presented but not enabled. """ supported_alt_php_versions = supported_alt_php(version) return filter_php_versions_with_not_loaded_redis(supported_alt_php_versions) def parse_args() -> argparse.Namespace: """ Parse arguments for enable_redis_for_alt_php.py utility. """ parser = argparse.ArgumentParser( prog='enable_redis_for_alt_php', description='Utility for enabling redis extension for alt-php', ) parser.add_argument( '--version', type=int, help='Enable redis extension for specific alt-php version', ) parser.add_argument( '--no-rebuild', action='store_true', help='Run without rebuilding users\' alt_php.ini files', ) parser.add_argument( '--remove-custom-ini', action='store_true', help='Run to remove custom acceleratewp.ini' ) parser.add_argument('--all', action='store_true', help='Run to remove ALL custom acceleratewp.ini') parser.add_argument('-v', '--verbose', action='store_true') parser.add_argument('-f', '--force', action='store_true') opts, _ = parser.parse_known_args() if opts.verbose: logging.basicConfig(level=logging.DEBUG) return opts def main(): """ Enable redis extension for alt-php versions supported by AccelerateWP. """ opts = parse_args() if not is_module_visible_for_user(OBJECT_CACHE_FEATURE) and not opts.force: print('Run only if object caching is allowed for at least one user') sys.exit(0) cagefs = CageFs() if opts.remove_custom_ini: remove_custom_ini(opts.version, opts.all) sys.exit(0) with acquire_lock(os.path.join('/var/run', ALT_PHP_PREFIX), attempts=None): php_versions_to_enable_redis = get_php_versions_to_enable_redis(opts.version) # we don't continue if there are no alt-php versions (supported by WPOS) # with redis presented but not loaded if not php_versions_to_enable_redis: logger.info('All php versions have redis extension installed and active') sys.exit(0) with create_pid_file(ALT_PHP_PREFIX): for php_version in php_versions_to_enable_redis: enable_redis_extension(php_version) # iter all supported, to sync users ini in case we already enabled in global .ini if os.path.exists(DO_NOT_MODIFY_PHP_GLOBAL_MARKER): for php_version in supported_alt_php(None): update_user_ini(php_version) # we don't continue if there are no alt-php versions (supported by WPOS) # with redis presented but not loaded if not php_versions_to_enable_redis: sys.exit(0) # Rebuild users' alt_php.ini if all condition are satisfied: # - script called with no flag --no-rebuild # - cagefs package is installed if not opts.no_rebuild and cagefs.is_cagefs_present(): cagefs.rebuild_alt_php_ini() update_selector_built_in_extensions(logger) if __name__ == '__main__': main()