#!/usr/bin/env python # -*- mode:python; coding:utf-8; -*- import sys import getopt import os import logging import glob import subprocess from shutil import copy2 try: import db.clcommon.cpapi as cpapi except ImportError: import detectcp as cpapi MODES = ("check", "install", "uninstall") def configure_logging(verbose): """ Logging configuration function :type verbose: bool :param verbose: Enable additional debug output if True, display only errors othervise :return: configured logger object """ 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 find_alt_php_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 """ php_versions = [] for php_dir in glob.glob("/opt/alt/php[0-9][0-9]"): php_versions.append((php_dir[-2:], php_dir)) php_versions.sort() return php_versions def plesk_check_php_handler(cgi_type, php_ver): """ :param php_ver: alt-php version (e.g. 44, 55, 70) :return: If handler exist returns True, otherwise False """ proc = subprocess.Popen(["/usr/local/psa/bin/php_handler", "--list"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) out, _ = proc.communicate() for line in out.split("\n"): if 'alt-php%s-%s' % (php_ver, cgi_type) in line.strip().split(" ")[0]: logging.info("Handler for alt-php%s-%s exist." % (php_ver, cgi_type)) return True logging.info("Handler for alt-php%s-%s not exist." % (php_ver, cgi_type)) return False def plesk_add_php_handler(cgi_type, php_ver, php_path): if plesk_check_php_handler(cgi_type, php_ver): logging.info("Handler for alt-php%s-%s exist." % (php_ver, cgi_type)) return False logging.info("Plesk: Installing alt-php%s-%s handler." % (php_ver, cgi_type)) print >> sys.stdout, "Plesk: Installing alt-php%s-%s handler." % (php_ver, cgi_type) # run /usr/local/psa/bin/php_handler --add -displayname alt-php-7.0.0 -path /opt/alt/php70/usr/bin/php-cgi # -phpini /opt/alt/php70/etc/php.ini -type fastcgi -id 666 -clipath /opt/alt/php70/usr/bin/php command = "/usr/local/psa/bin/php_handler" add_command = [ command, '--add', '-displayname', 'alt-php%s-%s' % (php_ver, cgi_type), '-clipath', os.path.join(php_path, 'usr/bin/php'), '-phpini', os.path.join(php_path, 'etc/php.ini'), '-type', cgi_type, '-id', 'alt-php%s-%s' % (php_ver, cgi_type), ] if cgi_type == "fpm": add_command.extend([ '-service', 'alt-php%s-fpm' % php_ver, '-path', os.path.join(php_path, 'usr/sbin/php-fpm'), '-poold', os.path.join(php_path, 'etc/php-fpm.d'),]) if not os.path.exists("/opt/alt/php%s/etc/php-fpm.conf" % php_ver): copy2(os.path.join(php_path, 'etc/php-fpm.conf.plesk'), os.path.join(php_path, 'etc/php-fpm.conf')) else: add_command.extend([ '-path', os.path.join(php_path, 'usr/bin/php-cgi'),]) proc = subprocess.Popen(add_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) out, _ = proc.communicate() if proc.returncode != 0: raise Exception(u"cannot execute \"%s\": %s" % (' '.join(add_command), out)) proc = subprocess.Popen([command, "--reread"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) out, _ = proc.communicate() if proc.returncode != 0: raise Exception(u"cannot execute \"" + command + " --reread\": %s" % out) logging.info("Handler for alt-php%s was successfully added." % php_ver) return True def plesk_remove_php_handler(cgi_type, php_ver): if plesk_check_php_handler(cgi_type, php_ver): logging.info("Plesk: Removing alt-php%s-%s handler." % (php_ver, cgi_type)) print >> sys.stdout, "Plesk: Removing alt-php%s-%s handler." % (php_ver, cgi_type) command = ["/usr/local/psa/bin/php_handler", "--remove", "-id", "alt-php%s-%s" % (php_ver, cgi_type)] proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) out, _ = proc.communicate() if proc.returncode != 0: raise Exception(u"cannot execute \"%s\": %s" % (' '.join(command), out)) logging.info("Handler for alt-php%s-%s was successfully removed." % (php_ver, cgi_type)) return True else: logging.info("Handler for alt-php%s-%s not exist." % (php_ver, cgi_type)) return False def configure_alt_php(mode, php_ver, php_path): """ :rtype: bool :return: If success returns True, otherwise False """ try: cp_name = cpapi.getCPName() if cp_name == "Plesk": if not os.path.exists("/usr/local/psa/bin/php_handler"): raise Exception("/usr/local/psa/bin/php_handler not exist.") if mode == "install": plesk_add_php_handler('fastcgi', php_ver, php_path) plesk_add_php_handler('cgi', php_ver, php_path) if os.path.exists("/etc/init.d/alt-php%s-fpm" % php_ver) or os.path.exists("/usr/lib/systemd/system/alt-php%s-fpm.service" % php_ver): plesk_add_php_handler('fpm', php_ver, php_path) elif mode == "uninstall": plesk_remove_php_handler('fastcgi', php_ver) plesk_remove_php_handler('cgi', php_ver) if os.path.exists("/etc/init.d/alt-php%s-fpm" % php_ver) or os.path.exists("/usr/lib/systemd/system/alt-php%s-fpm.service" % php_ver): plesk_remove_php_handler('fpm', php_ver) else: return plesk_check_php_handler('fastcgi', php_ver) and plesk_check_php_handler('cgi', php_ver) and plesk_check_php_handler('fpm', php_ver) except Exception as e: logging.info(e) return False def main(sys_args): try: opts, args = getopt.getopt(sys_args, "m:p:v", ["mode=", "php=", "verbose"]) except getopt.GetoptError, e: print >> sys.stderr, \ u"cannot parse command line arguments: %s" % unicode(e) return 1 verbose = False mode = "check" php_versions = [] for opt, arg in opts: if opt in ("-m", "--mode"): if arg not in MODES: # use check mode mode = "check" else: mode = arg if opt in ("-p", "--php"): if not os.path.isdir("/opt/alt/php%s" % arg): print sys.stderr, \ u"unknown PHP version %s" % arg return 1 php_versions.append((arg, "/opt/alt/php%s" % arg)) if opt in ("-v", "--verbose"): verbose = True log = configure_logging(verbose) if not php_versions: php_versions = find_alt_php_versions() log.info(u"installed alt-php versions are\n%s" % "\n".join(["\t alt-php%s: %s" % i for i in php_versions])) for ver, path in php_versions: configure_alt_php(mode, ver, path) if __name__ == "__main__": sys.exit(main(sys.argv[1:]))