Mini Shell

Direktori : /usr/share/l.v.e-manager/
Upload File :
Current File : //usr/share/l.v.e-manager/install-lvemanager-plugin.py

#!/opt/cloudlinux/venv/bin/python3 -bb
# -*- coding: utf-8 -*-

# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import subprocess

from future.moves import configparser as ConfigParser
import os
import sys
import getopt
import shutil
import datetime
import re
import uuid
import json

from builtins import map

import cldetectlib as detect
from lvemanager.config_parser import SectionlessConfigParser
from copy_directory import CopyDirectory
from exec_command import exec_command, exec_command_check
from crontab import add_cron, remove_cron
from feature_manager import cpanel_fix_feature_manager
from clcommon.utils import create_symlink
from clcommon.const import Feature
from clcommon.cpapi import is_panel_feature_supported
from clcommon.public_hooks.bundle.cpanel import (
    install_hooks,
    remove_hooks,
    Hook
)
from clcommon.utils import mod_makedirs
from lvemanager import PKG_VERSION as LVEMANAGER_VERSION
from lvemanager import PKG_RELEASE as LVEMANAGER_RELEASE
from lvemanager.sudoers import (
    add_unix_user_to_sudoers
)
from clcommon.ui_config import UIConfig

LVEMANAGER_CRON = "lvemanager-cron"
CL_SELECTOR_PHP_CONF_PATH = '/etc/cl.selector/php.conf'

SOURCE_PATH = "/usr/share/l.v.e-manager/"
ROOT_CPANEL_DIR = "/usr/local/cpanel/whostmgr/docroot/"
CPANEL_CUSTOM_PATH = '/var/cpanel/perl/Cpanel/ResourceUsage/Custom/'
ROOT_IWORX_DIR = "/usr/local/interworx/plugins/"
ROOT_ISPMGR_DIR = "/usr/local/ispmgr/"
ROOT_DA_DIR = "/usr/local/directadmin/plugins/"
CPANEL_PAPER_LATERN_HOME = "/usr/local/cpanel/base/frontend/paper_lantern/home/"
CPANEL_PATCHES_PATH = SOURCE_PATH + 'cpanel/patches/'
CPANEL_ORIGINAL_FILES_DIR = '/usr/local/cpanel/base/3rdparty/cloudlinux/original/'
SPA_RESOURCE_DIR = SOURCE_PATH + "commons/spa-resources/"
CPANEL_BASED_DEMO_SERVER_FLAG = "/var/lve/demo-server.flag"
UI_CONFIG_PATH = '/usr/share/l.v.e-manager/lvemanager-config.json'
CLOUDLINUX_SERVER_FLAGS_SOURCE_DIR = SOURCE_PATH + 'cl-server-flags/'
CLOUDLINUX_SERVER_FLAGS_DESTINATION_DIR = '/opt/cloudlinux/flags/available-flags.d/'

# cPanel parametres
CPANEL_ICON_BASE_DIR = '/usr/local/cpanel/base/frontend/'
CRON_TASKS = [
    ("*/5", "*", "*", "*", "*", "root", "/usr/bin/flock -n /var/run/cloudlinux_cl-quota.cronlock /usr/bin/cl-quota -YC")
]
CPANEL_CRON_TASKS = [
    ("*/5", "*", "*", "*", "*", "root", "/usr/bin/flock -n /var/run/cloudlinux_lve_manager.cronlock /usr/share/l.v.e-manager/cpanel/hooks/l.v.e-manager_postupcp_hook.sh --cronjob"),
    ("*/5", "*", "*", "*", "*", "root", "/usr/bin/flock -n /var/run/detect_edition_changes.cronlock /usr/share/l.v.e-manager/detect_edition_changes.py > /dev/null 2>&1"),
]

if is_panel_feature_supported(Feature.LVE):
    CPANEL_CRON_TASKS.append(("*/5", "*", "*", "*", "*", "root", "/usr/bin/flock -n /var/run/cloudlinux_cl-syncpkg.cronlock /usr/bin/cl-syncpkgs"))


CPANEL_SELECTOR_UNPARK_HOOK = SOURCE_PATH + 'commons/lib/selectorhooks/selectorunparkhook.py'
CPANEL_SELECTOR_UNPARK_HOOK_SCRIPT = '/scripts/selectorunparkhook.py'

CPANEL_OLD_NODEJS_UNPARK_HOOK_SCRIPT = '/scripts/nodejsunparkhook.py'

_CPANEL_HOOKS = (
    Hook(CPANEL_SELECTOR_UNPARK_HOOK_SCRIPT, 'Whostmgr', 'Domain::unpark', 'post'),
)
_CPANEL_LEGACY_HOOKS_TO_REMOVE = (
    Hook(CPANEL_OLD_NODEJS_UNPARK_HOOK_SCRIPT, 'Whostmgr', 'Domain::unpark', 'post'),
)

# cpanel scripts to install&uninstall end-user plugins
CPANEL_PLUGIN_INSTALL_SCRIPT = "/usr/local/cpanel/scripts/install_plugin"
CPANEL_PLUGIN_UNINSTALL_SCRIPT = "/usr/local/cpanel/scripts/uninstall_plugin"

# list of configs ready to format with theme
CPANEL_DYNAMICUI_CONFIGS = [
    "/usr/local/cpanel/base/frontend/{}/dynamicui/dynamicui_lvepythonsel.conf",
    "/usr/local/cpanel/base/frontend/{}/dynamicui/dynamicui_lverubysel.conf",
    "/usr/local/cpanel/base/frontend/{}/dynamicui/dynamicui_lvephpsel.conf",
    "/usr/local/cpanel/base/frontend/{}/dynamicui/dynamicui_lvenodejssel.conf",
    "/usr/local/cpanel/base/frontend/{}/dynamicui/dynamicui_lveresusage.conf",
    "/usr/local/cpanel/base/frontend/{}/dynamicui/dynamicui_lvewpos.conf"
]

# DirectAdmin parametres
DA_HOOK_DEST_DIR = '/usr/local/directadmin/scripts/custom'
DA_CREATE_USER_HOOK_FILENAME = 'user_create_post.sh'
DA_REMOVE_USER_HOOK_FILENAME = 'user_destroy_post.sh'
DA_CREATE_USER_HOOK_CMD_OLD = '/usr/bin/da-addsudoer "$username" add_user'
DA_REMOVE_USER_HOOK_CMD_OLD = '/usr/bin/da-removesudoer "$username" lve_user'

# https://www.directadmin.com/features.php?id=448
DA_CHANGE_DOMAIN_HOOK_CMD = '/usr/bin/da_transit_app "$username" "$domain" "$newdomain"'
DA_CHANGE_DOMAIN_HOOK_FILE = 'domain_change_post.sh'

DA_CREATE_USER_HOOK_CMD = '/usr/bin/da_add_admin "$username"'
DA_REMOVE_USER_HOOK_CMD = '/usr/bin/da_remove_admin "$username"'
DA_SUDOERS_USER = 'lvemanager'
# Plesk parameters
ROOT_PLESK_DIR = "/usr/local/psa/admin/"
PLESK_MIGRATOR_DIR = '/usr/local/psa/var/modules/panel-migrator/events/subscription-migration-finished/'
PLESK_MIGRATOR_FILE = "PHP_settings_update.py"
PLESK_MIGRATOR_HOOK = "/usr/share/l.v.e-manager/hooks/plesk/" + PLESK_MIGRATOR_FILE

PANEL_CONFIG = '/opt/cpvendor/etc/integration.ini'


def touch(fname):
    try:
        os.utime(fname, None)
    except OSError:
        open(fname, 'a').close()


def getItem(txt1, txt2, op):
    try:
        i1 = int(txt1)
    except ValueError:
        i1 = -1
    try:
        i2 = int(txt2)
    except ValueError:
        i2 = -1
    if i1 == -1 or i2 == -1:
        if op == 0:
            return txt1>txt2
        else:
            return txt1<txt2
    else:
        if op == 0:
            return i1>i2
        else:
            return i1<i2


#Compare version of types xx.xx.xxx... and yyy.yy.yy.y..
#if xxx and yyy is numbers, than comapre as numbers
#else - comapre as strings
def verCompare (base, test):
    base = base.split(".")
    test = test.split(".")
    if(len(base)>len(test)):
        ln = len(test)
    else:
        ln = len(base)
    for i in range(ln):
        if getItem(base[i],test[i],0):
            return 1
        if getItem(base[i],test[i],1):
            return -1
    if len(base)==len(test):
        return 0
    elif len(base)>len(test):
        return 1
    else:
        return 0


def usage():
    print('')
    print('Use following syntax to manage CloudLinux Manager install utility:')
    print(sys.argv[0]+" [OPTIONS]")
    print('Options:')
    print(" -i | --install     : install lvemanager plugin")
    print(" --patch-paper-lantern : deprecated; use --postupcp")
    print(" --postupcp         : always run after updating cPanel")
    print(" -d | --delete      : delete  lvemanager plugin")
    print(" -u | --update      : update  lvemanager plugin")


def exit_with_error(message, status=1):
    sys.stderr.write("Error: %s\n" % (str(message,)))
    sys.exit(status)


def add_sudoers(user):
    try:
        from clsudo import Clsudo
        sudo = Clsudo()
        sudo.add_user(user)
    except Exception as e:
        exit_with_error(e)


def install_cpanel_icons(plugin_name):
    try:
        base_dir = SOURCE_PATH + "cpanel/" + plugin_name + "/icon/"
        themes = os.listdir(base_dir)
        for theme in themes:
            icons = os.listdir(base_dir + theme)
            for icon_file in icons:
                if os.path.isfile(base_dir + theme + "/" + icon_file):
                    # print 'copy ' +base_dir + theme + "/" + icon_file + ' to ' + CPANEL_ICON_BASE_DIR + theme + '/branding/'
                    if verCompare (cp.version, "11.46.0") >= 0:
                        if os.path.isdir(CPANEL_ICON_BASE_DIR + theme + '/styled/basic/icons/'):
                            shutil.copy(base_dir + theme + "/" + icon_file, CPANEL_ICON_BASE_DIR + theme + '/styled/basic/icons/')
                    else:
                        if os.path.isdir(CPANEL_ICON_BASE_DIR + theme + '/branding/'):
                            shutil.copy(base_dir + theme + "/" + icon_file, CPANEL_ICON_BASE_DIR + theme + '/branding/')
    except (OSError, IOError):
        pass   #skip all errors;


def list_patches(reverse=False):
    if not os.path.exists(CPANEL_PATCHES_PATH):
        return []

    comparator = lambda first, second: int(first.split('_', 1)[0]) - int(second.split('_', 1)[0])

    lst = os.listdir(CPANEL_PATCHES_PATH)
    lst = [x for x in lst if x.endswith('.patch')]
    lst.sort(cmp=comparator, reverse=reverse)
    return lst


def check_if_backup_older_than_month(file_):
    """
    :param file_: file name
    :return: True if file older then month. False if can't parse date or not older than month
    """
    try:
        file_datetime = datetime.datetime.strptime(file_.split("_")[-2], "%Y-%m-%d")
    except (ValueError, IndexError):
        return False
    if file_datetime < datetime.datetime.now() - datetime.timedelta(days=30):
        return True
    else:
        return False


def delete_old_papper_latern_backups(dir_with_backups=CPANEL_PAPER_LATERN_HOME):
    filelist = os.listdir(dir_with_backups)
    filelist = [x for x in filelist if
                (x.startswith("stats_display_name.html.tt.orig_") or
                 x.startswith("stats_bar.html.tt.orig_")) and
                check_if_backup_older_than_month(x)]
    for f in filelist:
        try:
            os.remove(os.path.join(dir_with_backups, f))
        except OSError:
            pass
    print("Deleted " + str(len(filelist)) + \
          " old backup files ( for stats_display_name.html.tt and stats_bar.html.tt) in directory " + dir_with_backups)


def cpanel_use_patches():
    if verCompare(cp.version, "69.9032") >= 0:
        return
    delete_old_papper_latern_backups()
    patches = list_patches()
    for patch_file_name in patches:
        full_patch_path = os.path.join(CPANEL_PATCHES_PATH, patch_file_name)
        if os.path.exists(full_patch_path):
            exec_command("patch -t -F3 -b -z .orig_$(date +%%F_%%R) -r- -p0 -d / -N -i %s" % full_patch_path)


def cpanel_rollback_patches():
    if verCompare(cp.version, "69.9032") >= 0:
        return
    patches = list_patches(reverse=True)
    for patch_file_name in patches:
        full_patch_path = os.path.join(CPANEL_PATCHES_PATH, patch_file_name)
        if os.path.exists(full_patch_path):
            exec_command("patch -R -F3 -t -b -z .orig_$(date +%%F_\%%R) -r- -p0 -d / -N -i %s" % full_patch_path)


def restore_cpanel_statsbar():
    subprocess.run('/bin/bash /usr/share/l.v.e-manager/cpanel/patches/restore-statsbar.sh',
                   shell=True, executable='/bin/bash')


def add_lve_limits_to_stats_bar():
    if verCompare(cp.version, "69.9032") >= 0:
        restore_cpanel_statsbar()
        if not os.path.exists(CPANEL_CUSTOM_PATH):
            os.makedirs(CPANEL_CUSTOM_PATH)
        shutil.copyfile(SOURCE_PATH + 'cpanel/stats_bar/Cloudlinux.pm', CPANEL_CUSTOM_PATH + 'Cloudlinux.pm')


def grep(line, f):
    stream = open(f)
    for line_ in stream:
        if line in line_:
            stream.close()
            return True
    stream.close()
    return False


def patch_cpanel_config():
    exec_command(SOURCE_PATH + 'cpanel/utils/dynamicuictl.py --verbose --sync-conf=all --no-rebuild-sprites')

def plesk_commons():
    cpdir = CopyDirectory(SPA_RESOURCE_DIR, ROOT_PLESK_DIR + 'htdocs/modules/plesk-lvemanager')
    cpdir.process()
    # LVEMAN-1479: remove /usr/local/psa/admin/htdocs/modules/plesk-lvemanager/misc/clinfo.php
    try:
        os.unlink(ROOT_PLESK_DIR + 'htdocs/modules/plesk-lvemanager/misc/clinfo.php')
    except OSError:
        pass

def cpanel_commons():
    CopyDirectory(SPA_RESOURCE_DIR, ROOT_CPANEL_DIR + '3rdparty/cloudlinux/assets').process()
    create_symlink(ROOT_CPANEL_DIR + '3rdparty/cloudlinux', ROOT_CPANEL_DIR + 'cgi/cloudlinux')

def da_commons():
    CopyDirectory(SPA_RESOURCE_DIR, ROOT_DA_DIR + 'lvemanager_spa/images/assets').process()
    CopyDirectory(SOURCE_PATH + 'directadmin/assets', ROOT_DA_DIR + 'lvemanager_spa/images/assets').process()
    DA_PLUGIN_NAMES = ['nodejs_selector', 'python_selector', 'phpselector', 'resource_usage']
    for plugin_name in DA_PLUGIN_NAMES:
        CopyDirectory(ROOT_DA_DIR + 'lvemanager_spa/images/assets', ROOT_DA_DIR + plugin_name + '/images/assets')\
            .process()

def install_commons():
    panels = {
        'Plesk': plesk_commons,
        'cPanel': cpanel_commons,
        'DirectAdmin': da_commons
    }
    try:
        panels[cp.name]()
    except KeyError as e:
        pass


def migrate_ui_configs(panel_name):
    """
    Migrate all of the UI configs from the old config file
    to the new lvemanager-config.json file.
    :param panel_name: name of the panel
    """
    plesk_conf_file = '/usr/local/psa/admin/plib/modules/lvemanager.conf'
    if (not os.path.exists(UI_CONFIG_PATH) and panel_name in ['cPanel', 'DirectAdmin', 'Plesk']) \
            or (os.path.exists(plesk_conf_file) and panel_name == 'Plesk'):
        print ('Migrating {} UI configs to new UI config file...'.format(panel_name))
        configs = {
            'cPanel': {'path': '/var/cpanel/cpanel.config', 'params': ['lve_showinodeusage', 'lve_hideuserstat',
                                                                       'lve_hideextensions', 'lve_enablerubyapp',
                                                                       'lve_enablepythonapp', 'lve_hide_selector']},
            'DirectAdmin': {'path': '/usr/local/directadmin/plugins/phpselector/plugin.conf', 'params': ['active']},
            'Plesk': {'path': plesk_conf_file, 'params': ['enable_selector']}
        }

        parsed_config = {}
        if os.path.exists(configs[panel_name]['path']):
            try:
                f = open(configs[panel_name]['path'])
                config_lines = f.readlines()
                f.close()
            except (OSError, IOError) as e:
                print(e)
        else:
            config_lines = ''
        try:
            for idx in range(0, len(config_lines)):
                line_parts = config_lines[idx].strip().split('=')
                if len(line_parts) != 2:
                    continue
                if line_parts[0] in configs[panel_name]['params']:
                    try:
                        value = line_parts[1]
                        if not isinstance(value, bool):
                            if value.lower() in ['y', '1', 'on', 'true', 'yes']:
                                value = True
                            else:
                                value = False
                        parsed_config[line_parts[0]] = value
                    except ValueError:
                        parsed_config[line_parts[0]] = False
        except (KeyError, IndexError) as e:
            print(e)

        result_config = dict()
        if panel_name == 'cPanel':
            result_config['inodeLimits'] = {'showUserInodesUsage': parsed_config.get('lve_showinodeusage')}
            result_config['uiSettings'] = {'hideLVEUserStat': parsed_config.get('lve_hideuserstat'),
                                         'hidePHPextensions': parsed_config.get('lve_hideextensions'),
                                         'hideRubyApp': not parsed_config.get('lve_enablerubyapp'),
                                         'hidePythonApp': not parsed_config.get('lve_enablepythonapp'),
                                         'hidePhpApp': parsed_config.get('lve_hide_selector')}
        elif panel_name == 'DirectAdmin':
            result_config = UIConfig().get_config()
            result_config['uiSettings']['hidePhpApp'] = False if parsed_config.get('active') else True
        else:
            result_config = UIConfig().get_config()
            result_config['uiSettings']['hidePhpApp'] = False if parsed_config.get('enable_selector') else True
            if os.path.exists(configs[panel_name]['path']):
                os.remove(configs[panel_name]['path'])

        with open(UI_CONFIG_PATH, 'w') as new_file:
            json.dump({'ui_config': result_config}, new_file)


def check_and_rename_ui_setting(old_key, new_key):
    """
    Read and rename key in uiSettings from /usr/share/l.v.e-manager/lvemanager-config.json if required
    """
    if not os.path.exists(UI_CONFIG_PATH):
        return
    with open(UI_CONFIG_PATH, 'r') as json_file:
        data = json.load(json_file)
    if old_key in data.get("ui_config", {}).get("uiSettings", {}):
        data["ui_config"]["uiSettings"][new_key] = data["ui_config"]["uiSettings"].pop(old_key)
        with open(UI_CONFIG_PATH, 'w') as json_file:
            json.dump(data, json_file)


def fix_php_conf():
    """
    for details please see LVEMAN-1215: fix syntax in /etc/cl.selector/php.conf for old installations of lvemanager
    """
    if not os.path.isfile(CL_SELECTOR_PHP_CONF_PATH):
        return
    replace_values = [
        {
            's_from': '\nComment   = If PHP is in the safe mode and a script tries to access some files, files from t' \
                      'his directory will bypass security (UID/GID) checks. Th\ne directory must also be in include_p' \
                      'ath. For example: /dir/inc\n',
            's_to': '\nComment   = If PHP is in the safe mode and a script tries to access some files, files from thi' \
                    's directory will bypass security (UID/GID) checks. The directory must also be in include_path. F' \
                    'or example: /dir/inc\n'
        },
        {
            's_from': '\nRange     = ~E_ALL,E_ALL & ~E_NOTICE,E_ALL\n',
            's_to': '\nRange     = ~E_ALL,E_ALL & ~E_NOTICE,E_ALL,E_ALL & ~E_DEPRECATED & ~E_STRICT\n'
        }
    ]
    with open(CL_SELECTOR_PHP_CONF_PATH, 'r') as f:
        php_conf = f.read()
    for item in replace_values:
        if item['s_from'] in php_conf:
            php_conf = php_conf.replace(item['s_from'], item['s_to'])
    with open(CL_SELECTOR_PHP_CONF_PATH, 'w') as f:
        f.write(php_conf)


def create_selector_config_dir(selector_name):
    """
    Create config dir for NodeJS/Python/etc selector in easy mountable location
    and create symlink from /etc to that location
    for details see CAG-797: mount NodeJS Selector config directory into CageFS and
                    CAG-828: Add python-selector.json to cagefs
    :param selector_name: name of selector: nodejs, python, etc
    """
    selector_cfg_dir = os.path.join(SOURCE_PATH, 'cl.{}'.format(selector_name))
    # symlink for ease of use the selector config and avoiding problem with cagefs
    selector_cfg_symlink = '/etc/cl.{}'.format(selector_name)
    if not os.path.isdir(selector_cfg_dir):
        mod_makedirs(selector_cfg_dir, 0o755)
    create_symlink(selector_cfg_dir, selector_cfg_symlink)


def install_plugin(tp):
    print('Starting {} script...\n'.format(tp))
    # install into crontab
    remove_cron(LVEMANAGER_CRON)
    remove_cron('lvemanager-selector')
    if is_panel_feature_supported(Feature.RUBY_SELECTOR):
        add_cron('lvemanager-selector', 'r', 'r', '*', '*', '*', 'root', '/usr/bin/flock -n /var/run/cloudlinux_cache_ruby.cronlock ' +  SOURCE_PATH + 'utils/cache_rubygems.py')
    if is_panel_feature_supported(Feature.PHP_SELECTOR):
        add_cron('lvemanager-selector', '*/5', '*', '*', '*', '*', 'root', '/usr/bin/flock -n /var/run/cloudlinux_cache_php.cronlock ' +  SOURCE_PATH + 'utils/cache_phpdata.py')

    for task in CRON_TASKS:
        add_cron(LVEMANAGER_CRON, *task, check_command=False)

    fix_php_conf()

    create_selector_config_dir('nodejs')
    create_selector_config_dir('python')

    # install only. rewrite all existing file
    update_php_config()

    # Remember version and release.
    remember_version()

    # Detect the first installation.
    create_first_installation_flags()

    # Add cloudlinux-server-flags
    add_cl_server_flags()

    # migrating ui configs
    migrate_ui_configs(cp.name)

    # rename hideWPOSApp to hideAccelerateWPApp if old config
    check_and_rename_ui_setting('hideWPOSApp', 'hideAccelerateWPApp')

    if cp.name == "Plesk" and verCompare (cp.version, "10") >= 0:
        # Checking the install version 2.0
        if (LVEMANAGER_VERSION == '2.0' and not os.path.exists(ROOT_PLESK_DIR + 'htdocs/modules/plesk-lvemanager/lvemanager_spa')) \
                or (LVEMANAGER_VERSION == '1.0' and os.path.exists(ROOT_PLESK_DIR + 'htdocs/modules/plesk-lvemanager/lvemanager_spa')):
            delete_plugin()
        add_sudoers("psaadm")
        exec_command(SOURCE_PATH+"utils/generate_locale_files_for_plesk.py")

        # Prepare static files for SPA
        cpdir = CopyDirectory(SPA_RESOURCE_DIR+'static/', SOURCE_PATH+'plesk/htdocs/modules/plesk-lvemanager/static/')
        cpdir.process()

        cpdir = CopyDirectory(SOURCE_PATH+"plesk", ROOT_PLESK_DIR)
        cpdir.process()

        if os.path.exists(SOURCE_PATH+"utils/install-plesk-plugin.sh"):
            exec_command(SOURCE_PATH+"utils/install-plesk-plugin.sh")
        if os.path.exists(SOURCE_PATH+"utils/plesk-cgi.sh"):
            if not os.path.exists("/usr/share/l.v.e-manager/plesk/script/"):
                os.makedirs("/usr/share/l.v.e-manager/plesk/script/")
            shutil.copyfile(SOURCE_PATH+"utils/plesk-cgi.sh", "/usr/share/l.v.e-manager/plesk/script/plesk-cgi.sh")
            if os.path.exists(SOURCE_PATH+"utils/installsupergrp.sh"):
                exec_command(SOURCE_PATH+"utils/installsupergrp.sh psaadm")
        register_plesk_plugin()
        # install migration hook for Plesk 12.5+
        if verCompare(cp.version, "12.5") >= 0:
            # Plesk 12.5+
            if not os.path.exists(PLESK_MIGRATOR_DIR):
                os.makedirs(PLESK_MIGRATOR_DIR)
            print("%s --> %s" % (PLESK_MIGRATOR_HOOK, PLESK_MIGRATOR_DIR+PLESK_MIGRATOR_FILE))
            shutil.copy(PLESK_MIGRATOR_HOOK, PLESK_MIGRATOR_DIR)
    elif cp.name == "cPanel":
        # Checking the install version 2.0
        if (LVEMANAGER_VERSION == '2.0'
            and not os.path.exists(ROOT_CPANEL_DIR + '3rdparty/cloudlinux/assets/lvemanager_spa')
            and not os.path.exists('/var/lve/lvemanager_is_not_installed')) \
                or (LVEMANAGER_VERSION == '1.0' and os.path.exists(ROOT_CPANEL_DIR + '3rdparty/cloudlinux/assets/lvemanager_spa')):
            delete_plugin()

        # Prepare static files for SPA
        cpdir = CopyDirectory(SPA_RESOURCE_DIR+'static/', SOURCE_PATH+'cpanel/spa/assets/static/')
        cpdir.process()

        if verCompare(cp.version, "59.9999") < 0:
            print("Warning!!! You use old version of CPanel. Some functional may not work correctly.")
        # fix JSON-styled configs
        exec_command(SOURCE_PATH + 'cpanel/utils/dynamicuictl.py --fix-dynamicui')
        cpdir = CopyDirectory(SOURCE_PATH + "cpanel/images", ROOT_CPANEL_DIR + "images/")
        cpdir.process()

        # Reinstall hooks from scratch to prevent garbage in cases where some
        # files were renamed or removed
        if os.path.exists(SOURCE_PATH + "cpanel/hooks/cpanel-delete-hooks"):
            exec_command(SOURCE_PATH + "cpanel/hooks/cpanel-delete-hooks")
        if os.path.exists(SOURCE_PATH + "cpanel/hooks/cpanel-install-hooks"):
            exec_command(SOURCE_PATH + "cpanel/hooks/cpanel-install-hooks")
        # delete old hooks that are now moved to cllib
        if os.path.exists(SOURCE_PATH + "cpanel/hooks/cpanel-delete-unused-hooks"):
            exec_command(SOURCE_PATH + "cpanel/hooks/cpanel-delete-unused-hooks")

        cpanel_install_user_plugins_from_tar()

        cpanel_use_patches()

        patch_cpanel_config()

        if os.path.exists(SOURCE_PATH+"cpanel/utils/install_module.pl"):
            action_key = ( ( tp == "install" and '-i' ) or '-u' )
            exec_command("perl "+SOURCE_PATH+"cpanel/utils/install_module.pl " + action_key)

        for task in CPANEL_CRON_TASKS:
            add_cron(LVEMANAGER_CRON, *task, check_command=False)

        subprocess.run("/usr/local/cpanel/bin/sprite_generator --all", shell=True, executable='/bin/bash')

        # delete old hooks cause it is not deleted automatically during update
        remove_hooks(_CPANEL_LEGACY_HOOKS_TO_REMOVE)

        if os.path.isfile(CPANEL_SELECTOR_UNPARK_HOOK):
            shutil.copy(CPANEL_SELECTOR_UNPARK_HOOK, CPANEL_SELECTOR_UNPARK_HOOK_SCRIPT)
            install_hooks(_CPANEL_HOOKS)

        register_cpanel_plugin()
        exec_command(SOURCE_PATH + 'utils/dynamicui.py --silent --fix-display-plugin')
        exec_command(SOURCE_PATH + 'cpanel/cpanel_hooks_manage.py -i')

        if os.path.isfile(CPANEL_BASED_DEMO_SERVER_FLAG):
            create_cpanel_based_demo_server()

    elif cp.name == "InterWorx":
        cpdir = CopyDirectory(SOURCE_PATH+"interworx/", ROOT_IWORX_DIR, "*", "*", 0)
        cpdir.process()
        exec_command("chmod -R 755 "+ROOT_IWORX_DIR+"lvemanager")
        add_sudoers('iworx')
        if os.path.exists(SOURCE_PATH+"utils/installsupergrp.sh"):
            exec_command(SOURCE_PATH+"utils/installsupergrp.sh iworx")

    elif cp.name == "ISPManager":
        if verCompare(cp.version, "5") == -1:
            # ISP Manager 4
            res1 = exec_command("/usr/sbin/lvectl --lve-version")[0].strip()
            try:
                i = int(res1)
            except ValueError:
                i = 0

            m_path = "{0}ispmanager/liblve{1}/".format(SOURCE_PATH,
                                                       "0.8" if i < 6 else "1.1")
            for name in ["addon", "etc", "skins/sirius"]:
                CopyDirectory("{0}{1}".format(m_path, name),
                              "{0}{1}".format(ROOT_ISPMGR_DIR, name), "*", "*", 0,
                              copy_file_mode=True).process()

            if verCompare(cp.version, "4.4.4") <= 0:
                # for <=4.4.4 version copy mobile skin. for other verions don`t copy
                CopyDirectory("{}skins/mobile".format(m_path),
                              "{}skins/mobile".format(ROOT_ISPMGR_DIR), "*", "*", 0,
                              copy_file_mode=True).process()

            # Clear ISP Manager's cache and restart it
            shutil.rmtree('/usr/local/ispmgr/var/.xmlcache/ispmgr', True)
            exec_command("/usr/bin/killall ispmgr")
            exec_command(SOURCE_PATH+"utils/delete-isp-plugin.sh")

    elif cp.name == "DirectAdmin":
        if (LVEMANAGER_VERSION == '2.0' and not os.path.exists(ROOT_DA_DIR + 'lvemanager_spa/lvemanager_spa')) \
                or (LVEMANAGER_VERSION == '1.0' and os.path.exists(ROOT_DA_DIR + 'lvemanager_spa/lvemanager_spa')):
            delete_plugin()
        if (not os.path.isdir(ROOT_DA_DIR)):
            os.mkdir(ROOT_DA_DIR)
            exec_command("chown -R diradmin:diradmin "+ROOT_DA_DIR)
            exec_command("chmod -R 755 "+ROOT_DA_DIR)


        CopyDirectory(SOURCE_PATH+"directadmin/lvemanager_spa/", ROOT_DA_DIR+"lvemanager_spa/").process()

        update_da_plugin_conf(SOURCE_PATH+"directadmin/lvemanager_spa/plugin.conf",
                              ROOT_DA_DIR+"lvemanager_spa/plugin.conf")

        exec_command("chown -R diradmin:diradmin "+ROOT_DA_DIR+"lvemanager_spa")
        exec_command("chmod -R 755 "+ROOT_DA_DIR+"lvemanager_spa/admin")
        exec_command("chmod -R 755 " + ROOT_DA_DIR + "lvemanager_spa/reseller")
        exec_command("chmod -R 755 "+ROOT_DA_DIR+"lvemanager_spa/user")

        if not is_panel_feature_supported(Feature.RESELLER_LIMITS):
            # We do not need to show plugin for reseller if reseller_limits not supported
            if os.path.exists(ROOT_DA_DIR+"lvemanager_spa/reseller"):
                shutil.rmtree(ROOT_DA_DIR+"lvemanager_spa/reseller")

        da_install_user_plugins()

        # Clear old versions files
        clear_da_old_files()
        # Fix possibly sysctl options out of sync - LVEMAN-867
        exec_command("/sbin/sysctl -p")
        # Install DA create user hook
        install_da_hook()
        # Add all DA admins to sudoers and clsupergid group
        from clcommon.cpapi import admins
        for user in admins():
            try:
                # Add user to sudoers/clsupergid groups and add sudoer group to /etc/sudoers
                add_unix_user_to_sudoers(user)
            except Exception as e:
                print("Unable to add unix user %s to sudoers group; error: %s\n" % (user, str(e)))
        # Create user for run reseller plugin
        create_da_lvemanager_user()
    else:
        from clcommon import cpapi
        for user in cpapi.admins():
            try:
                # Add user to sudoers/clsupergid groups and add sudoer group to /etc/sudoers
                add_unix_user_to_sudoers(user)
            except Exception as e:
                print("Unable to add unix user %s to sudoers group; error: %s\n" % (user, str(e)))

    # convert locales files for SPA (from yaml to json)
    exec_command(SOURCE_PATH+"utils/sync_locales.py --panel='"+cp.name+"'")

    install_commons()
    # Install to custom panel if exists
    custom_panel_features()
    print('Finished {} script...\n'.format(tp))

# Install DA create user hook
def install_da_hook():
    from clcommon.public_hooks.bundle.directadmin import remove_da_hook
    # Remove old hooks
    remove_da_hook(DA_CREATE_USER_HOOK_FILENAME, DA_CREATE_USER_HOOK_CMD_OLD)
    remove_da_hook(DA_REMOVE_USER_HOOK_FILENAME, DA_REMOVE_USER_HOOK_CMD_OLD)
    remove_da_hook(DA_CREATE_USER_HOOK_FILENAME, DA_CREATE_USER_HOOK_CMD)
    remove_da_hook(DA_REMOVE_USER_HOOK_FILENAME, DA_REMOVE_USER_HOOK_CMD)
    remove_da_hook(DA_CHANGE_DOMAIN_HOOK_FILE, DA_CHANGE_DOMAIN_HOOK_CMD)

def clear_da_old_files():
    if os.path.exists(ROOT_DA_DIR+"new_lvemanager"):
        shutil.rmtree(ROOT_DA_DIR+"new_lvemanager")


def create_da_lvemanager_user():
    PLUGIN_FILE = ROOT_DA_DIR + 'lvemanager_spa/plugin.conf'
    remove_da_custom_lvemanager_users()
    new_user_name = prepare_da_system_lvemanager_user()
    if new_user_name != DA_SUDOERS_USER:
        with open(PLUGIN_FILE) as f:
            file_str = f.read()
        file_str = file_str.replace('reseller_run_as=lvemanager', 'reseller_run_as=' + new_user_name)
        with open(PLUGIN_FILE, "w") as f:
            f.write(file_str)


def remove_da_custom_lvemanager_users():
    import pwd
    lvemanager_users = [p[0] for p in pwd.getpwall() if p[0].startswith('lvemanager_')]
    for username in lvemanager_users:
        exec_command('userdel {}'.format(username))


def prepare_da_system_lvemanager_user():
    new_user_name = DA_SUDOERS_USER
    has_panel_user = os.path.exists('/usr/local/directadmin/data/users/lvemanager')
    has_nonsystem_user = False
    if exec_command_check('id {}'.format(DA_SUDOERS_USER)):
        user_info = exec_command('id {}'.format(DA_SUDOERS_USER))
        if 'clsudoers' in user_info[0]:
            print("Remove old lvemanager user")
            exec_command('userdel {}'.format(DA_SUDOERS_USER))
        else:
            has_nonsystem_user = True
    if has_panel_user or has_nonsystem_user:
        if not exec_command_check('id {}'.format(DA_SUDOERS_USER)):
            # return panel user
            exec_command('adduser --home /home/lvemanager lvemanager')
        # system username for plugin
        new_user_name = '{}_{}'.format(DA_SUDOERS_USER, uuid.uuid4().hex)[:32]
        print('Warning!!! Non-system user "lvemanager" exists. Will be used {} as system user.'.format(new_user_name))

    print("Adding {} user".format(new_user_name))
    groups = ['clsupergid', 'clsudoers'] if is_panel_feature_supported(Feature.LVE) else ['clsudoers']
    exec_command(
        'adduser --system -s /bin/false --groups {} --home /usr/share/l.v.e-manager {}'.format(
            ','.join(groups), new_user_name))
    return new_user_name


def delete_plugin(spa_install=True):
    delete_first_installation_flags()
    # remove crontab files
    if not spa_install:
        remove_cron('lvemanager-selector')
        remove_cron(LVEMANAGER_CRON)
    # remove installed files
    if cp.name == "Plesk" and verCompare (cp.version, "10") >= 0:
        exec_command('/usr/local/psa/bin/extension --uninstall plesk-lvemanager')
        if os.path.exists(SOURCE_PATH+"utils/delete-plesk-plugin.sh"):
            exec_command(SOURCE_PATH+"utils/delete-plesk-plugin.sh")
        if os.path.exists(PLESK_MIGRATOR_DIR+PLESK_MIGRATOR_FILE):
            os.remove(PLESK_MIGRATOR_DIR+PLESK_MIGRATOR_FILE)
    elif cp.name == "cPanel":
        exec_command(SOURCE_PATH+"cpanel/hooks/cpanel-delete-hooks")
        remove_hooks(_CPANEL_HOOKS)
        if verCompare(cp.version, "65.9999") >=0:
            exec_command("sed -i -e '/^#WHMADDON:lvemanager:CloudLinux Manager/d' "+CPANEL_ORIGINAL_FILES_DIR+"CloudLinux.cgi")
        if os.path.exists(SOURCE_PATH+"cpanel/utils/install_module.pl"):
            exec_command("perl "+SOURCE_PATH+"cpanel/utils/install_module.pl -d")
        if os.path.exists(ROOT_CPANEL_DIR+"images/lve"):
            shutil.rmtree(ROOT_CPANEL_DIR+"images/lve")
        # if os.path.exists(ROOT_CPANEL_DIR+"images/CloudLinux_logo.png"):
        #     os.remove(ROOT_CPANEL_DIR+"images/CloudLinux_logo.png")
        if os.path.exists(ROOT_CPANEL_DIR+"images/spa"):
            shutil.rmtree(ROOT_CPANEL_DIR+"images/spa")
        # delete end-user plugins (lveversion)
        cpanel_uninstall_user_plugin_by_tar(SOURCE_PATH + "cpanel/lveversion/user-plugins.tar.bz2")
        # Deleting new resource usage plugin
        cpanel_uninstall_user_plugin_by_tar(SOURCE_PATH + "cpanel/resource_usage/plugin.tar.bz2")

        # Remove links from themes
        cpanel_remove_links_from_themes()

        subprocess.run("/usr/local/cpanel/bin/rebuild_sprites --force", shell=True, executable='/bin/bash')

        if verCompare(cp.version, "69.9032") >= 0:
            custom_path = CPANEL_CUSTOM_PATH + 'Cloudlinux.pm'
            if os.path.exists(custom_path):
                os.unlink(custom_path)

        # rollback patches
        cpanel_rollback_patches()
        exec_command(SOURCE_PATH + 'cpanel/cpanel_hooks_manage.py -d')

    elif cp.name == "InterWorx":
        if os.path.exists(ROOT_IWORX_DIR+"lvemanager"):
            shutil.rmtree(ROOT_IWORX_DIR+"lvemanager")
    elif cp.name == "ISPManager":
        if verCompare(cp.version, "5") == -1:
            # ISP Manager 4
            if os.path.exists(ROOT_ISPMGR_DIR+"addon/lvemanager"):
                shutil.rmtree(ROOT_ISPMGR_DIR+"addon/lvemanager")
            if (os.path.exists("/usr/local/ispmgr/addon/lvemanager.php")):
                os.remove("/usr/local/ispmgr/addon/lvemanager.php")
            if (os.path.exists("/usr/local/ispmgr/addon/LVEPackage.php")):
                os.remove("/usr/local/ispmgr/addon/LVEPackage.php")
            if (os.path.exists("/usr/local/ispmgr/addon/LVEPackageUser.php")):
                os.remove("/usr/local/ispmgr/addon/LVEPackageUser.php")
            if (os.path.exists("/usr/local/ispmgr/etc/ispmgr_mod_lvemanager.xml")):
                os.remove("/usr/local/ispmgr/etc/ispmgr_mod_lvemanager.xml")
            if (os.path.exists("/usr/local/ispmgr/etc/ispmgr_mod_lvepreset.xml")):
                os.remove("/usr/local/ispmgr/etc/ispmgr_mod_lvepreset.xml")
            if (os.path.exists("/usr/local/ispmgr/skins/mobile/mb-lve.png")):
                os.remove("/usr/local/ispmgr/skins/mobile/mb-lve.png")
            if (os.path.exists("/usr/local/ispmgr/skins/mobile/mb-resource.png")):
                os.remove("/usr/local/ispmgr/skins/mobile/mb-resource.png")
            if (os.path.exists("/usr/local/ispmgr/skins/mobile/m-lve.png")):
                os.remove("/usr/local/ispmgr/skins/mobile/m-lve.png")
            if (os.path.exists("/usr/local/ispmgr/skins/mobile/m-resource.png")):
                os.remove("/usr/local/ispmgr/skins/mobile/m-resource.png")
            if (os.path.exists("/usr/local/ispmgr/skins/mobile/refresh_auto.png")):
                os.remove("/usr/local/ispmgr/skins/mobile/refresh_auto.png")
            if (os.path.exists("/usr/local/ispmgr/skins/mobile/refresh.png")):
                os.remove("/usr/local/ispmgr/skins/mobile/refresh.png")
            if (os.path.exists("/usr/local/ispmgr/skins/sirius/mb-lve.png")):
                os.remove("/usr/local/ispmgr/skins/sirius/mb-lve.png")
            if (os.path.exists("/usr/local/ispmgr/skins/sirius/mb-resource.png")):
                os.remove("/usr/local/ispmgr/skins/sirius/mb-resource.png")
            if (os.path.exists("/usr/local/ispmgr/skins/sirius/m-lve.png")):
                os.remove("/usr/local/ispmgr/skins/sirius/m-lve.png")
            if (os.path.exists("/usr/local/ispmgr/skins/sirius/m-resource.png")):
                os.remove("/usr/local/ispmgr/skins/sirius/m-resource.png")
            if (os.path.exists("/usr/local/ispmgr/skins/sirius/refresh_auto.png")):
                os.remove("/usr/local/ispmgr/skins/sirius/refresh_auto.png")
            if (os.path.exists("/usr/local/ispmgr/skins/sirius/refresh.png")):
                os.remove("/usr/local/ispmgr/skins/sirius/refresh.png")
            # Clear ISP Manager's cache and restart it
            shutil.rmtree('/usr/local/ispmgr/var/.xmlcache/ispmgr', True)
            exec_command("/usr/bin/killall ispmgr")
            exec_command(SOURCE_PATH+"utils/delete-isp-plugin.sh")

    elif cp.name == "DirectAdmin":
        # Remove dirs
        if os.path.exists(ROOT_DA_DIR+"new_lvemanager"):
            shutil.rmtree(ROOT_DA_DIR+"new_lvemanager")
        if os.path.exists(ROOT_DA_DIR+"resource_usage"):
            shutil.rmtree(ROOT_DA_DIR+"resource_usage")
        if os.path.exists(ROOT_DA_DIR+"phpselector"):
            shutil.rmtree(ROOT_DA_DIR+"phpselector")
        if os.path.exists(ROOT_DA_DIR+"selector"):
            shutil.rmtree(ROOT_DA_DIR+"selector")
        if os.path.exists(ROOT_DA_DIR+"lvemanager_spa"):
            shutil.rmtree(ROOT_DA_DIR+"lvemanager_spa")
        if os.path.exists(ROOT_DA_DIR + "nodejs_selector"):
            shutil.rmtree(ROOT_DA_DIR + "nodejs_selector")
        if os.path.exists(ROOT_DA_DIR + "python_selector"):
            shutil.rmtree(ROOT_DA_DIR + "python_selector")
    else:
        print("Current panel unsupported. Panel name: "+cp.name+" version: "+cp.version)

    if os.path.exists(SOURCE_PATH+"utils/downgrades/clear-reseller.py"):
        subprocess.run(SOURCE_PATH+"utils/downgrades/clear-reseller.py --unregister", shell=True, executable='/bin/bash')
    if os.path.exists(SOURCE_PATH+"utils/downgrades/clear-new-resource-usage.py"):
        subprocess.run(SOURCE_PATH+"utils/downgrades/clear-new-resource-usage.py", shell=True, executable='/bin/bash')
    if os.path.exists(SOURCE_PATH + "utils/downgrades/migrate-ui-configs.py"):
        subprocess.run(SOURCE_PATH + "utils/downgrades/migrate-ui-configs.py", shell=True, executable='/bin/bash')


def update_php_config():
    """
    Adds defaults for error_reporting option
    (to avoid empty value) and tries to keep
    all user changes untouched
    """
    data = {}
    data_index = []
    if not os.path.isfile(CL_SELECTOR_PHP_CONF_PATH):
        return
    fd = open(CL_SELECTOR_PHP_CONF_PATH,'r')
    directive = None
    for line in fd:
        if '=' not in line:
            continue
        if line.startswith('Directive'):
            directive = line[ line.find('=')+1 : ].strip()
            data_index.append(directive)
            data[directive] = {}
            if not 'data' in data[directive]:
                data[directive]['data'] = {}
            if not 'index' in data[directive]:
                data[directive]['index'] = []
            continue
        if not directive:
            continue
        ( key, value ) = list(map( ( lambda x: x.strip() ), line.split('=', 1) ))
        data[directive]['index'].append(key.lower())
        data[directive]['data'][ key.lower() ] = value
    fd.close()
    if 'error_reporting' not in data:
        return
    if 'default' in data['error_reporting']['data'] and data['error_reporting']['data']['default'] != "":
        return
    if 'default' not in data['error_reporting']['data']:
        data['error_reporting']['index'].insert(0,'default')
    data['error_reporting']['data']['default'] = 'E_ALL & -E_NOTICE'
    fd = open( CL_SELECTOR_PHP_CONF_PATH, 'w' )
    for directive in data_index:
        fd.write( "Directive = %s\n" % directive )
        for item in data[directive]['index']:
            fd.write( "%s = %s\n" % ( item.capitalize().ljust(9), data[directive]['data'][item]) )
        fd.write("\n")
    fd.close()


def cp_supported():
    if cp.name == "Plesk" and verCompare (cp.version, "10") >= 0:
        return True
    if cp.name in ("cPanel", "InterWorx", "ISPManager", "DirectAdmin"):
        return True
    return False


class ControlPanel:
    name = ''
    varsion = ''

    def __init__(self, name, version):
        self.name = name
        self.version = version


def postupcp():
    cpanel_install_user_plugins_from_tar()
    cpanel_use_patches()
    add_lve_limits_to_stats_bar()
    install_cpanel_icons('resourceusage')
    install_cpanel_icons('lveversion')
    exec_command(SOURCE_PATH + 'cpanel/utils/dynamicuictl.py --verbose --sync-conf=all')


def get_release_number():
    """
    Get release number from release name
    """
    matchOb = re.match('^\d+(\.\d+)?', LVEMANAGER_RELEASE, re.I)
    if matchOb:
        release = matchOb.group()
    else:
        release = LVEMANAGER_RELEASE
    return release

def register_cpanel_plugin():
    if verCompare(cp.version, "63.9999") >=0:
        if verCompare(cp.version, '65.9999') >= 0:
            cpanel_config = 'cpanel66'
        else:
            cpanel_config = 'cpanel64'
    else:
        cpanel_config = 'native'

    print('\n'.join(exec_command(SOURCE_PATH + 'utils/install-cpanel-plugin.sh unregister')))
    print('\n'.join(exec_command(SOURCE_PATH + 'utils/install-cpanel-plugin.sh register %s' % cpanel_config)))

def register_plesk_plugin():
    fd = open(ROOT_PLESK_DIR+"plib/modules/plesk-lvemanager/meta.xml", 'w')
    release_number = get_release_number()
    text = """<?xml version="1.0" encoding="utf-8"?>
    <module>
      <id>plesk-lvemanager</id>
      <name>CloudLinux Manager</name>
      <description>CloudLinux Manager ({vr})</description>
      <url>http://cloudlinux.com/</url>
      <version>{version}</version>
      <release>{release}</release>
      <vendor>Cloud Linux</vendor>
      <icon>/images/modules/plesk-lvemanager/addon_CloudLinux_logo.png</icon>
    </module>"""
    fd.write(text.format(
        vr='%s-%s' % (LVEMANAGER_VERSION, release_number),
        version=LVEMANAGER_VERSION, release=release_number)
    )
    fd.close()
    exec_command('/usr/local/psa/bin/extension --register plesk-lvemanager')

def remember_version():
    """
    Remember version and release.
    """
    version_info = "{}-{}".format(LVEMANAGER_VERSION, get_release_number())
    version_file_path = "{}version".format(SOURCE_PATH)

    with open(version_file_path, 'w') as version_file:
        version_file.write(version_info)

def update_da_plugin_conf(src_path, dst_path):
    config = SectionlessConfigParser(strict=False)
    try:
        config.read(dst_path)
    except:
        print("Warning: Cann't open {}".format(dst_path))
        return
    active_value = config.get('__config__', 'active', fallback=None)
    installed_value = config.get('__config__', 'installed', fallback=None)
    try:
        shutil.copy(src_path, dst_path)
    except:
        print("Warning: Cann't update {}".format(dst_path))
        return

    # Set old value previously stored in config. Other values will be inherited from default
    config.read(dst_path)
    if active_value:
        config.set('__config__', 'active', active_value)
    if installed_value:
        config.set('__config__', 'installed', installed_value)
    try:
        with open(dst_path, 'w') as f:
            config.write(f)
    except:
        print("Warning: Cann't save {}".format(dst_path))
        return


FIRST_INSTALL_FLAG = '/var/lve/wizard/is_first_installation.flag'
CLDEPLOY_IGNORE_FLAG = '/var/lve/wizard/ignore_cldeploy.flag'
LVEMANAGER_RPM_FIRST_INSTALL_FLAG = '/var/lve/lvemanager_is_not_installed'

def create_first_installation_flags():
    """
    Detect the first installation of CloudLinux Manager and create flags (files)
    """
    if (os.path.exists(LVEMANAGER_RPM_FIRST_INSTALL_FLAG) or
            (not os.path.isfile('/var/log/cldeploy.log') and not os.path.isfile(CLDEPLOY_IGNORE_FLAG))):
        if not os.path.exists(os.path.dirname(FIRST_INSTALL_FLAG)):
            os.makedirs(os.path.dirname(FIRST_INSTALL_FLAG))
        touch(FIRST_INSTALL_FLAG)
        touch(CLDEPLOY_IGNORE_FLAG)
        try:
            os.unlink(LVEMANAGER_RPM_FIRST_INSTALL_FLAG)
        except OSError:
            pass

def delete_first_installation_flags():
    """
    Delete first installation flags
    """
    for path in (FIRST_INSTALL_FLAG, CLDEPLOY_IGNORE_FLAG, LVEMANAGER_RPM_FIRST_INSTALL_FLAG):
        try:
            os.unlink(path)
        except OSError:
            pass

def add_cl_server_flags():
    """
    Create CloudLinux server flags
    """
    CopyDirectory(CLOUDLINUX_SERVER_FLAGS_SOURCE_DIR, CLOUDLINUX_SERVER_FLAGS_DESTINATION_DIR).process()

def custom_panel_features():
    """
    Copy lvemanager files to directory defined in panel config file
    install and run python server if required
    """
    if not os.path.isfile(PANEL_CONFIG):
        return
    parser = ConfigParser.SafeConfigParser(interpolation=None, strict=False)
    parser.read(PANEL_CONFIG)
    try:
        no_panel_base_path = parser.get('lvemanager_config', 'base_path')
        if no_panel_base_path:
            print('Copy files for other panels to ' + no_panel_base_path)
            CopyDirectory(SOURCE_PATH + 'panelless-version/lvemanager', no_panel_base_path).process()
            CopyDirectory(SPA_RESOURCE_DIR, no_panel_base_path + '/assets').process()
    except ConfigParser.NoSectionError:
        print('WARNING: Cannot copy files for no panel version')

    try:
        run_service = parser.get('lvemanager_config', 'run_service')
        if run_service and int(run_service):
            print('install python dependencies')
            exec_command('/opt/cloudlinux/venv/bin/python3 -m pip install -r '
                         '{}panelless-version/daemon/requirements.txt'.format(SOURCE_PATH))
            print('Enable and start lvemanager')
            if os.path.exists('/usr/bin/systemctl'):
                exec_command('systemctl enable lvemanager')
                exec_command('systemctl restart lvemanager')
            else:
                exec_command('chkconfig lvemanager on')
                exec_command('service lvemanager restart')
    except ConfigParser.NoSectionError:
        print('WARNING: Cannot copy files for no panel version')

    try:
        base_path = parser.get('lvemanager_config', 'base_path')
        vendor_php = parser.get('lvemanager_config', 'vendor_php')
        if os.path.isfile(vendor_php):
            shutil.copy2(vendor_php, base_path)
    except ConfigParser.NoSectionError:
        print('WARNING: Cannot copy vendor.php file for no panel version')
    except ConfigParser.NoOptionError:
        pass

def create_cpanel_based_demo_server():
    """
    Create demo server
    """
    print('Copy files for cpanel-based demo server')
    shutil.copyfile(SOURCE_PATH + 'panelless-version/cpanel-based-demo-server/utils.py', SOURCE_PATH + 'panelless-version/daemon/utils.py')
    shutil.copyfile(SOURCE_PATH + 'panelless-version/cpanel-based-demo-server/templates/app.html', SOURCE_PATH + 'panelless-version/daemon/templates/app.html')
    print('install python dependencies')
    exec_command('/opt/cloudlinux/venv/bin/python3 -m pip install -r '
                 '{}panelless-version/daemon/requirements.txt'.format(SOURCE_PATH))
    print('Enable and start lvemanager')
    if os.path.exists('/usr/bin/systemctl'):
        exec_command('systemctl enable lvemanager')
        exec_command('systemctl restart lvemanager')
    else:
        exec_command('chkconfig lvemanager on')
        exec_command('service lvemanager restart')

def cpanel_install_user_plugins_from_tar():
    # Install PHP Selector for end-user
    if is_panel_feature_supported(Feature.PHP_SELECTOR):
        selector_install_json_path_user_plugins = SOURCE_PATH + "cpanel/lveversion/user-plugins/selector/"
        selector_plugin_tar_user_plugins = SOURCE_PATH + "cpanel/lveversion/user-plugins.tar.bz2"
        cpanel_install_user_plugin_from_tar(selector_install_json_path_user_plugins, selector_plugin_tar_user_plugins)
        cpanel_fix_feature_manager(['cpanel/lveversion/user-plugins/selector/install.json'])

    # install NodeJS Selector
    if is_panel_feature_supported(Feature.NODEJS_SELECTOR):
        nodejs_install_json_path_user_plugins = SOURCE_PATH + "cpanel/lveversion/user-plugins/nodejssel/"
        nodejs_plugin_tar_user_plugins = SOURCE_PATH + "cpanel/lveversion/user-plugins.tar.bz2"
        cpanel_install_user_plugin_from_tar(nodejs_install_json_path_user_plugins, nodejs_plugin_tar_user_plugins)
        cpanel_fix_feature_manager(['cpanel/lveversion/user-plugins/nodejssel/install.json'])

    # install Python Selector
    if is_panel_feature_supported(Feature.PYTHON_SELECTOR):
        python_install_json_path_user_plugins = SOURCE_PATH + "cpanel/lveversion/user-plugins/pythonsel/"
        python_plugin_tar_user_plugins = SOURCE_PATH + "cpanel/lveversion/user-plugins.tar.bz2"
        cpanel_install_user_plugin_from_tar(python_install_json_path_user_plugins, python_plugin_tar_user_plugins)
        cpanel_fix_feature_manager(['cpanel/lveversion/user-plugins/pythonsel/install.json'])

    # install Ruby Selector
    if is_panel_feature_supported(Feature.RUBY_SELECTOR):
        ruby_install_json_path_user_plugins = SOURCE_PATH + "cpanel/lveversion/user-plugins/rubysel/"
        ruby_plugin_tar_user_plugins = SOURCE_PATH + "cpanel/lveversion/user-plugins.tar.bz2"
        cpanel_install_user_plugin_from_tar(ruby_install_json_path_user_plugins, ruby_plugin_tar_user_plugins)
        cpanel_fix_feature_manager(['cpanel/lveversion/user-plugins/rubysel/install.json'])

    # Install Resource usage
    install_json_path_resource_usage = SOURCE_PATH + "cpanel/resource_usage/plugin/"
    plugin_tar_resource_usage = SOURCE_PATH + "cpanel/resource_usage/plugin.tar.bz2"
    cpanel_install_user_plugin_from_tar(install_json_path_resource_usage, plugin_tar_resource_usage)
    if is_panel_feature_supported(Feature.LVE):
        add_lve_limits_to_stats_bar()
    cpanel_fix_feature_manager(['cpanel/resource_usage/plugin/install.json'])


def cpanel_install_user_plugin_from_tar(install_json_path, plugin_tar):
    """
    Install plugin for end-user using script /usr/local/cpanel/scripts/install_plugin.
    To install we need to call the script like /usr/local/cpanel/scripts/install_plugin plugin.tar.bz2 --theme theme.
    The action should be performed for each theme.
    :param install_json_path: string (path where located install.json for the plugin)
    :param plugin_tar: string (path to plugin .tar.bz2 file)
    :return:
    """
    if os.path.exists(install_json_path):
        exec_command("/bin/tar -cjf {} -C {} .".format(plugin_tar, install_json_path))
    if os.path.exists(plugin_tar) and os.path.exists(CPANEL_PLUGIN_INSTALL_SCRIPT):
        for theme in cpanel_get_theme_list():
            exec_command("{} {} --theme {}".format(CPANEL_PLUGIN_INSTALL_SCRIPT, plugin_tar, theme))


def cpanel_uninstall_user_plugin_by_tar(plugin_tar):
    """
    Uninstall plugin for end-user using script /usr/local/cpanel/scripts/uninstall_plugin.
    To remove we need to call the script like /usr/local/cpanel/scripts/uninstall_plugin plugin.tar.bz2 --theme theme.
    To fully remove we need to call this script for each available theme.
    :param plugin_tar: string (path to plugin .tar.bz2 file)
    :return: None
    """
    if os.path.exists(plugin_tar) and os.path.exists(CPANEL_PLUGIN_UNINSTALL_SCRIPT):
        for theme in cpanel_get_theme_list():
            exec_command("{} {} --theme {}".format(CPANEL_PLUGIN_UNINSTALL_SCRIPT, plugin_tar, theme))


def cpanel_get_theme_list():
    """
    Get list of themes for cpanel. Each folder in /usr/local/cpanel/base/frontend/ represent the theme
    :return: list
    """
    if os.path.isdir(CPANEL_ICON_BASE_DIR):
        return next(os.walk(CPANEL_ICON_BASE_DIR), (None, None, []))[1]


def cpanel_remove_links_from_themes():
    """
    Remove links for each theme and each plugin
    :return: None
    """
    for theme in cpanel_get_theme_list():
        for config in CPANEL_DYNAMICUI_CONFIGS:
            config_file = config.format(theme)
            if os.path.exists(config_file):
                exec_command("rm {}".format(config_file))


def da_install_user_plugins():
    """
    Install only end-user plugins for DirectAdmin
    """
    # PHP Selector
    if is_panel_feature_supported(Feature.PHP_SELECTOR):
        CopyDirectory(SOURCE_PATH+"directadmin/phpselector/", ROOT_DA_DIR+"phpselector/").process()
        update_da_plugin_conf(SOURCE_PATH + "directadmin/phpselector/plugin.conf",
                              ROOT_DA_DIR + "phpselector/plugin.conf")
        exec_command("chown -R diradmin:diradmin "+ROOT_DA_DIR+"phpselector")
        exec_command("chmod -R 755 "+ROOT_DA_DIR+"phpselector")
        exec_command("chmod 644 "+ROOT_DA_DIR+"phpselector/plugin.conf")

    # Resource usage
    CopyDirectory(SOURCE_PATH+"directadmin/resource_usage/", ROOT_DA_DIR+"resource_usage/").process()
    if os.path.isfile(ROOT_DA_DIR+"new_lvemanager/plugin.conf"):
        shutil.copy(ROOT_DA_DIR + "new_lvemanager/plugin.conf", ROOT_DA_DIR + "resource_usage/plugin.conf")
    update_da_plugin_conf(SOURCE_PATH + "directadmin/resource_usage/plugin.conf",
                          ROOT_DA_DIR + "resource_usage/plugin.conf")
    exec_command("chown -R diradmin:diradmin "+ROOT_DA_DIR+"resource_usage")
    exec_command("chmod -R 755 "+ROOT_DA_DIR+"resource_usage")
    exec_command("chmod -R 755 "+ROOT_DA_DIR+"resource_usage/user")
    exec_command("chmod 644 "+ROOT_DA_DIR+"resource_usage/plugin.conf")

    # Node.js Selector
    if is_panel_feature_supported(Feature.NODEJS_SELECTOR):
        CopyDirectory(SOURCE_PATH+"directadmin/nodejs_selector/", ROOT_DA_DIR+"nodejs_selector/").process()
        update_da_plugin_conf(SOURCE_PATH + "directadmin/nodejs_selector/plugin.conf",
                              ROOT_DA_DIR + "nodejs_selector/plugin.conf")
        exec_command("chown -R diradmin:diradmin "+ROOT_DA_DIR+"nodejs_selector")
        exec_command("chmod -R 755 "+ROOT_DA_DIR+"nodejs_selector/user")
        exec_command("chmod 644 "+ROOT_DA_DIR+"nodejs_selector/plugin.conf")

    # Python Selector
    if is_panel_feature_supported(Feature.PYTHON_SELECTOR):
        CopyDirectory(SOURCE_PATH + "directadmin/python_selector/", ROOT_DA_DIR + "python_selector/").process()
        update_da_plugin_conf(SOURCE_PATH + "directadmin/python_selector/plugin.conf",
                              ROOT_DA_DIR + "python_selector/plugin.conf")
        exec_command("chown -R diradmin:diradmin "+ROOT_DA_DIR+"python_selector")
        exec_command("chmod -R 755 "+ROOT_DA_DIR+"python_selector/user")
        exec_command("chmod 644 "+ROOT_DA_DIR+"python_selector/plugin.conf")

if __name__ == "__main__":
    detect.getCP()
    cp = ControlPanel(detect.CP_NAME, detect.CP_VERSION)
    try:
        opts, args = getopt.getopt(sys.argv[1:], "hidu", ["help", "postupcp", "install", "delete", "update"])
    except getopt.GetoptError as err:
        # print help information and exit:
        print(str(err))  # will print something like "option -a not recognized"
        usage()
        sys.exit(2)

    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-i", "--install"):
            install_plugin("install")
        elif o in ("-d", "--delete"):
            delete_plugin(spa_install=False)
        elif o in ("-u", "--update"):
            install_plugin("update")
        elif o in ("--postupcp",):
            postupcp()
        else:
            usage()
            sys.exit(2)

Zerion Mini Shell 1.0