관리-도구
편집 파일: multiphp_reconfigure.py
#!/usr/libexec/platform-python # -*- mode:python; coding:utf-8; -*- # author: Dmitriy Kasyanov <dkasyanov@cloudlinux.com> import getopt import glob import logging import os import sys import traceback try: import configparser except ImportError: import ConfigParser as configparser try: import rpm except: class rpm: @staticmethod def labelCompare(version1, version2): def index_exists(_list, i): return (0 <= i < len(_list)) or (-len(_list) <= i < 0) res = 0 ver1 = version1[1].split('.') ver2 = version2[1].split('.') max_num = len(ver1) if len(ver2) > max_num: max_num = len(ver2) i = 0 while i < max_num: if index_exists(ver1,i) and index_exists(ver2,i): if ver1[i] == ver2[i]: res=0 else: return int(ver1[i]) - int(ver2[i]) elif index_exists(ver1,i) and not index_exists(ver2,i): return 1 elif index_exists(ver2,i) and not index_exists(ver1,i): return -1 i += 1 return 0 # Minimal version with MultiPHP support for alt-php MIN_CPANEL_VERSION = '11.66.0.11' SCL_PREFIX_PATH = '/etc/scl/prefixes' CONFIG_PATH = '/opt/alt/alt-php-config/alt-php.cfg' def configure_logging(verbose): """ Logging configuration function. @type verbose: bool @param verbose: Enable additional debug output if True, display only errors otherwise. """ if verbose: level = logging.DEBUG else: level = logging.ERROR handler = logging.StreamHandler() handler.setLevel(level) log_format = "%(levelname)-8s: %(message)s" formatter = logging.Formatter(log_format, "%H:%M:%S %d.%m.%y") handler.setFormatter(formatter) logger = logging.getLogger() logger.addHandler(handler) logger.setLevel(level) return logger def get_cpanel_version(): """ Returns cPanel version if cPanel installed or None othervise. @rtype: str or None @return: String with cPanel version or None if cPanel not installed. """ if os.path.exists('/usr/local/cpanel/version'): with open('/usr/local/cpanel/version', 'r') as fd: version = fd.read() return version return None def find_interpreter_versions(): """ Returns list of installed alt-php versions and their base directories. @rtype: list @return: List of version (e.g. 44, 55) and base directory tuples. """ int_versions = [] base_path_regex = "/opt/alt/php[0-9][0-9]" for int_dir in glob.glob(base_path_regex): if os.path.exists(os.path.join(int_dir, "usr/bin/php")): int_versions.append((int_dir[-2:], int_dir)) int_versions.sort() return int_versions def delete_prefix(prefix_path): """ Remove prefix file @type prefix_path: str @param prefix_path: Path to the prefix file, e.g. /etc/scl/prefix/alt-php70 @rtype: bool @return: True if file was removed sucessfully, False otherwise """ try: if os.path.exists(prefix_path): os.unlink(prefix_path) return True except OSError as e: logging.error(u"Couldn't remove prefix %s:\n%s" % (prefix_path, e)) return False def create_prefix(prefix_path, prefix_content): """ Creates prefix with path to alt-php @type prefix_path: str @param prefix_path: Path to the prefix file, e.g. /etc/scl/prefix/alt-php70 @type prefix_content: str @param prefix_content: SCL path, e.g. /opt/cloudlinux @rtype: bool @return: True if file was created sucessfully, False otherwise """ try: with open(prefix_path, 'w') as fd: fd.write(prefix_content) except IOError as e: logging.error(u"Couldn't open file %s:\n%s" % (prefix_path, e)) return False return True def reconfigure(config, int_version): """ @type config: @param config: @type int_version: str @param int_version: Interpreter version (44, 55, 72, etc.) @type int_path: str @param int_path: Interpreter directory on the disk (/opt/alt/php51, etc.) @rtype: bool @return: True if reconfiguration was successful, False otherwise """ cp_version = get_cpanel_version() prefix_name = "alt-php%s" % int_version prefix_path = os.path.join(SCL_PREFIX_PATH, prefix_name) prefix_content = "/opt/cloudlinux\n" alt_php_enable_file = "/opt/cloudlinux/alt-php%s/enable" % int_version if cp_version and rpm.labelCompare( ('1', cp_version, '0'), ('1', MIN_CPANEL_VERSION, '0')) < 0: status = delete_prefix(prefix_path) else: try: int_enabled = config.getboolean("MultiPHP Manager", prefix_name) except configparser.NoOptionError as e: int_enabled = True logging.warning("Prefix %s doesn't exist in %s:\n" % (prefix_name, CONFIG_PATH)) config.set("MultiPHP Manager", prefix_name, "yes") with open(CONFIG_PATH, 'w') as configfile: config.write(configfile) except configparser.NoSectionError as e: int_enabled = True config.add_section('MultiPHP Manager') config.set("MultiPHP Manager", prefix_name, "yes") with open(CONFIG_PATH, 'w') as configfile: config.write(configfile) print("Config %s is broken:\nCreated it.\n" % (CONFIG_PATH)) if int_enabled and os.path.exists(alt_php_enable_file): status = create_prefix(prefix_path, prefix_content) elif not int_enabled and os.path.exists(prefix_path): status = delete_prefix(prefix_path) else: return True return status def check_alt_path_exists(int_path, int_name, int_ver): """ Check if alt-php path exist ---------- @type int_path: str or unicode @param int_path: Interpreter directory on the disk (/opt/alt/php51, etc.) @type int_name: str or unicode @param int_name: Interpreter name (php, python) @type int_ver: str or unicode @apram int_ver: Interpreter version (44, 55, 72, etc.) @rtype: bool @return: True if interpreter path exists, False otherwise """ if not os.path.isdir(int_path): sys.stderr.write("unknown {0} version {1}".format(int_name, int_ver)) return False return True def main(sys_args): try: opts, args = getopt.getopt(sys_args, "p:v", ["php=", "verbose"]) except getopt.GetoptError as e: sys.stderr.write("cannot parse command line arguments: {0}".format(e)) return 1 verbose = False int_versions = [] int_name = "php" for opt, arg in opts: if opt in ("-p", "--php"): int_name = "php" int_path = "/opt/alt/php%s" % arg if check_alt_path_exists(int_path, int_name, arg): int_versions.append((arg, int_path)) else: return 1 if opt in ("-v", "--verbose"): verbose = True log = configure_logging(verbose) config = configparser.ConfigParser() config.read(CONFIG_PATH) try: if not int_versions: int_versions = find_interpreter_versions() for int_ver, int_dir in int_versions: reconfigure(config, int_ver) return 0 except Exception as e: log.error(u"cannot reconfigure alt-%s for SCL: %s. " u"Traceback:\n%s" % (int_name, e, traceback.format_exc())) return 1 if __name__ == "__main__": sys.exit(main(sys.argv[1:]))