#!/usr/bin/env python # -*- mode:python; coding:utf-8; -*- # author: Dmitriy Kasyanov import getopt import glob import logging import os import sys import traceback import ConfigParser try: import rpm except: class rpm: @staticmethod def labelCompare(version1, version2): for i in range(0, len(version1)): if version1[i] < version2[i]: return -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): 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, 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, 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')) == -1: status = delete_prefix(prefix_path) else: try: int_enabled = config.getboolean("MultiPHP Manager", prefix_name) except (ConfigParser.NoOptionError, ConfigParser.NoSectionError), e: int_enabled = True logging.error("Could not parse alt-php.cfg:\n %s" % e) if int_enabled and os.path.exists(alt_php_enable_file): status = create_prefix(prefix_path, prefix_content) else: status = delete_prefix(prefix_path) 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): print >> sys.stderr, u"unknown %s version %s" % (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, e: print >> sys.stderr, \ u"cannot parse command line arguments: %s" % unicode(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.SafeConfigParser() 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, e: log.error(u"cannot reconfigure alt-%s for SCL: %s. " u"Traceback:\n%s" % (int_name, unicode(e), traceback.format_exc())) return 1 if __name__ == "__main__": sys.exit(main(sys.argv[1:]))