#!/usr/bin/env python3
# -*- coding:utf-8 -*-
#############################################################################
# Copyright (c): 2012-2017, Huawei Tech. Co., Ltd.
# Description : PreInstallUtility.py is a utility to install the cluster on local node.
#############################################################################
from __future__ import print_function

try:
    import getopt
    import sys
    import os
    import socket
    import subprocess
    import time
    import pwd
    import grp
    import stat

    sys.path.append(sys.path[0] + "/../")
    from gspylib.common.GaussLog import GaussLog
    from gspylib.common.ParameterParsecheck import Parameter
    from gspylib.common.Common import DefaultValue, ClusterCommand
    from gspylib.common.OMCommand import OMCommand
    from gspylib.common.LocalBaseOM import LocalBaseOM
    from gspylib.common.ErrorCode import ErrorCode
    from gspylib.os.gsfile import g_file
    from gspylib.os.gsOSlib import g_OSlib
    from gspylib.os.platform import support_platform
    from gspylib.os.gsplatform import g_Platform, Platform
    from gspylib.common.VersionInfo import VersionInfo
    from gspylib.os.gsservice import g_service
    from gspylib.os.gsnetwork import g_network

except ImportError as ie:
    sys.exit("[GAUSS-52200] : Unable to import module: %s." % str(ie))

ACTION_PREPARE_PATH = "prepare_path"
ACTION_CHECK_OS_VERSION = "check_os_Version"
ACTION_CREATE_OS_USER = "create_os_user"
ACTION_CHECK_OS_USER = "check_os_user"
ACTION_CREATE_CLUSTER_PATHS = "create_cluster_paths"
ACTION_SET_FINISH_FLAG = "set_finish_flag"
ACTION_SET_USER_ENV = "set_user_env"
ACTION_SET_TOOL_ENV = "set_tool_env"
ACTION_PREPARE_USER_CRON_SERVICE = "prepare_user_cron_service"
ACTION_PREPARE_USER_SSHD_SERVICE = "prepare_user_sshd_service"
ACTION_SET_WARNING_ENV = "set_warning_env"
ACTION_SET_LIBRARY = "set_library"
ACTION_SET_CGROUP = "set_cgroup"
ACTION_SET_VIRTUALIP = "set_virtualIp"
ACTION_CHECK_HOSTNAME_MAPPING = "check_hostname_mapping"
ACTION_INIT_GAUSSLOG = "init_gausslog"
ACTION_CHECK_ENVFILE = "check_envfile"
ACTION_SET_ARM_OPTIMIZATION = "set_arm_optimization"
FLAGS_WRITE = os.O_WRONLY | os.O_CREAT | os.O_TRUNC

g_nodeInfo = None
envConfig = {}
configuredIps = []
checkOSUser = False
g_component_list = []
instance_type_set = ()

#####################################################
# syslog variables
#####################################################
RSYSLOG = "rsyslog"
SYSLOG_NG = "syslog-ng"
RSYSLOG_CONFIG_FILE = "/etc/rsyslog.conf"
SYSLOG_NG_CONFIG_FILE = "/etc/syslog-ng/syslog-ng.conf"
SYSLOG_NG_CONFIG_FILE_SERVER = "/etc/sysconfig/syslog"
SYSTEMD_JOURNALD_CONF = "/etc/systemd/journald.conf"
RSYSLOG_FACILITY_LEVEL = "local3.*"
AP_RSYSLOG_FACILITY_LEVEL = ":msg,contains,\"MPPDB\""
SYSLOG_NG_FACILITY = "local3"
SYSLOG_NG_LEVEL = "debug..emerg"
AP_SERVER_SYSLOG_FILE = "/var/log/syslog_MPPDB"
IMJOURNAL_RATELIMIT_INTERVAL = 1
IMJOURNAL_RATELIMIT_BURST = 50000
SYSTEMLOG_RATELIMIT_INTERVAL = 1
SYSTEMLOG_RATELIMIT_BURST = 50000
ARM_PLATE = False
functionName = "PreInstallUtility"


class ConfigVip:

    def __init__(self, back_ip_nic, vip_num, configured_ip, net_mask, tmp_file):
        self.back_ip_nic = back_ip_nic
        self.vip_num = vip_num
        self.configured_ip = configured_ip
        self.net_mask = net_mask
        self.tmp_file = tmp_file


class PreInstall(LocalBaseOM):
    """
    install the cluster on local node
    """

    def __init__(self):
        LocalBaseOM.__init__(self)
        self.action = ""
        self.userInfo = ""
        self.user = ""
        self.group = ""
        self.clusterConfig = ""
        self.preparePath = ""
        self.checkEmpty = False
        self.envParams = []
        self.warningIp = ""
        self.warningNode = ""
        self.warningType = 1
        self.logFile = ""
        self.mpprcFile = ""
        self.clusterToolPath = ""
        self.cgroupMountDir = ""
        self.tmpFile = ""
        self.logAction = ""
        self.logUuid = ""
        self.logStep = 0

    def initGlobals(self):
        """
        init global variables
        input : NA
        output: NA
        """
        global instance_type_set
        self.initLogger(functionName)
        if self.clusterConfig != "":
            self.readConfigInfoByXML()

    def initNodeInfo(self):
        """
        function:
          init node info
        precondition:
          self.clusterInfo has been initialized
        input : NA
        output: NA
        """
        global g_nodeInfo

        hostName = socket.gethostname()
        g_nodeInfo = self.clusterInfo.getDbNodeByName(hostName)
        if g_nodeInfo is None:
            self.logger.logExit(ErrorCode.GAUSS_516["GAUSS_51620"] % "local" + " It is not a host named %s." % hostName)

    def usage(self):
        """
Usage:
    python3 PreInstallUtility.py -t action -u user -T warning_type [-g group] [-X xmlfile] [-P path]
    [-Q clusterToolPath] [-D mount_path] [-e "envpara=value" [...]] [-w warningserverip] [-h nodename]
    [-s mpprc_file] [--check_empty] [-l log]
Common options:
    -t                                The type of action.
    -u                                The OS user of cluster.
    -g                                The OS user's group of cluster.
    -X                                The XML file path.
    -P                                The path to be check.
    -Q                                The path of cluster tool.
    -D                                The path that Cgroup will mount on.
    -e "envpara=value"                The OS user environment variable.
    --check_empty                     Check path empty.
    -T                                'warningtype=1' will use N9000/FI format, 'warningtype=2' will use ICBC format
    -w                                The IP of warning server.
    -s                                The path of MPP environment file.
    -h                                The nodename of warning server.
    -l                                The path of log file.
    --help                            Show this help, then exit.
        """
        print(self.usage.__doc__)

    def parseCommandLine(self):
        """
        function: Check parameter from command line
        input : NA
        output: NA
        """
        try:
            opts, args = getopt.getopt(sys.argv[1:], "t:u:g:X:P:Q:D:e:T:w:s:h:l:f:",
                                       ["check_empty", "help", "log-action=", "log-uuid=", "log-step="])
        except Exception as e:
            self.usage()
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"] % str(e))

        if len(args) > 0:
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"] % str(args[0]))

        parameter_map = {"-t": self.action, "-u": self.user, "-g": self.group, "-X": self.clusterConfig,
                         "-P": self.preparePath, "-Q": self.clusterToolPath, "-D": self.cgroupMountDir,
                         "-T": self.warningType, "-w": self.warningIp, "-h": self.warningNode,
                         "-s": self.mpprcFile, "-f": self.tmpFile,
                         "--log-action": self.logAction, "--log-uuid": self.logUuid, "--log-step": self.logStep}
        parameter_keys = parameter_map.keys()

        for (key, value) in opts:
            if key == "--help":
                self.usage()
                sys.exit(0)
            elif key in parameter_keys:
                parameter_map[key] = value
            elif key == "-e":
                self.envParams.append(value)
            elif key == "--check_empty":
                self.checkEmpty = True
            elif key == "-l":
                self.logFile = os.path.realpath(value)
            Parameter.checkParaVaild(key, value)

        self.action = parameter_map["-t"]
        self.user = parameter_map["-u"]
        self.group = parameter_map["-g"]
        self.clusterConfig = parameter_map["-X"]
        self.preparePath = parameter_map["-P"]
        self.clusterToolPath = parameter_map["-Q"]
        self.cgroupMountDir = parameter_map["-D"]
        self.warningType = parameter_map["-T"]
        self.warningIp = parameter_map["-w"]
        self.warningNode = parameter_map["-h"]
        self.mpprcFile = parameter_map["-s"]
        self.tmpFile = parameter_map["-f"]
        self.logAction = parameter_map["--log-action"]
        self.logUuid = parameter_map["--log-uuid"]
        self.logStep = parameter_map["--log-step"]

    def checkParameter(self):
        """
        function: Check parameter from command line
        input : NA
        output: NA
        """
        if self.user == "" and self.action != ACTION_SET_VIRTUALIP:
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'u' + ".")

        try:
            if (self.action == ACTION_PREPARE_PATH
                    or self.action == ACTION_CREATE_CLUSTER_PATHS
                    or self.action == ACTION_SET_FINISH_FLAG
                    or self.action == ACTION_SET_USER_ENV):
                DefaultValue.checkUser(self.user, False)
        except Exception as e:
            GaussLog.exitWithError(str(e))
        parameter_list = [ACTION_CHECK_OS_VERSION, ACTION_SET_FINISH_FLAG, ACTION_SET_USER_ENV, ACTION_SET_LIBRARY,
                          ACTION_PREPARE_USER_CRON_SERVICE, ACTION_PREPARE_USER_SSHD_SERVICE,
                          ACTION_SET_VIRTUALIP, ACTION_INIT_GAUSSLOG, ACTION_CHECK_ENVFILE,
                          ACTION_SET_ARM_OPTIMIZATION]
        if self.action == "":
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 't' + ".")
        function_map = {ACTION_PREPARE_PATH: self.checkPreparePathParameter,
                        ACTION_CREATE_OS_USER: self.checkCreateOSUserParameter,
                        ACTION_CHECK_OS_USER: self.checkCreateOSUserParameter,
                        ACTION_CREATE_CLUSTER_PATHS: self.checkCreateClusterPathsParameter,
                        ACTION_SET_TOOL_ENV: self.checkSetToolEnvParameter,
                        ACTION_SET_WARNING_ENV: self.checkSetWarningEnvParameter,
                        ACTION_SET_CGROUP: self.checkSetCgroupParameter,
                        ACTION_CHECK_HOSTNAME_MAPPING: self.checkHostnameMappingParameter}
        function_map_keys = function_map.keys()
        if self.action in function_map_keys:
            function_map[self.action]()
        elif self.action in parameter_list:
            pass
        else:
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50004"] % "t")

        if self.mpprcFile != "":
            if not os.path.isabs(self.mpprcFile):
                GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50213"] % "mpprc file")
                # 1.set tool env is the first time we use this mpprc file, so we can check and create it.
            # 2.in other scene, the mpprc file should have exist, so we just check its exists
            if self.action == ACTION_SET_TOOL_ENV:
                self.prepareMpprcFile()
            elif self.action == ACTION_CHECK_ENVFILE:
                pass
            else:
                if not os.path.exists(self.mpprcFile):
                    GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50201"] % self.mpprcFile)

        if self.logFile == "":
            self.logFile = DefaultValue.getOMLogPath(DefaultValue.LOCAL_LOG_FILE, self.user, "")
        self.checkTmpFile()

        if self.logStep != "":
            self.logStep = int(self.logStep)
        else:
            self.logStep = 0

    def checkTmpFile(self):
        """
        """
        if self.tmpFile != "":
            if os.path.islink(self.tmpFile):
                GaussLog.exitWithError("[GAUSS-50212] : The file [%s] is a link file." % self.tmpFile)
            startsFlag = "/tmp/gauss_set_virtualIP"
            if not self.tmpFile.startswith(startsFlag):
                GaussLog.exitWithError(
                    "[GAUSS-50212] : The prefix of the file [%s] should be '%s'." % (self.tmpFile, startsFlag))

    def prepareMpprcFile(self):
        """
        function: prepare MPPRC file, include path and permission
        input : NA
        output: NA
        """
        mpprcFilePath, _ = os.path.split(self.mpprcFile)
        ownerPath = self.mpprcFile
        if not os.path.exists(self.mpprcFile):
            while True:
                # find the top path to be created
                (ownerPath, dirName) = os.path.split(ownerPath)
                if os.path.exists(ownerPath) or dirName == "":
                    ownerPath = os.path.join(ownerPath, dirName)
                    break

        try:
            # for internal useage, we should set mpprc file permission to 644 here, and change to 640 later.
            g_file.createDirectory(mpprcFilePath, True)
            if os.path.exists(self.mpprcFile):
                pass
            else:
                g_file.createFile(self.mpprcFile, False)
            g_file.changeMode(DefaultValue.KEY_DIRECTORY_MODE, ownerPath, True, "shell")
            g_file.changeMode(DefaultValue.HOSTS_FILE, self.mpprcFile, False, "shell")

            # if given group info in cmdline, we will change the mpprc file owner, otherwise,
            # will not change the mpprc file owner.
            if self.group != "":
                g_file.changeOwner(self.user, ownerPath, True, "shell")
        except Exception as e:
            raise Exception(str(e))

    def checkPreparePathParameter(self):
        """
        function: check whether PreparePath parameter is right
        input : NA
        output: NA
        """
        if self.preparePath == "":
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'P' + ".")
        if not os.path.isabs(self.preparePath):
            GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50213"] % self.preparePath)
        if self.group == "":
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'g' + ".")

    def checkCreateOSUserParameter(self):
        """
        function: check whether CreateOSUser parameter is right
        input : NA
        output: NA
        """
        if self.group == "":
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'g' + ".")

    def checkCreateClusterPathsParameter(self):
        """
        function: check whether CreateClusterPaths parameter is right
        input : NA
        output: NA
        """
        if self.group == "":
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'g' + ".")

        if self.clusterConfig == "":
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'X' + ".")
        if not os.path.exists(self.clusterConfig):
            GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50201"] % self.clusterConfig)
        if not os.path.isabs(self.clusterConfig):
            GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50213"] % "configuration file")

    def checkSetToolEnvParameter(self):
        """
        function: check whether SetToolEnv parameter is right
        input : NA
        output: NA
        """
        if self.clusterToolPath == "":
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'Q' + ".")

    def checkSetCgroupParameter(self):
        """
        function: check whether SetCgroup parameter is right
        input : NA
        output: NA
        """
        if self.clusterToolPath == "":
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'Q' + ".")
        if self.cgroupMountDir != "":
            if not os.path.isabs(self.cgroupMountDir):
                GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50213"] % "Cgroup mount directory")

    def checkSetWarningEnvParameter(self):
        """
        function: check whether SetWarningEnv parameter is right
        input : NA
        output: NA
        """
        if self.warningType == "":
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'T' + ".")
        self.warningType = int(self.warningType)
        if self.warningType == 2 and self.warningIp == "":
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'w' + ".")

    def checkHostnameMappingParameter(self):
        """
        function: check whether HostnameMapping parameter is right
        input : NA
        output: NA
        """
        if self.clusterConfig == "":
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'X' + ".")
        if not os.path.exists(self.clusterConfig):
            GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50201"] % self.clusterConfig)
        if not os.path.isabs(self.clusterConfig):
            GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50213"] % "configuration file")

    def checkOSVersion(self):
        """
        function:
          check if OS version is supported
        input : NA
        output: NA
        """
        self.logger.log("Checking OS version.")
        try:
            if not DefaultValue.checkOsVersion():
                self.logger.logExit(ErrorCode.GAUSS_519["GAUSS_51900"])
        except Exception as e:
            self.logger.logExit(str(e))

        self.logger.log("Successfully checked OS version.")

    def prepareGivenPath(self, onePath, checkEmpty=True, checkSize=True):
        """
        function:
          make sure the path exist and user has private to access this path
        precondition:
          1.checkEmpty is True or False
          2.checkSize is True or False
          3.user and group has been initialized
          4.path list has been initialized
          5.path in path list is absolute path
        postcondition:
          1.
        input:
          1.path list
          2.checkEmpty
          3.checkSize
          4.path owner
        output:
          paths in os
        hiden info:na
        ppp:
        for each path in the path list
            save the path
            if path exist
                if need check empty
                    check empty
            else
                find the top path to be created
            create the path
            chown owner
            check permission
            check path size
        """
        self.logger.debug("Preparing path [%s]." % onePath)
        ownerPath = onePath
        if os.path.exists(onePath):
            if checkEmpty:
                fileList = os.listdir(onePath)
                if "pg_location" in fileList:
                    fileList.remove("pg_location")
                if len(fileList) != 0:
                    self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50202"] % onePath)
            # check the owner of 'onepath' whether it is exist; if not, change it's owner to the cluster user
            DefaultValue.checkPathandChangeOwner(onePath, self.user, self.group, DefaultValue.KEY_DIRECTORY_MODE)
        else:
            while True:
                # find the top path to be created
                (ownerPath, dirName) = os.path.split(ownerPath)
                if os.path.exists(ownerPath) or dirName == "":
                    ownerPath = os.path.join(ownerPath, dirName)
                    break
            # create the given path
            self.logger.debug("Path [%s] does not exist. Please create it." % onePath)
            self.makeDirsInRetryMode(onePath, DefaultValue.KEY_DIRECTORY_MODE)

        # if the path already exist, just change the top path mode, else change mode with -R
        # do not change the file mode in path if exist
        # found error: given path is /a/b/c, script path is /a/b/c/d, then change mode with -R
        # will cause an error
        try:
            if ownerPath != onePath:
                g_file.changeOwner(self.user, ownerPath, True, "shell")
                g_file.changeMode(DefaultValue.KEY_DIRECTORY_MODE, ownerPath, True, "shell")
            else:
                g_file.changeOwner(self.user, ownerPath, False, "shell")
        except Exception as e:
            raise Exception(str(e))
        # check permission
        if self.action == ACTION_PREPARE_PATH:
            # for tool path, we only need check enter permission
            if not self.checkPermission(self.user, onePath, True):
                self.logger.logExit(ErrorCode.GAUSS_501["GAUSS_50100"] % (onePath, self.user))
        else:
            if not self.checkPermission(self.user, onePath):
                self.logger.logExit(ErrorCode.GAUSS_501["GAUSS_50102"] % (onePath, self.user))
        # check path size
        if checkSize:
            DefaultValue.checkDirSize(onePath, DefaultValue.INSTANCE_DISK_SIZE, self.logger)

        self.logger.debug("Successfully prepared path.")

    def makeDirsInRetryMode(self, onePath, dirMode, retryTimes=3):
        """
        function: command for creating path, if failed then retry.Retry for 3 times
        input : onePath,dirMode,retryTimes
        output: NA
        """
        retry = 1
        while True:
            try_flag = g_file.createDirectory(onePath, True, dirMode)
            if try_flag is True:
                break
            if retry >= retryTimes:
                self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50206"] % onePath)
            retry += 1

    def checkPermission(self, username, originalPath, check_enter_only=False):
        """
        function:
          check if given user has operation permission for given path
        precondition:
          1.user should be exist
          2.originalPath should be an absolute path
          3.caller should has root privilege
        postcondition:
          1.return True or False
        input : username,originalPath,check_enter_only
        output: True/False
        """
        # action: check and modify the permission of path before do check
        # For the scene: After delete the user when execute gs_postuninstall --delete-user,
        # the owner of GPHOME path becomes no owner; when execute gs_preinstall secondly,
        # report permission error about GPHOME
        DefaultValue.checkPathandChangeOwner(originalPath, self.user, self.group, DefaultValue.KEY_DIRECTORY_MODE)
        cmd = "su - %s -c \"cd '%s'\"" % (username, originalPath)
        status = os.system(cmd)
        if status != 0:
            return False

        if check_enter_only:
            return True

        testFile = os.path.join(originalPath, "touch.tst")
        cmd = "su - %s -c 'touch %s && chmod %s %s' >/dev/null 2>&1" % (
            username, testFile, DefaultValue.KEY_FILE_MODE, testFile)
        status = os.system(cmd)
        if status != 0:
            return False

        cmd = "su - %s -c 'echo aaa > %s' >/dev/null 2>&1" % (username, testFile)
        status = os.system(cmd)
        if status != 0:
            cmd = "rm -f '%s' >/dev/null 2>&1" % testFile
            os.system(cmd)
            return False

        cmd = "rm -f '%s' >/dev/null 2>&1" % testFile
        status = os.system(cmd)
        if status != 0:
            return False

        return True

    def checkMappingForHostName(self):
        """
        function: Checking hostname mapping
        input : NA
        output: NA
        """
        self.logger.debug("Checking hostname mapping.")
        try:
            OMCommand.checkHostnameMapping(self.clusterInfo, self.logFile)
        except Exception as e:
            self.logger.logExit(str(e))

        self.logger.debug("Successfully checked hostname mapping.")

    def checkPasswdIsExpires(self):
        """
        function: Check if user password is expires
        input : user name
        output: False or True
        """
        cmd = g_file.SHELL_CMD_DICT["checkPassword"] % (self.user, "'^Password expires'")
        (timestatus, output) = subprocess.getstatusoutput(cmd)
        if timestatus != 0:
            self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error:\n%s" % output)
        result = output.split(":")[1].strip()
        try:
            passwd_expiretime = time.strptime(result, "%b %d, %Y")
        except Exception:
            return False
        local_time_string = time.strftime("%b %d, %Y")
        local_time = time.strptime(local_time_string, "%b %d, %Y")
        expire_seconds = int(time.mktime(passwd_expiretime))
        lcoalTime_seconds = int(time.mktime(local_time))
        if expire_seconds < lcoalTime_seconds:
            return True
        else:
            return False

    def delTempFile(self, filename):
        """
        function: delete temp file
        input : NA
        output: NA
        """
        try:
            if os.path.isfile(filename):
                g_file.removeFile(filename, "shell")
        except Exception as e:
            raise Exception(str(e))

    def addAllowUser(self, user):
        """
        function: Add "user" to AllowUsers in /etc/ssh/sshd_config if necessary.
        input:
            user: the user name in string.
        output:
            1: Successfully added.
            0: Already added, or "AllowUsers" is disabled, nothing to do.
        """
        # If "AllowUsers" in sshd is enabled, only specified users can be authenticated.
        # So we need to add the newly created user to white list.
        sshd_config = "/etc/ssh/sshd_config"
        allowUsersCmd = "cat " + sshd_config + " | grep '\\<AllowUsers\\>'"
        (status, output) = subprocess.getstatusoutput(allowUsersCmd)

        allowUsersRes = output
        # No results found. "grep" returns non-zero if nothing grepped.
        # AllowUsers in sshd_config is disabled.
        if (status != 0) and (output is None or len(output) == 0):
            self.logger.debug("'AllowUers' of sshd_config is disabled.")
            return 0
        elif status != 0:
            # It really failed.
            self.logger.logExit(ErrorCode.GAUSS_503["GAUSS_50321"] % "AllowUsers" +
                                " Command: %s. Error: \n%s" % (allowUsersCmd, output))
        else:
            allowUsersRes = str(output).lstrip().lstrip("\t")
            if allowUsersRes.find('#') == 0:
                return 0
            elif allowUsersRes.find('#') > 0:
                allowUsersRes = allowUsersRes[0:allowUsersRes.find('#')]
            allowUsersRes = allowUsersRes.replace("\n", "\\n")

        if self.user not in allowUsersRes.split(' '):
            setAllowUsersCmd = "sed -i '/\\<AllowUsers\\>/d' %s" % sshd_config
            (status, output) = subprocess.getstatusoutput(setAllowUsersCmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % setAllowUsersCmd + " Error:\n%s" % output)
            g_Platform.setKeyValueInSshd(allowUsersRes, user)
        # Attention: here we will not restart sshd service, as it will be done in "prepareUserSshdService".
        self.logger.debug("User '%s' added to 'AllowUsers' of %s successfully." % (user, sshd_config))
        return 1

    def check_group(self):
        """
        Check if group exists
        :return: groupstatus
        """
        cmd = "cat /etc/group | awk -F [:] '{print $1}' | grep '^%s$'" % self.group
        (groupstatus, groupoutput) = subprocess.getstatusoutput(cmd)
        if groupstatus != 0:
            self.logger.debug("Command for checking group exists: %s." % cmd + " Error:\n%s" % groupoutput)
        return groupstatus

    def check_user(self):
        """"
        """
        userstatus = 0
        # Check if user exists
        try:
            DefaultValue.getUserId(self.user)
            # check user passwd is Expires
            if self.checkPasswdIsExpires():
                self.logger.logExit(ErrorCode.GAUSS_503["GAUSS_50307"])
        except Exception:
            self.logger.debug("User[%s] not exists." % self.user)
            userstatus = 1
        # check if the user is correct in /home/user path
        if userstatus == 1:
            userHomePath = "/home/%s" % self.user
            if os.path.exists(userHomePath):
                homePathUser, _ = g_file.getfileUser(userHomePath)
                if homePathUser != self.user:
                    self.logger.logExit(ErrorCode.GAUSS_503["GAUSS_50315"] % (self.user, userHomePath) +
                                        "\nPlease check if the path %s is already created by other users or if the"
                                        "parameters in gs_preinstall specify this path." % userHomePath)
        return userstatus

    def createOSUser(self):
        """
        function: Create OS user and group
        input : NA
        output: NA
        """
        self.logger.debug("Creating OS user on local host.")
        tempFile = "/tmp/temp.%s" % self.user
        userstatus = self.check_user()
        groupstatus = self.check_group()
        # user exists and input group not exists
        if userstatus == 0 and groupstatus != 0:
            self.logger.logExit(ErrorCode.GAUSS_503["GAUSS_50305"])
        # user exists and group exists
        if userstatus == 0 and groupstatus == 0:
            # UID is 0
            if pwd.getpwnam(self.user).pw_uid == 0:
                self.logger.logExit(ErrorCode.GAUSS_503["GAUSS_50302"])
            # user's group != input group
            groupInfo = grp.getgrgid(pwd.getpwnam(self.user).pw_gid).gr_name
            if self.group != groupInfo:
                self.logger.logExit(ErrorCode.GAUSS_503["GAUSS_50305"])
            self.delTempFile(tempFile)
            return

        if checkOSUser:
            sys.exit(1)
        # user does not exist and group does not exist
        if userstatus != 0 and groupstatus != 0:
            self.logger.debug("Creating OS user [%s:%s]." % (self.user, self.group))
            cmd = "groupadd %s && useradd -m -g %s %s" % (self.group, self.group, self.user)
            status, output = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50206"] % 'OS user' +
                                    " Command: %s. Error: \n%s" % (cmd, output))
        # user does not exist and group exists
        if userstatus != 0 and groupstatus == 0:
            self.logger.debug("Creating OS user [%s:%s]." % (self.user, self.group))
            cmd = "useradd -m -g %s %s" % (self.group, self.user)
            status, output = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50206"] % 'OS user' +
                                    " Command: %s. Error: \n%s" % (cmd, output))

        self.logger.debug("Changing user password.")
        try:
            # check if the file is a link
            g_OSlib.checkLink(tempFile)
            with open(tempFile, "r") as fp:
                password = fp.read()
            self.delTempFile(tempFile)
        except Exception:
            self.delTempFile(tempFile)
            self.logger.logExit(ErrorCode.GAUSS_503["GAUSS_50311"] % "user")
        cmd = "echo '%s:%s' | chpasswd" % (self.user, password)
        status, output = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_503["GAUSS_50311"] % self.user + " Error: \n%s" % output)

    def createClusterPaths(self):
        """
        function:
          create all paths for cluster
            install path
            tmp path
            data path
            log path
        precondition:
          1.self.clusterInfo has been initialized
        postcondition:
          1.all path exist and have proper authority
        input:NA
        output:na
        hiden info:
          current info of each path
        """
        self.logger.debug("Creating paths for cluster.")
        if self.checkFinishFlag():
            needCheckEmpty = False
        else:
            needCheckEmpty = True

        self.initNodeInfo()
        self.prepareGaussLogPath()
        self.prepareInstallPath(needCheckEmpty)
        self.prepareTmpPath(needCheckEmpty)
        self.prepareDataPath(needCheckEmpty)
        self.preparePluginPath()

        self.logger.debug("Successfully created paths for cluster.")

    def prepareGaussLogPath(self):
        """
        function: Prepare Gausslog Path
        input : NA
        output: NA
        """
        self.logger.debug("Creating log path.")
        gaussdb_dir = self.clusterInfo.logPath

        self.logger.debug("Checking %s directory [%s]." % (VersionInfo.PRODUCT_NAME, gaussdb_dir))
        if not os.path.exists(gaussdb_dir):
            self.makeDirsInRetryMode(gaussdb_dir, DefaultValue.KEY_DIRECTORY_MODE)

        try:
            # change gaussdb dir mode
            g_file.changeMode(DefaultValue.DIRECTORY_MODE, gaussdb_dir, False, "shell")
            g_file.changeOwner(self.user, gaussdb_dir, False, "shell")
        except Exception as e:
            raise Exception(str(e))

        # make user log dir
        user_dir = "%s/%s" % (self.clusterInfo.logPath, self.user)
        self.prepareGivenPath(user_dir, False)

        # change the directory permission. Remove hidden folders
        cmdDir = "find '%s' -type d ! -name '.*' -exec chmod '%s' {} \;" % (user_dir, DefaultValue.DIRECTORY_MODE)
        (status, diroutput) = subprocess.getstatusoutput(cmdDir)
        self.logger.debug("Command to chmod the directory in directory[%s] " % user_dir)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50201"] % user_dir + " Error:\n%s" % diroutput)
        # change the file permission
        ClusterCommand.getchangeFileModeCmd(user_dir)

        # change user log dir owner
        try:
            g_file.changeOwner(self.user, user_dir, True, "shell", retryFlag=True, retryTime=15, waiteTime=1)
        except Exception as e:
            raise Exception(str(e))
        self.logger.debug("Successfully created log path.")

    def prepareTmpPath(self, needCheckEmpty):
        """
        function: Prepare temporary path
        input : needCheckEmpty
        output: NA
        """
        self.logger.debug("Creating temporary path.")
        tmpDir = DefaultValue.getTmpDir(self.user, self.clusterConfig)
        self.prepareGivenPath(tmpDir, needCheckEmpty)
        self.logger.debug("Successfully created temporary path.")

    def prepareDataPath(self, needCheckEmpty):
        """
        function: Prepare data path
        input : needCheckEmpty
        output: NA
        """
        self.logger.debug("Creating data path.")

        self.logger.debug("Checking CM datadir.")
        self.prepareGivenPath(g_nodeInfo.cmDataDir, False)

        self.logger.debug("Checking CMAgent configuration.")
        for cmaInst in g_nodeInfo.cmagents:
            self.prepareGivenPath(cmaInst.datadir, needCheckEmpty)

        self.logger.debug("Checking CMServer configuration")
        for cmsInst in g_nodeInfo.cmservers:
            self.prepareGivenPath(cmsInst.datadir, needCheckEmpty)

        self.logger.debug("Checking GTM configuration.")
        for gtmInst in g_nodeInfo.gtms:
            self.prepareGivenPath(gtmInst.datadir, needCheckEmpty)

        self.logger.debug("Checking CN configuration.")
        for cooInst in g_nodeInfo.coordinators:
            self.prepareGivenPath(cooInst.datadir, needCheckEmpty)
            if len(cooInst.ssdDir) != 0:
                self.prepareGivenPath(cooInst.ssdDir, needCheckEmpty)

        self.logger.debug("Checking DN configuration.")
        for dnInst in g_nodeInfo.datanodes:
            self.prepareGivenPath(dnInst.datadir, needCheckEmpty)
            if len(dnInst.ssdDir) != 0:
                self.prepareGivenPath(dnInst.ssdDir, needCheckEmpty)

        self.logger.debug("Checking ETCD configuration.")
        for etcdInst in g_nodeInfo.etcds:
            self.prepareGivenPath(etcdInst.datadir, needCheckEmpty)

        self.logger.debug("Successfully created data path.")

    def prepareInstallPath(self, needCheckEmpty):
        """
        function: Prepare installation path
        input : needCheckEmpty
        output: NA
        """
        self.logger.debug("Creating installation path.")
        installPath = self.clusterInfo.appPath
        self.prepareGivenPath(installPath, needCheckEmpty)
        os.chown(os.path.dirname(installPath),
                 pwd.getpwnam(self.user).pw_uid,
                 pwd.getpwnam(self.user).pw_gid)
        os.chmod(os.path.dirname(installPath), 0o700)

        self.logger.debug("Successfully created installation path.")

    def preparePluginPath(self):
        """
        function: Prepare plugin path
        input : NA
        output: NA
        """
        self.logger.debug("Creating plugin path.")
        plugin_path = "%s/plugin" % self.clusterToolPath
        if not os.path.exists(plugin_path):
            self.makeDirsInRetryMode(plugin_path, DefaultValue.KEY_DIRECTORY_MODE)
        os.chown(os.path.dirname(plugin_path),
                 pwd.getpwnam(self.user).pw_uid,
                 pwd.getpwnam(self.user).pw_gid)
        os.chmod(os.path.dirname(plugin_path), 0o700)
        self.logger.debug("Successfully created plugin path.")

    def prepareUserCronService(self):
        """
        function:
        1.set cron bin permission
        2.check and make sure user have permission to use cron
        3.restart cron service
        input : NA
        output: NA
        """
        self.logger.debug("Preparing user cron service.")
        # 1.set crontab file permission
        crontabFile = "/usr/bin/crontab"
        if not os.path.exists(crontabFile):
            self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50201"] % crontabFile)
        if not os.path.isfile(crontabFile):
            self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50210"] % crontabFile)

        # attention:crontab file permission should be 755
        g_file.changeOwner("root", crontabFile)
        g_file.changeMode(DefaultValue.MAX_DIRECTORY_MODE, crontabFile)
        cmd = "chmod u+s '%s'" % crontabFile
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_501["GAUSS_50107"] % crontabFile +
                                " Command:%s. Error:\n%s" % (cmd, output))

        # 2.make sure user have permission to use cron
        cron_allow_file = "/etc/cron.allow"
        if not os.path.isfile(cron_allow_file):
            g_file.createFile(cron_allow_file)
        g_file.changeMode(DefaultValue.KEY_FILE_MODE, cron_allow_file)
        g_file.changeOwner("root", cron_allow_file)

        g_file.deleteLine(cron_allow_file, "^\\s*%s\\s*$" % self.user)
        g_file.writeFile(cron_allow_file, [self.user])

        # 3.restart cron service
        self.logger.debug("Restarting CRON service.")
        retryTimes = 0
        while True:
            (status, output) = g_service.manageOSService("crond", "restart")
            if status == 0:
                break
            if retryTimes > 10:
                self.logger.logExit(ErrorCode.GAUSS_508["GAUSS_50802"] % "restart crond" + " Error:\n%s" % output)
            else:
                self.logger.debug("Failed to restart CRON service. Retrying.\nOutput: \n%s." % str(output))
            retryTimes = retryTimes + 1
            time.sleep(1)

        self.logger.debug("Successfully prepared user CRON service.")

    def setDailyAlarm(self):
        """
        function: set daily alarm.
        input : NA
        output: NA
        """
        self.logger.log("Set daily alarm.")
        tmpPath = self.clusterInfo.readClusterTmpMppdbPath(self.user, self.clusterConfig)
        dirName = os.path.dirname(os.path.realpath(__file__))
        packageDir = os.path.realpath(os.path.join(dirName, "./../../"))

        alarmFile = "%s/gauss_daily_alarm_%d" % (tmpPath, os.getpid())
        # get all content by crontab command
        (status, output) = g_OSlib.getAllCrontab()
        if status == 0:
            # overwrite cronFile, make it empty.
            g_file.createFile(alarmFile, True)
            content_CronFile = [output]
            if output != "":
                g_file.writeFile(alarmFile, content_CronFile)
                g_file.deleteLine(alarmFile, "\\/sudo\\/gs_om -t dailyAlarm")
        # status==1 means this user has no cron
        elif status != 1:
            self.logger.logExit(ErrorCode.GAUSS_508["GAUSS_50803"] + " Error: \n%s" % output)

        cronContent = "0 12 * * * "
        if self.mpprcFile:
            cronContent += "export MPPDB_ENV_SEPARATE_PATH='%s';" % self.mpprcFile
        cronContent += "export GPHOME='%s';" % self.clusterToolPath
        cronContent += "export PATH=$PATH:$GPHOME/script/gspylib/pssh/bin:$GPHOME/script;"
        cronContent += "export PYTHONPATH=$GPHOME/lib;"
        if os.path.exists('/var/chroot/') and os.path.exists('/rds/datastore/') and \
                not DefaultValue.is_os_with_conflicting_so_libraries():
            cronContent += "export LD_LIBRARY_PATH=$GPHOME/lib:$LD_LIBRARY_PATH;"
        cronContent += "export GAUSS_WARNING_TYPE=%s;" % self.warningType
        cronContent += "export GAUSSLOG='%s';" % self.clusterInfo.logPath
        cronContent += "uid=`ls -n %s/sudo/gs_om |awk '{print $3}'`;" % packageDir
        cronContent += "if [ $uid -eq 0 ]; then python3 %s/sudo/gs_om -t dailyAlarm -U %s >>/dev/null 2>&1; fi &" % (
            packageDir, self.user)

        content_CronFile = [cronContent]
        g_file.writeFile(alarmFile, content_CronFile)

        g_OSlib.execCrontab(alarmFile)
        g_file.removeFile(alarmFile)

    def prepareUserSshdService(self):
        """
        function: set MaxStartups to 1000.
        input : NA
        output: NA
        """
        self.logger.debug("Preparing user SSHD service.")
        sshd_config_file = "/etc/ssh/sshd_config"
        paramName = "MaxStartups"
        sshdNeedReload = False

        # 1.change the MaxStartups
        cmd = "grep -E '^[ ]*MaxStartups[ ]*1000$' %s" % sshd_config_file
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            cmd = "sed -i '/^.*%s.*$/d' %s" % (paramName, sshd_config_file)
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error:\n%s" % output)
            g_Platform.setKeyValueInSshd('MaxStartups', '1000')
            self.logger.debug("Write MaxStartups value.")
            sshdNeedReload = True

        # Check if is DWS mode.
        OsVersionFlag = False
        rdsFlag = False
        chrootFlag = False
        gs_platform = Platform()
        distname, _, _ = gs_platform.dist()
        if distname in support_platform.RHEL_DERIVATION_PLATFORM_LIST:
            OsVersionFlag = True
        if os.path.exists("/rds/"):
            rdsFlag = True
        if os.path.exists("/var/chroot/"):
            chrootFlag = True
        if OsVersionFlag and rdsFlag and chrootFlag:
            # DWS mode has its own value of ClientAliveInterval, which is 43200.
            self.logger.debug("In DWS mode, skip set ClientAliveInterval.")
            self.logger.debug("Successfully prepared user SSHD service.")
            return

        # 2.change the ClientAliveInterval
        cmd = "grep -E '^[ ]*ClientAliveInterval[ ]*0$' %s" % sshd_config_file
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            cmd = "sed -i '/^.*ClientAliveInterval.*$/d' %s" % sshd_config_file
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error:\n%s" % output)
            g_Platform.setKeyValueInSshd('ClientAliveInterval', '0')
            self.logger.debug("Write ClientAliveInterval value.")
            sshdNeedReload = True

        # 3. add cluster owner to 'AllowUser' to /etc/ssh/sshd_config if necessary.
        if self.addAllowUser(self.user) > 0:
            sshdNeedReload = True

        if sshdNeedReload:
            self.logger.debug("Reload sshd service.")
            (status, output) = g_service.manageOSService("sshd", "reload")
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_508["GAUSS_50802"] % "reload sshd" + " Error:\n%s" % output)

        self.logger.debug("Successfully prepared user SSHD service.")

    def add_multi_queue_config_to_init_file(self):
        """
        The NIC multi queue configuration is lost after reboot
        write multi-queue to the os init file
        """
        if os.path.exists('/var/chroot/') and os.path.exists('/rds/datastore/'):
            self.logger.debug("ignore write multi-queue to the os init file on dws mode.")
            return
        self.initNodeInfo()
        command = os.path.normpath(self.clusterToolPath + "/script/local/LocalCheckOS.py")
        cmd = "python3 %s -t Set_Network_Configure --local-ips '%s' -l '%s'" % (command,
                                                                                g_nodeInfo.backIps[0],
                                                                                self.logFile)

        initFile = DefaultValue.getOSInitFile()
        try:
            g_file.deleteLine(initFile, "Set_Network_Configure")
            cmd_write = "echo %s >> %s" % (cmd, initFile)
            status, output = subprocess.getstatusoutput(cmd_write)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_516["GAUSS_51632"] % cmd + " Error: \n%s" % output)
        except Exception as e:
            self.logger.debug(str(e))

    def get_and_check_user_profile(self):
        """
        """
        if self.mpprcFile != "" and self.mpprcFile is not None:
            userProfile = self.mpprcFile
        else:
            cmd = "su - %s -c \"echo ~\" 2>/dev/null" % self.user
            status, output = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error:\n%s" % output)

            # check if user profile exist
            userProfile = "/home/%s/.bashrc" % self.user
            if not os.path.exists(userProfile):
                self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50201"] % 'user profile' +
                                    " Please create %s." % userProfile)
        return userProfile

    def change_file_owner(self):
        """
        """
        # Change the owner of Gausslog
        self.logger.debug("Changing the owner of Gausslog.")
        user_dir = "%s/%s" % (self.clusterInfo.logPath, self.user)
        self.logger.debug("Changing the owner of GPHOME: %s." % user_dir)
        g_file.changeOwner(self.user, user_dir, True, "shell", retryFlag=True, retryTime=15, waiteTime=1)
        omLogPath = os.path.dirname(self.logFile)
        self.logger.debug("Changing the owner of preinstall log path: %s." % omLogPath)
        if os.path.exists(omLogPath):
            g_file.changeOwner(self.user, omLogPath, True, "shell", retryFlag=True, retryTime=15, waiteTime=1)
        self.logger.debug("Checking the permission of GPHOME: %s." % user_dir)
        cmd = g_file.SHELL_CMD_DICT["checkUserPermission"] % (self.user, user_dir)
        self.logger.debug("The command of check permission is: %s." % cmd)
        status, output = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error:\n%s" % output)
        self.logger.debug("Successfully change the owner of Gausslog.")

        # Change the owner of /etc/ldap.conf.
        gs_platform = Platform()
        distname, _, _ = gs_platform.dist()
        self.logger.debug("Changing the owner of /etc/ldap.")
        ldapFile = "/etc/ldap.conf"
        if os.path.isfile(ldapFile) and distname.lower() == support_platform.SUSE:
            g_file.changeMode(DefaultValue.KEY_FILE_MODE, ldapFile, True, "shell")
            g_file.changeOwner("root", ldapFile, True, "shell")
        self.logger.debug("Successfully change the owner of /etc/ldap.")

        # Change the owner of /etc/openldap/ldap.conf.
        self.logger.debug("Changing the owner of /etc/openldap/ldap.conf.")
        openLdapFile = "/etc/openldap/ldap.conf"
        if os.path.isfile(openLdapFile) and distname.lower() == support_platform.SUSE:
            g_file.changeMode(DefaultValue.KEY_FILE_MODE, openLdapFile, True, "shell")
            g_file.changeOwner(self.user, openLdapFile, True, "shell")
        self.logger.debug("Successfully change the owner of /etc/openldap/ldap.conf.")

    def setFinishFlag(self):
        """
        function:
          set env show that do pre install succeed
        precondition:
          1.user has been created
        postcondition:
          1.the value of GAUSS_ENV is 1
        input:NA
        output:user's env GAUSS_ENV
        hidden:
          the evn name and value to be set
        ppp:
        if user bashrc file does not exist
            create it
        clean GAUSS_ENV in user bashrc file
        set GAUSS_ENV in user bashrc file

        After set env, set daily alarm.
        """
        # get and check the userProfile
        userProfile = self.get_and_check_user_profile()

        # clean user's environmental variable
        self.logger.debug("Deleting user's environmental variable.")
        DefaultValue.cleanUserEnvVariable(userProfile)
        self.logger.debug("Successfully delete user's environmental variable.")

        # user's environmental variable
        self.logger.debug("Seting user's environmental variable.")
        installPath = self.clusterInfo.appPath
        tmpPath = self.clusterInfo.readClusterTmpMppdbPath(self.user, self.clusterConfig)
        clusterName = self.clusterInfo.name
        logPath = "%s/%s" % (self.clusterInfo.readClusterLogPath(self.clusterConfig), self.user)
        DefaultValue.setUserEnvVariable(userProfile, installPath, tmpPath, clusterName, logPath)
        self.logger.debug("Successfully set user's environmental variable.")

        # Set daily alarm.
        self.logger.debug("Set daily alarm.")
        # Check if is DWS mode.
        OsVersionFlag = False
        rdsFlag = False
        chrootFlag = False
        gs_platform = Platform()
        distname, _, _ = gs_platform.dist()
        # check if OS version is Euler
        if distname in support_platform.RHEL_DERIVATION_PLATFORM_LIST:
            OsVersionFlag = True
        if os.path.exists("/rds/"):
            rdsFlag = True
        if os.path.exists("/var/chroot/"):
            chrootFlag = True
        if OsVersionFlag and rdsFlag and chrootFlag:
            self.logger.debug("In DWS mode, skip set daily alarm.")
        elif self.clusterInfo.isSingleInstCluster():
            self.logger.log("Skip set daily alarm in single inst mode.")
        else:
            self.setDailyAlarm()
            self.logger.debug("Successfully set daily alarm.")

        # Change file owner
        self.change_file_owner()

        # get the value of GAUSS_ENV
        self.logger.debug("Setting finish flag.")
        cmd = "su - %s -c 'source %s;echo $GAUSS_ENV' 2>/dev/null" % (self.user, userProfile)
        status, output = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error:\n%s" % output)
        ENVNUM = output.split("\n")[0]
        # set finish flag
        if str(ENVNUM) != "2":
            DefaultValue.updateUserEnvVariable(userProfile, "GAUSS_ENV", "1")

        self.logger.debug("Successfully set finish flag.")

    def unsetHPMonitor(self):
        self.logger.debug("Unset hot patch monitor.")

        cronFile = "/var/spool/cron/%s" % self.user
        if not os.path.exists(cronFile):
            self.logger.debug("%s does not exists." % cronFile)
            return

        g_file.deleteLine(cronFile, "hotpatch_monitor.py")

    def setOSSar(self):
        """
        :return:
        """
        watermark_scale_factor = "/proc/sys/vm/watermark_scale_factor"
        sysctl = "/etc/sysctl.conf"
        if os.path.exists(watermark_scale_factor) and os.path.exists(sysctl):
            cmd = "sed -i '/^\\s*vm.watermark_scale_factor *=.*$/d' %s &&" \
                  "echo 'vm.watermark_scale_factor = 1000'  >> %s &&" \
                  "sysctl -p" % (sysctl, sysctl)

            self.logger.debug(cmd)
            status, output = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.debug("Failed to execute %s. Error:\n%s" % (cmd, output))

        sysstat_collect_timer = "/usr/lib/systemd/system/sysstat-collect.timer"
        if os.path.exists(sysstat_collect_timer):
            systemd_dir = "/etc/systemd/system/"
            g_file.cpFile(sysstat_collect_timer, systemd_dir)

            cmd = "sed -i 's/\(^OnCalendar.*\)/OnCalendar=*:*:0\/5/' %s/sysstat-collect.timer && " \
                  "systemctl daemon-reload; systemctl restart sysstat-collect.timer" % systemd_dir
            self.logger.debug(cmd)
            status, output = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.debug("Failed to execute %s. Error:\n%s" % (cmd, output))

    def collect_os_info(self):
        """
        :return:
        """
        cmd = "cat /sys/devices/system/node/node*/cpulist"
        status, output = subprocess.getstatusoutput(cmd)
        if status != 0 or output.strip() == "":
            self.logger.debug("Failed to execute %s. Error:\n%s" % (cmd, output))
        else:
            self.logger.debug("Command:%s,Output:%s." % (cmd, output))
            cpu_list = os.path.join(self.clusterToolPath, "cpulist")
            with os.fdopen(os.open(cpu_list, FLAGS_WRITE, 0o600), 'w') as fp:
                fp.write(output.strip() + os.linesep)

            os.chown(cpu_list, pwd.getpwnam(self.user).pw_uid,
                     pwd.getpwnam(self.user).pw_gid)

    def checkFinishFlag(self):
        """
        function:
        return True means have execed preinstall script
        return False means have not execed preinstall script
        input : NA
        output: True/False
        """
        if self.mpprcFile != "":
            cmd = "source %s; echo $GAUSS_ENV 2>/dev/null" % self.mpprcFile
        else:
            cmd = "su - %s -c 'echo $GAUSS_ENV' 2>/dev/null" % self.user
        status, output = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.debug("Failed to obtain the environment variable $GAUSS_ENV. Error:\n%s" % output)
            return False

        if output.strip() == str(1) or output.strip() == str(2):
            self.logger.debug("Successfully checked GAUSS_ENV.")
            return True
        else:
            self.logger.debug(
                "The environmental variable [GAUSS_ENV]'s value is invalid. The value is:%s" % (output.strip()))
            return False

    def setUserProfile(self, user, userEnvConfig):
        """
        function:
          set env into user's .bashrc file
        precondition:
          1.env list are valid
          2.user exist
        input:
          1.env list
          2.use name
        postcondition:na
        output:na
        hiden:
          the file to be set into
        """
        self.logger.debug("Setting user profile.")
        if self.mpprcFile != "":
            # have check its exists when check parameters, so it should exist here
            userProfile = self.mpprcFile
        else:
            # check if user home exist
            cmd = "su - %s -c \"echo ~\" 2>/dev/null" % self.user
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error:\n%s" % output)

            # check if user profile exist
            userProfile = "/home/%s/.bashrc" % self.user
            if not os.path.exists(userProfile):
                self.logger.debug("User profile does not exist. Please create %s." % userProfile)
                cmd = "su - %s -c 'touch %s && chmod %s %s'" % (
                    self.user, userProfile, DefaultValue.DIRECTORY_MODE, userProfile)
                status, output = subprocess.getstatusoutput(cmd)
                if status != 0:
                    self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50206"] % userProfile + " Error:\n%s" % output)

        # clean ENV in user bashrc file
        self.logger.debug("User profile exist. Deleting crash old ENV.")
        for env in userEnvConfig:
            g_file.deleteLine(userProfile, "^\\s*export\\s*%s=.*$" % env)
            self.logger.debug("Deleting %s in user profile" % env)

        # set ENV in user bashrc file
        self.logger.debug("Successfully deleted crash old ENV. Setting new ENV.")
        for env in userEnvConfig:
            context = "export %s=%s" % (env, userEnvConfig[env])
            g_file.writeFile(userProfile, [context])

        self.logger.debug("Successfully set user profile.")

    def getUserProfile(self):
        """
        function: set env into /etc/profile
        input : OSEnvConfig
        output: NA
        """
        if self.mpprcFile != "":
            # have check its exists when check parameters, so it should exist here
            userProfile = self.mpprcFile
        else:
            # check if os profile exist
            userProfile = "/etc/profile"
            if not os.path.exists(userProfile):
                self.logger.debug("Profile does not exist. Please create %s." % userProfile)
                g_file.createFile(userProfile)
                g_file.changeMode(DefaultValue.DIRECTORY_MODE, userProfile)
        return userProfile

    def setDBUerProfile(self):
        """
        function:
        set database user's env into user's .bashrc file.
        env list are provided by user
        input : NA
        output: NA
        """
        self.logger.debug("Setting %s user profile." % VersionInfo.PRODUCT_NAME)
        # check if need to set env parameter
        if len(self.envParams) == 0:
            self.logger.debug("No need to set ENV.")
            return

        # parse env user inputed
        for param in self.envParams:
            keyValue = param.split("=")
            if len(keyValue) != 2:
                self.logger.logExit(ErrorCode.GAUSS_500["GAUSS_50000"] % param)
            envConfig[keyValue[0].strip()] = keyValue[1].strip()

        # set env into user's profile
        self.setUserProfile(self.user, envConfig)

        self.logger.debug("Successfully set %s  user profile." % VersionInfo.PRODUCT_NAME)

    def setToolEnv(self):
        """
        function: set environment variables
        input : NA
        output: NA
        """
        self.logger.debug("Setting tool ENV.")

        userProfile = self.getUserProfile()

        # clean ENV in os profile
        self.logger.debug("OS profile exists. Deleting crash old tool ENV.")
        # clean MPPRC FILE PATH
        if self.mpprcFile != "":
            g_file.deleteLine(userProfile, "^\\s*export\\s*%s=.*$" % DefaultValue.MPPRC_FILE_ENV)
            self.logger.debug("Deleting crash MPPRC file path in user environment variables.")
            g_file.deleteLine(userProfile,
                              "^\\s*export\\s*LDAPCONF=.*$")
            ldap = "Deleting crash LDAPCONF in user environment variables."
            self.logger.debug(ldap)

        # clean LD_LIBRARY_PATH
        if os.path.exists('/var/chroot/') and os.path.exists('/rds/datastore/'):
            g_file.deleteLine(userProfile, "^\\s*export\\s*LD_LIBRARY_PATH=\\$GPHOME\\/lib:\\$LD_LIBRARY_PATH$")
            g_file.deleteLine(userProfile,
                              "^\\s*export\\s*LD_LIBRARY_PATH=\\$GPHOME\\/lib\\/libsimsearch:\\$LD_LIBRARY_PATH$")
            g_file.deleteLine(userProfile, "^\\s*export\\s*LD_LIBRARY_PATH=\\$LD_LIBRARY_PATH:\\$GPHOME\\/lib$")
            g_file.deleteLine(userProfile,
                              "^\\s*export\\s*LD_LIBRARY_PATH=\\$LD_LIBRARY_PATH:\\$GPHOME\\/lib\\/libsimsearch$")
            self.logger.debug("Deleting crash LD_LIBRARY_PATH in user environment variables.")

        # clean GPHOME
        g_file.deleteLine(userProfile, "^\\s*export\\s*GPHOME=.*$")
        self.logger.debug("Deleting crash GPHOME in user environment variables.")

        # clean PATH
        g_file.deleteLine(userProfile, "^\\s*export\\s*PATH=\\$GPHOME\\/pssh-2.3.1\\/bin:\\$GPHOME\\/script:\\$PATH$")
        g_file.deleteLine(userProfile,
                          "^\\s*export\\s*PATH=\\$GPHOME\\/script\\/gspylib\\/pssh\\/bin:\\$GPHOME\\/script:\\$PATH$")
        g_file.deleteLine(userProfile, "^\\s*export\\s*PATH=\\$PATH:\\$GPHOME\\/pssh-2.3.1\\/bin:\\$GPHOME\\/script$")
        g_file.deleteLine(userProfile,
                          "^\\s*export\\s*PATH=\\$PATH:\\$GPHOME\\/script\\/gspylib\\/pssh\\/bin:\\$GPHOME\\/script$")
        self.logger.debug("Deleting crash PATH in user environment variables.")

        # clean PYTHONPATH
        g_file.deleteLine(userProfile, "^\\s*export\\s*PYTHONPATH=\\$GPHOME\\/lib")
        self.logger.debug("Deleting crash PYTHONPATH in user environment variables.")

        # set ENV in os profile
        self.logger.debug("Successfully deleted crash old tool ENV. Setting new tool ENV.")
        # set env in user profile
        try:
            # check if the file is a link
            g_OSlib.checkLink(userProfile)
            # set mpprc file
            if self.mpprcFile != "":
                context = "export %s=%s" % (DefaultValue.MPPRC_FILE_ENV, self.mpprcFile)
                g_file.writeFile(userProfile, [context])
                # set LDAPCONF.
                current_path = os.path.dirname(self.mpprcFile)
                context = "export LDAPCONF=%s/ldap.conf" % current_path
                g_file.writeFile(userProfile, [context])
            # set GPHOME
            env_info = "export GPHOME=%s" % self.clusterToolPath
            DefaultValue.set_env_variable_depended(userProfile, env_info)
            # set PATH
            g_file.writeFile(userProfile, ["export PATH=$PATH:$GPHOME/script/gspylib/pssh/bin:$GPHOME/script"])
            if os.path.exists('/var/chroot/') and os.path.exists('/rds/datastore/') and \
                    not DefaultValue.is_os_with_conflicting_so_libraries():
                g_file.writeFile(userProfile, ["export LD_LIBRARY_PATH=$GPHOME/lib:$LD_LIBRARY_PATH"])
                g_file.writeFile(userProfile, ["export LD_LIBRARY_PATH=$GPHOME/lib/libsimsearch:$LD_LIBRARY_PATH"])
            # set PYTHONPATH
            g_file.writeFile(userProfile, ["export PYTHONPATH=$GPHOME/lib"])
            self.modifyDwsChrootEnv()
        except Exception as e:
            self.logger.logExit(str(e))
        self.logger.debug("Successfully set tool ENV.")

    def modifyDwsChrootEnv(self):
        """
        function: The environment variable information for OpenSSL configuration switchover may
          exist in the existing environment of the 910 version.
         Before the upgrade preinstall, roll back the environment variable in the chroot sandbox.
        """
        chroot_profile_path = "/var/chroot/etc/profile"
        chroot_bashrc_path = "/var/chroot/home/Ruby/.bashrc"
        cmd = ""
        if os.path.exists(chroot_profile_path) and not DefaultValue.is_os_with_conflicting_so_libraries():
            cmd += "sed -i 's|^export LD_LIBRARY_PATH=\\$LD_LIBRARY_PATH:\\$GPHOME\\/lib\\/libsimsearch$" \
                   "|export LD_LIBRARY_PATH=\\$GPHOME\\/lib\\/libsimsearch:\\$LD_LIBRARY_PATH|g' %s ; " % \
                   chroot_profile_path
            cmd += "sed -i 's|^export LD_LIBRARY_PATH=\\$LD_LIBRARY_PATH:\\$GPHOME\\/lib$" \
                   "|export LD_LIBRARY_PATH=\\$GPHOME\\/lib:\\$LD_LIBRARY_PATH|g' %s ; " % chroot_profile_path
        if os.path.exists(chroot_bashrc_path) and not DefaultValue.is_os_with_conflicting_so_libraries():
            cmd += "sed -i 's|^export LD_LIBRARY_PATH=\\$LD_LIBRARY_PATH:\\$GAUSSHOME\\/lib\\/libsimsearch$" \
                   "|export LD_LIBRARY_PATH=\\$GAUSSHOME\\/lib\\/libsimsearch:\\$LD_LIBRARY_PATH|g'" \
                   " %s ; " % chroot_bashrc_path
            cmd += "sed -i 's|^export LD_LIBRARY_PATH=\\$LD_LIBRARY_PATH:\\$GAUSSHOME\\/lib$" \
                   "|export LD_LIBRARY_PATH=\\$GAUSSHOME\\/lib:\\$LD_LIBRARY_PATH|g' %s ; " % chroot_bashrc_path
        if not cmd:
            self.logger.debug("no need to modify chroot env.")
            return
        self.logger.debug("Command for modify chroot env: %s." % cmd)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.debug("Warning: Failed to modify chroot env, Detail:\n%s" % output)

    def cleanWarningEnv(self):
        """
        function: Deleting crash rsyslog or syslog-ng log ENV
        input : NA
        output: NA
        """
        self.logger.debug("Deleting crash system log ENV.")
        # judge the installed syslog type on the local host is rsyslog or syslog-ng
        syslogType = self.judgeSyslogType()
        if syslogType == SYSLOG_NG:
            self.cleanWarningEnvForSyslogng()
        elif syslogType == RSYSLOG:
            self.cleanWarningEnvForRsyslog()
        self.logger.debug("Successfully deleted crash system log ENV.")

    def cleanWarningEnvForSyslogng(self):
        """
        function: Deleting crash syslog-ng ENV
        input : NA
        output: NA
        """
        # clean client syslog-ng configure
        cmd = "(if [ -s '%s' ]; then " % SYSLOG_NG_CONFIG_FILE
        cmd += "sed -i -e '/^filter f_gaussdb.*$/d' %s " % SYSLOG_NG_CONFIG_FILE
        cmd += "-e '/^destination d_gaussdb.*$/d' %s " % SYSLOG_NG_CONFIG_FILE
        cmd += "-e '/^log { source(src); filter(f_gaussdb); destination(d_gaussdb); };$/d' %s;fi;) " \
               % SYSLOG_NG_CONFIG_FILE
        self.logger.debug("Command for deleting crash client system log: %s." % cmd)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50207"] % 'crash client system log' +
                                " Error: \n%s" % output)

        # clean server syslog-ng configure
        cmd = "(if [ -s '%s' ]; then " % SYSLOG_NG_CONFIG_FILE
        cmd += "sed -i -e '/^template t_gaussdb.*$/d' %s " % SYSLOG_NG_CONFIG_FILE
        cmd += "-e '/^source s_gaussdb.*$/d' %s " % SYSLOG_NG_CONFIG_FILE
        cmd += "-e '/^filter f_gaussdb.*$/d' %s " % SYSLOG_NG_CONFIG_FILE
        cmd += "-e '/^destination d_gaussdb.*$/d' %s " % SYSLOG_NG_CONFIG_FILE
        cmd += "-e '/^log { source(s_gaussdb); filter(f_gaussdb); destination(d_gaussdb); };$/d' %s;fi; " \
               % SYSLOG_NG_CONFIG_FILE
        cmd += "if [ -s '%s' ]; then " % SYSLOG_NG_CONFIG_FILE_SERVER
        cmd += "sed -i -e '/^SYSLOGD_OPTIONS=\\\"-r -m 0\\\"/d' %s " % SYSLOG_NG_CONFIG_FILE_SERVER
        cmd += "-e '/^KLOGD_OPTIONS=\\\"-x\\\"/d' %s; " % SYSLOG_NG_CONFIG_FILE_SERVER
        cmd += "fi) "
        self.logger.debug("Command for cleaning crash server system log: %s." % cmd)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50207"] % 'crash server system log' +
                                " Error: \n%s" % output)

        # restart the syslog service
        self.logger.debug("Restart syslog service.")
        (status, output) = g_service.manageOSService("syslog", "restart")
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_508["GAUSS_50802"] % "restart syslog" + " Error: \n%s" % output)

    def cleanWarningEnvForRsyslog(self):
        """
        function: Deleting crash rsyslog ENV
        input : NA
        output: NA
        """
        # clean rsyslog config on client and server
        cmd = "(if [ -s %s ]; then " % RSYSLOG_CONFIG_FILE
        cmd += "sed -i -e '/^$ModLoad imjournal.*$/d' %s " % RSYSLOG_CONFIG_FILE
        cmd += "-e '/^$ModLoad imudp.*$/d' %s " % RSYSLOG_CONFIG_FILE
        cmd += "-e '/^$UDPServerRun 514.*$/d' %s " % RSYSLOG_CONFIG_FILE
        cmd += "-e '/^$imjournalRatelimitInterval.*$/d' %s " % RSYSLOG_CONFIG_FILE
        cmd += "-e '/^$imjournalRatelimitBurst.*$/d' %s " % RSYSLOG_CONFIG_FILE
        cmd += "-e '/^$SystemLogRateLimitInterval.*$/d' %s " % RSYSLOG_CONFIG_FILE
        cmd += "-e '/^$SystemLogRateLimitBurst.*$/d' %s " % RSYSLOG_CONFIG_FILE
        cmd += "-e '/^%s.*$/d' %s; " % (AP_RSYSLOG_FACILITY_LEVEL, RSYSLOG_CONFIG_FILE)
        cmd += "fi) "
        self.logger.debug("Command for cleaning crash rsyslog: %s." % cmd)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50207"] % 'crash rsyslog' + " Error: \n%s" % output)

        # restart the rsyslog service
        self.logger.debug("Restart rsyslog service.")
        (status, output) = g_service.manageOSService("rsyslog", "restart")
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_508["GAUSS_50802"] % "restart rsyslog" + " Error: \n%s" % output)

    def setClientWarningEnv(self):
        """
        function: Setting client warning ENV for rsyslog or syslog-ng
        input : NA
        output: NA
        """
        self.logger.debug("Setting client warning ENV.")
        # judge the installed syslog type on the local host is rsyslog or syslog-ng
        syslogType = self.judgeSyslogType()
        if syslogType == SYSLOG_NG:
            self.setClientWarningEnvForSyslogng()
        elif syslogType == RSYSLOG:
            self.setJournalRateLimiting()
            self.setClientWarningEnvForRsyslog()
        self.logger.debug("Successfully set client warning ENV.")

    def setJournalRateLimiting(self):
        """
        function: Setting Systemd Journal Rate Limiting
        input : NA
        output: NA
        """
        # set SYSTEMD_JOURNALD_CONF configure
        if os.path.isfile(SYSTEMD_JOURNALD_CONF):
            self.logger.debug("Setting Systemd Journal Rate Limiting.")
            # clean old RateLimitInterval and RateLimitBurst
            g_file.deleteLine(SYSTEMD_JOURNALD_CONF, "^\\s*RateLimitInterval\\s*=.*")
            g_file.deleteLine(SYSTEMD_JOURNALD_CONF, "^\\s*RateLimitBurst\\s*=.*")
            # set RateLimitInterval and RateLimitBurst
            g_file.writeFile(SYSTEMD_JOURNALD_CONF, ["RateLimitInterval=0"])
            g_file.writeFile(SYSTEMD_JOURNALD_CONF, ["RateLimitBurst=0"])
            # restart systemd-journald, make it working
            self.logger.debug("Restart systemd-journald service.")
            (status, output) = g_service.manageOSService("systemd-journald", "restart")
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_508["GAUSS_50802"] % "restart systemd-journald" +
                                    " Error: \n%s" % output)

    def setClientWarningEnvForSyslogng(self):
        """
        function: Setting client warning ENV for syslog-ng
        input : NA
        output: NA
        """
        # set client syslog-ng configure
        client_filter = "filter f_gaussdb    { level(err,  crit) and match('MPPDB'); };"
        client_destination = "destination d_gaussdb { udp(\"%s\"  port(514) ); };" % self.warningIp
        client_log = "log { source(src); filter(f_gaussdb); destination(d_gaussdb); };"

        if os.path.exists(SYSLOG_NG_CONFIG_FILE) and os.path.getsize(SYSLOG_NG_CONFIG_FILE) > 0:
            cmdFileter = "'%s'" % client_filter
            self.logger.debug("Setting syslog-ng client configuration: %s" + client_filter)
            g_file.echoLineToFile(cmdFileter, SYSLOG_NG_CONFIG_FILE)
            cmdDestination = "'%s'" % client_destination
            self.logger.debug("Setting syslog-ng client configuration: %s" + client_destination)
            g_file.echoLineToFile(cmdDestination, SYSLOG_NG_CONFIG_FILE)
            cmdLog = "'%s'" % client_log
            self.logger.debug("Setting syslog-ng client configuration: %s" + client_log)
            g_file.echoLineToFile(cmdLog, SYSLOG_NG_CONFIG_FILE)

        self.logger.debug("Restart client syslog service.")
        (status, output) = g_service.manageOSService("syslog", "restart")
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_508["GAUSS_50802"] % "restart syslog" + " Error: \n%s" % output)

    def setClientWarningEnvForRsyslog(self):
        """
        function: Setting client warning ENV for rsyslog
        input : NA
        output: NA
        """
        # set client rsyslog configure
        client_journal = "$ModLoad imjournal"
        client_udp = "$ModLoad imudp"
        client_port = "$UDPServerRun 514"
        # to prevent from losing log when there are mass logs, set the $imjournalRatelimitInterval and
        # $imjournalRatelimitBurst
        client_imjournal_ratelimit_interval = "$imjournalRatelimitInterval %d" % IMJOURNAL_RATELIMIT_INTERVAL
        client_imjournal_ratelimit_burst = "$imjournalRatelimitBurst %d" % IMJOURNAL_RATELIMIT_BURST
        client_systemlog_ratelimit_interval = "$SystemLogRateLimitInterval  %d" % SYSTEMLOG_RATELIMIT_INTERVAL
        client_systemlog_ratelimit_burst = "$SystemLogRateLimitBurst %d" % SYSTEMLOG_RATELIMIT_BURST
        client_filter_destination = "%s    @%s:514" % (AP_RSYSLOG_FACILITY_LEVEL, self.warningIp)

        if os.path.exists(RSYSLOG_CONFIG_FILE) and os.path.getsize(RSYSLOG_CONFIG_FILE) > 0:
            self.logger.debug("Setting rsyslog client configuration.")
            cmdJournalUdp = "'%s'" % client_journal
            g_file.echoLineToFile(cmdJournalUdp, RSYSLOG_CONFIG_FILE)
            cmdCientUdp = "'%s'" % client_udp
            g_file.echoLineToFile(cmdCientUdp, RSYSLOG_CONFIG_FILE)
            cmdCientPort = "'%s'" % client_port
            g_file.echoLineToFile(cmdCientPort, RSYSLOG_CONFIG_FILE)
            cmdCientInterval = "'%s'" % client_imjournal_ratelimit_interval
            g_file.echoLineToFile(cmdCientInterval, RSYSLOG_CONFIG_FILE)
            cmdCientBurst = "'%s'" % client_imjournal_ratelimit_burst
            g_file.echoLineToFile(cmdCientBurst, RSYSLOG_CONFIG_FILE)
            cmdCientSyslogInterval = "'%s'" % client_systemlog_ratelimit_interval
            g_file.echoLineToFile(cmdCientSyslogInterval, RSYSLOG_CONFIG_FILE)
            cmdCientSyslogBurst = "'%s'" % client_systemlog_ratelimit_burst
            g_file.echoLineToFile(cmdCientSyslogBurst, RSYSLOG_CONFIG_FILE)
            cmdCientFilterDest = "'%s'" % client_filter_destination
            g_file.echoLineToFile(cmdCientFilterDest, RSYSLOG_CONFIG_FILE)

        # restart the rsyslog service
        self.logger.debug("Restart rsyslog service.")
        (status, output) = g_service.manageOSService("rsyslog", "restart")
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_508["GAUSS_50802"] % "restart rsyslog" + " Error: \n%s" % output)

    def setServerWarningEnv(self):
        """
        function: Setting server warning ENV for rsyslog or syslog-ng
        input : NA
        output: NA
        """
        self.logger.debug("Setting server warning ENV.")
        # judge the installed syslog type on the local host is rsyslog or syslog-ng
        syslogType = self.judgeSyslogType()
        if syslogType == SYSLOG_NG:
            self.setServerWarningEnvForSyslogng()
        elif syslogType == RSYSLOG:
            self.setServerWarningEnvForRsyslog()
        self.logger.debug("Successfully set server warning ENV.")

    def setServerWarningEnvForSyslogng(self):
        """
        function: Setting server warning ENV for syslog-ng
        input : NA
        output: NA
        """
        # set server syslog-ng configure
        server_template = "template t_gaussdb {template(\"$DATE $SOURCEIP $MSGONLY\\n\"); template_escape(no); };"
        server_source = "source s_gaussdb{ udp(); };"
        server_filter = "filter f_gaussdb    { level(err,  crit) and match('MPPDB'); };"
        server_destination = "destination d_gaussdb { file(\"%s\", template(t_gaussdb)); };" % AP_SERVER_SYSLOG_FILE
        server_log = "log { source(s_gaussdb); filter(f_gaussdb); destination(d_gaussdb); };"

        if os.path.exists(SYSLOG_NG_CONFIG_FILE) and os.path.getsize(SYSLOG_NG_CONFIG_FILE) > 0:
            cmdTemplate = "'%s'" % server_template
            self.logger.debug("Setting syslog-ng server configuration: %s" + server_template)
            g_file.echoLineToFile(cmdTemplate, SYSLOG_NG_CONFIG_FILE)
            cmdSource = "'%s'" % server_source
            self.logger.debug("Setting syslog-ng server configuration: %s" + server_source)
            g_file.echoLineToFile(cmdSource, SYSLOG_NG_CONFIG_FILE)
            cmdFilter = "'%s'" % server_filter
            self.logger.debug("Setting syslog-ng server configuration: %s" + server_filter)
            g_file.echoLineToFile(cmdFilter, SYSLOG_NG_CONFIG_FILE)
            cmdDestination = "'%s'" % server_destination
            self.logger.debug("Setting syslog-ng server configuration: %s" + server_destination)
            g_file.echoLineToFile(cmdDestination, SYSLOG_NG_CONFIG_FILE)
            cmdLog = "'%s'" % server_log
            self.logger.debug("Setting syslog-ng server configuration: %s" + server_log)
            g_file.echoLineToFile(cmdLog, SYSLOG_NG_CONFIG_FILE)

        # set server sysconfig configure
        server_sysconfig_syslogd = "SYSLOGD_OPTIONS=\"-r -m 0\""
        server_sysconfig_klogd = "KLOGD_OPTIONS=\"-x\""

        if os.path.exists(SYSLOG_NG_CONFIG_FILE_SERVER) and os.path.getsize(SYSLOG_NG_CONFIG_FILE_SERVER) > 0:
            cmdConfigLog = "'%s'" % server_sysconfig_syslogd
            self.logger.debug("Setting sys-config server configuration: %s" + server_sysconfig_syslogd)
            g_file.echoLineToFile(cmdConfigLog, SYSLOG_NG_CONFIG_FILE_SERVER)
            cmdConfigKLog = "'%s'" % server_sysconfig_klogd
            self.logger.debug("Setting sys-config server configuration: %s" + server_sysconfig_klogd)
            g_file.echoLineToFile(cmdConfigKLog, SYSLOG_NG_CONFIG_FILE_SERVER)

        self.logger.debug("Restart server syslog service.")
        (status, output) = g_service.manageOSService("syslog", "restart")
        if (status != 0):
            self.logger.logExit(ErrorCode.GAUSS_508["GAUSS_50802"] % "restart syslog" + " Error: \n%s" % output)

    def setServerWarningEnvForRsyslog(self):
        """
        function: Setting server warning ENV for rsyslog
        input : NA
        output: NA
        """
        # set server rsyslog configure
        server_filter_destination = "%s    %s" % (AP_RSYSLOG_FACILITY_LEVEL, AP_SERVER_SYSLOG_FILE)

        if os.path.exists(RSYSLOG_CONFIG_FILE) and os.path.getsize(RSYSLOG_CONFIG_FILE) > 0:
            # clean RSYSLOG_FACILITY_LEVEL
            cmd = "sed -i -e '/^%s.*$/d' %s" % (AP_RSYSLOG_FACILITY_LEVEL, RSYSLOG_CONFIG_FILE)
            self.logger.debug("Command for cleaning crash rsyslog: %s." % cmd)
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50207"] % 'crash rsyslog' + " Error: \n%s" % output)

            self.logger.debug("Setting rsyslog server configuration.")
            cmdFilterDest = "'%s'" % server_filter_destination
            g_file.echoLineToFile(cmdFilterDest, RSYSLOG_CONFIG_FILE)

        self.logger.debug("Restart server syslog service.")
        (status, output) = g_service.manageOSService("syslog", "restart")
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_508["GAUSS_50802"] % "restart syslog" + " Error: \n%s" % output)

    def judgeSyslogType(self):
        """
        function: judge syslog type
        input : NA
        output: NA
        """
        self.logger.debug("judging the syslog type is rsyslog or syslog-ng.")
        if os.path.isfile(RSYSLOG_CONFIG_FILE):
            return RSYSLOG
        elif os.path.isfile(SYSLOG_NG_CONFIG_FILE):
            return SYSLOG_NG
        else:
            self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50219"] + " \nError: Failed to judge the syslog type.")

    def setWarningEnv(self):
        """
        function: Setting warning ENV
        input : NA
        output: NA
        """
        self.logger.debug("Setting warning ENV.")
        # set warning env
        warningEnv = {'GAUSS_WARNING_TYPE': '%d' % self.warningType}
        self.setUserProfile(self.user, warningEnv)
        # set warning syslog configure
        if self.warningType == 2:
            # only suse11/suse12 can support it
            gs_platform = Platform()
            distname, _, _ = gs_platform.dist()
            if distname.upper() != "SUSE":
                return
            self.cleanWarningEnv()
            self.setClientWarningEnv()
            hostName = socket.gethostname()
            if self.warningNode == hostName:
                self.setServerWarningEnv()
        self.logger.debug("Successfully set warning ENV")

    def setLibrary(self):
        """
        function: Setting Library
        input : NA
        output: NA
        """
        self.logger.debug("Setting Library.")

        # create a link for libnsl if libnsl.so.1 not found
        cmd = "if [ ! -f /lib64/libnsl.so.1 ]; then " \
              "  if [ -f /lib64/libnsl.so.2 ]; then " \
              "    ln -s /lib64/libnsl.so.2 /lib64/libnsl.so.1;" \
              "  else " \
              "    ln -s /lib64/libnsl-2*.so /lib64/libnsl.so.1;" \
              "  fi " \
              "fi"
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)

        config_file_dir = "/etc/ld.so.conf"
        alreadySet = False
        # check if the file is a link
        g_OSlib.checkLink(config_file_dir)
        if os.path.isfile(config_file_dir):
            with open(config_file_dir, "r") as fp:
                libs = fp.read()
            for lib in libs.split("\n"):
                if lib.strip() == "/usr/local/lib":
                    alreadySet = True
            if alreadySet:
                pass
            else:
                cmd = "echo '/usr/local/lib' >> '/etc/ld.so.conf' && ldconfig"
                (status, output) = subprocess.getstatusoutput(cmd)
                if status != 0:
                    self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)
        self.logger.debug("Successfully set Library.")

    def skip_old_node(self):
        """
        function: Determine whether the current node needs to set Cgroup and Arm Optimization
        input : NA
        output: True     #no need to set
                False    #need to set
        """
        gaussdb_binary = os.path.join(self.clusterInfo.appPath, 'bin/gaussdb')
        if os.path.exists(gaussdb_binary):
            self.logger.debug("The current node has been installed, "
                              "no need to set cgroup and Arm Optimization.")
            return True
        else:
            return False

    def checkAndReplaceSoFile(self, srcDir, destDir):
        """
        """
        fileName = os.path.basename(destDir)
        cmd = "ls /usr/local/lib | grep '^%s$' | wc -l" % fileName
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)

        if int(output) == 1 and os.path.getsize(srcDir) == os.path.getsize(destDir):
            self.logger.debug("Skip copy %s." % fileName)
        else:
            cmd = "install -m %s '%s' '%s' && ldconfig" % (DefaultValue.KEY_FILE_MODE, srcDir, destDir)
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50214"] % fileName + " Error: \n%s" % output)

    def exec_cgroup(self, cgroup_exe_dir):
        """
        """
        bin_path = self.clusterInfo.logPath + "/%s/bin/gs_cgroup/" % self.user
        if not os.path.exists(bin_path):
            g_file.createDirectory(bin_path)

        cgroupLog = bin_path + "gs_cgroup.log"
        c_logger = GaussLog(cgroupLog, "gs_cgroup")
        mountDir = ""
        if self.cgroupMountDir != "":
            mountDir = "-D %s" % self.cgroupMountDir
        cgroup_lib_dir = os.path.join(os.path.dirname(cgroup_exe_dir), "../lib")
        cmd = ("export LD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH; "
               "%s -U %s --upgrade -c -H %s/%s %s") % (cgroup_lib_dir, cgroup_exe_dir, self.user,
                                                       self.clusterToolPath, self.user, mountDir)
        self.logger.debug("Command for executing gs_cgroup: %s\n" % cmd)
        status, output = subprocess.getstatusoutput(cmd)
        self.logger.debug("The result of gs_cgroup is:\n%s." % output)
        c_logger.debug(str(output))
        # Change the owner and permission.
        g_file.changeOwner(self.user, bin_path, True)
        g_file.changeMode(DefaultValue.KEY_DIRECTORY_MODE, bin_path)
        g_file.changeMode(DefaultValue.KEY_FILE_MODE, (bin_path + "*"))
        c_logger.closeLog()
        if status != 0:
            self.logger.logExit(str(output))

    def setCgroup(self):
        """
        function: Setting Cgroup
        input : NA
        output: NA
        """
        self.collect_os_info()

        if self.skip_old_node():
            return
        self.logger.debug("Setting Cgroup.")

        try:
            g_Platform.special_processing_for_cgroup()
        except Exception as e:
            self.logger.logExit(str(e))

        # create temp directory for libcgroup etc
        cgroup_etc_dir = "%s/%s/etc" % (self.clusterToolPath, self.user)
        dirName = os.path.dirname(os.path.realpath(__file__))
        libcgroup_dir = os.path.join(dirName, "../../libcgroup/lib/libcgroup.so")
        libsecurec_dir = os.path.join(dirName, "../../libcgroup/lib/libsecurec.so")
        libasan_dir = os.path.join(dirName, "../../libcgroup/lib/libasan.so.5")
        cmd = "rm -rf '%s/%s'" % (self.clusterToolPath, self.user)
        status, output = DefaultValue.retryGetstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(
                ErrorCode.GAUSS_502["GAUSS_50207"] % 'crash Cgroup congiguration file' + " Error: \n%s" % output)
        cmd = "if [ ! -d '%s' ];then mkdir -p '%s' && " % (cgroup_etc_dir, cgroup_etc_dir)
        cmd += "chmod %s '%s'/../ -R && chown %s:%s '%s'/../ -R;fi" % (
            DefaultValue.KEY_DIRECTORY_MODE, cgroup_etc_dir, self.user, self.group, cgroup_etc_dir)
        status, output = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50208"] % cgroup_etc_dir + " Error: \n%s" % output)
        # libcgroup
        libcgroup_target = "/usr/local/lib/libcgroup.so.1"
        libsecurec_target = "/usr/local/lib/libsecurec.so"
        self.checkAndReplaceSoFile(libcgroup_dir, libcgroup_target)
        self.checkAndReplaceSoFile(libsecurec_dir, libsecurec_target)
        if os.path.exists(libasan_dir):
            libasan_target = "/usr/local/lib/libasan.so.5"
            self.checkAndReplaceSoFile(libasan_dir, libasan_target)

        # cp GAUSSHOME/etc/gscgroup.cfg to GPHOME/etc/gscgroup_perfadms.cfg
        GPHOME_cgroupCfgFile = "%s/%s/etc/gscgroup_%s.cfg" % (self.clusterToolPath, self.user, self.user)
        GAUSSHOME_cgroupCfgFile = "%s/etc/gscgroup_%s.cfg" % (self.clusterInfo.appPath, self.user)
        cmd = "(if [ -f '%s' ]; then cp '%s' '%s';fi)" % (
            GAUSSHOME_cgroupCfgFile, GAUSSHOME_cgroupCfgFile, GPHOME_cgroupCfgFile)
        self.logger.debug("Command for copying GAUSSHOME gscgroup's config file to GPHOME: %s\n" % cmd)
        status, output = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50214"] % GAUSSHOME_cgroupCfgFile + " Error:\n%s" % output)

        # call cgroup
        cgroup_exe_dir = os.path.join(dirName, "../../libcgroup/bin/gs_cgroup")
        self.exec_cgroup(cgroup_exe_dir)
        self.logger.debug("Successfully set Cgroup.")

    def checkPlatformArm(self):
        """
        function: Setting ARM Optimization
        input : NA
        output: NA
        """
        self.logger.debug("Check if platform is ARM.")
        try:
            global ARM_PLATE
            cmd = "python3 -c 'import platform;print(platform.machine())'"
            self.logger.debug("Command for getting querying platform: %s" % cmd)
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)
            if str(output) == "aarch64":
                ARM_PLATE = True
        except Exception as e:
            self.logger.logExit(str(e))
        self.logger.debug("Successfully check platform ARM.")

    def setArmOptimization(self):
        """
        function: Setting ARM Optimization
        input : NA
        output: NA
        """
        if self.skip_old_node():
            return
        self.logger.debug("Set ARM Optimization.")
        try:
            initFile = DefaultValue.getOSInitFile()
            clusterToolPath = self.clusterToolPath
            # set_arm_optimization
            init_cmd = "sed -i \"/(if test -f \'.*setArmOptimization.sh\'; " \
                       "then export LC_ALL=C; sh .*setArmOptimization.sh;fi)/d\"  %s && " % initFile
            init_cmd += "echo \"(if test -f \'%s/sudo/setArmOptimization.sh\'; " \
                        "then export LC_ALL=C;sh %s/sudo/setArmOptimization.sh;fi)\" >> %s" \
                        % (clusterToolPath, clusterToolPath, initFile)
            (status, output) = subprocess.getstatusoutput(init_cmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % init_cmd + " Error: \n%s" % output)
            cmd = "if test -f \'%s/sudo/setArmOptimization.sh\'; then export LC_ALL=C;" \
                  "sh %s/sudo/setArmOptimization.sh;fi" % (clusterToolPath, clusterToolPath)
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)
        except Exception as e:
            self.logger.logExit(str(e))
        self.logger.debug("Successfully set ARM Optimization.")

    def setCpuAffi(self):
        """
        function: Set cpu affinity to networkcard
        input : NA
        output: NA
        """
        self.logger.debug("Begin to set cpu affinity to network.")
        cardList = self.getCardList()
        if len(cardList) == 0:
            self.logger.debug("Do not find 1822 network card.")
            return
        for dev in cardList:
            cpuNum = self.getCpuNum(dev)
            interrupt = self.getInterList(dev)
            self.writeCpuAffi(interrupt, cpuNum)
        self.logger.debug("Successfully set cpu affinity.")

    def writeCpuAffi(self, interrupt, cpuNum):
        """
        function: Write cpu affinity to network file
        input : interrupt, cpuNum
        output: NA
        """
        self.logger.debug("Write cpu affinity to network files.")
        cpuStart = cpuNum
        for inter in interrupt:
            irqFile = "/proc/irq/%s/smp_affinity" % inter
            affiNum = self.calculateCpuAffi(cpuStart)
            affiNum = str(affiNum)
            cmd = g_file.SHELL_CMD_DICT["overWriteFile"] % (affiNum, irqFile)
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)
            self.logger.debug("set irq %s to cpu %s, affi: %s" % (inter, cpuStart, affiNum))
            cpuStart = int(cpuStart) + 1
        self.logger.debug("Successfully writting netwokr files.")

    def calculateCpuAffi(self, cpuStart):
        """
        function: Calculate cpu affinity
        input : The start number of cpu range
        output: cpu affinit list
        """
        cpuStart = int(cpuStart)
        count = 0
        num = 0
        res = ""
        bitList = ["1", "2", "4", "8"]
        while count <= cpuStart:
            if count == cpuStart:
                res = bitList[num] + res
                break
            elif num == 3:
                num = 0
                res = "0" + res
                zero = res
                zeroLen = len(zero.replace(",", ""))
                if zeroLen % 8 == 0:
                    res = "," + res
                count = count + 1
            else:
                num = num + 1
                count = count + 1
        return res

    def getInterList(self, device):
        """
        function: Get network interrput.
        input : device
        output: interrupt list
        """
        self.logger.debug("Begin to get interrupt of network card.")
        cmd = g_file.SHELL_CMD_DICT["getInterrupt"] % device
        self.logger.debug("The get interrupt command:%s." % cmd)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)
        interList = output.strip().split("\n")
        self.logger.debug("The interrupt list:%s." % interList)
        return interList

    def getCpuNum(self, device):
        """
        function: Get cpu start num.
        input : device
        output: cpu start num
        """
        self.logger.debug("Begin to get cpu range of numa node.")
        # Get numa node num for the device.
        numaFile = "/sys/class/net/%s/device/numa_node" % device
        numaList = g_file.readFile(numaFile)
        numaNode = "node" + numaList[0].strip()
        cmd = g_file.SHELL_CMD_DICT["checkcpu"]
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)
        numaCpuList = output.split("\n")
        cpuStartNum = 0
        for cpuList in numaCpuList:
            if numaNode in cpuList:
                cpuRange = cpuList.strip().split(" ")
                self.logger.debug("Numa cpu range:%s." % cpuRange[-1])
                cpuRange = cpuRange[-1].split("-")
                cpuStartNum = cpuRange[0]
                break
        self.logger.debug("Successfully get start number of cpu range.")
        return cpuStartNum

    def getCardList(self):
        """
        function: Get 1822 devivce from all network card.
        input : NA
        output: 1822 card list
        """
        # Get 1822 networkcard name.
        cardList = []
        validLsit = []
        cmd = g_file.SHELL_CMD_DICT["getNetworkCardName"]
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)
        networkList = output.split("\n")
        self.logger.debug("All network card list is:%s." % networkList)
        for netCard in networkList:
            cmd = g_file.SHELL_CMD_DICT["checkIP"] % netCard
            (status, output) = subprocess.getstatusoutput(cmd)
            if status == 0:
                ipList = output.split("\n")
                ipList = ipList[0].strip().split(" ")
                if len(ipList) > 1:
                    if ipList[1] != "127.0.0.1":
                        self.logger.debug("IP:%s." % ipList[1])
                        validLsit.append(netCard)
            elif status == 0 and output != "":
                self.logger.debug("Check failed:%s." % output)
        self.logger.debug("The network card list is:%s." % validLsit)
        if len(validLsit) == 0:
            self.logger.debug("No valid network card.")
            return cardList
        # Check if device is 1822 card.
        for card in validLsit:
            cmd = g_file.SHELL_CMD_DICT["check1822Card"] % card
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)
            if output != "0":
                self.logger.debug("Dev:%s, output:%s." % (card, output))
                cardList.append(card)
        self.logger.debug("The 1822 card list is:%s." % cardList)
        return cardList

    def checkVirtualIp(self):
        """
        function: Checking virtual IP
        input : NA
        output: NA
        """
        self.logger.debug("Checking virtual IP...")
        try:
            global configuredIps
            configuredIps = DefaultValue.checkIsPing(g_nodeInfo.virtualIp)

            # check the self.hostnameList values are whether or not local IPs
            #  obtain the all local IPs
            localAddrs = DefaultValue.getIpAddressList()
            for ip in g_nodeInfo.virtualIp:
                if (ip not in configuredIps) and (ip not in localAddrs):
                    self.logger.logExit(ErrorCode.GAUSS_512["GAUSS_51224"] % ip)
                if g_network.isIPv6LocalLink(ip):
                    raise Exception(ErrorCode.GAUSS_512["GAUSS_51220"] % ip + " The IP address is of local scope.")
        except Exception as e:
            self.logger.logExit(str(e))
        self.logger.debug("Successfully check virtual IP.")

    def netNum(self, ip, mask):
        """
        function: net number
        input : ip,mask
        output: netAddress
        """
        ipArr = ip.split(".")
        maskArr = mask.split(".")
        binaryIpArr = []
        binaryMaskArr = []
        for element in ipArr:
            biElement = bin(int(element)).split("b")[1]
            binaryIpArr.append("0" * (8 - len(biElement)) + biElement)
        for element in maskArr:
            biElement = bin(int(element)).split("b")[1]
            binaryMaskArr.append("0" * (8 - len(biElement)) + biElement)
        binaryIp = ".".join(binaryIpArr)
        binaryMask = ".".join(binaryMaskArr)
        netAddress = ""
        for i in range(len(binaryMask)):
            if binaryMask[i] == ".":
                netAddress += "."
            elif binaryIp[i] == "0" or binaryMask[i] == "0":
                netAddress += "0"
            else:
                netAddress += "1"
        return netAddress

    def obtain_netmask(self):
        """
        # Determine whether the same IP network segment.
        :return: subnetMasks, subnetMask
        """
        subnetMasks = []
        subnetMask = ""
        for backIp in g_nodeInfo.backIps:
            # Get backIP subnet mask
            allNetworkInfo = g_network.getAllNetworkInfo()
            for network in allNetworkInfo:
                if g_network.isSameIP(backIp, network.ipAddress):
                    subnetMask = network.networkMask
            # Check whether the same subnet mask backIP
            if not len(subnetMasks):
                subnetMasks.append(subnetMask)
            else:
                if subnetMask != subnetMasks[0]:
                    raise Exception(ErrorCode.GAUSS_506["GAUSS_50606"])
        return subnetMasks, subnetMask

    def rm_temp_file(self, tmpFileFp):
        """
        remove tmpfile
        :param tmpFileFp:
        :return:
        """
        if tmpFileFp:
            tmpFileFp.close()
        if os.path.exists(self.tmpFile):
            os.remove(self.tmpFile)

    def set_ipv4_vip(self, configuredIp, vipNo, tmpFileFp):
        """
        function: creating virtual Ip for ipv4
        input : configuredIp, vipNo, tmpFileFp
        output: NA
        """
        # Check with backup virtual IP on the same network segment
        self.initNodeInfo()
        backIp = g_nodeInfo.backIps[0]
        backIpNIC = DefaultValue.getNICNum(g_nodeInfo.backIps[0])
        subnetMasks, subnetMask = self.obtain_netmask()
        if self.netNum(backIp, subnetMasks[0]) != self.netNum(configuredIp, subnetMasks[0]):
            raise Exception(ErrorCode.GAUSS_512["GAUSS_51226"] + "Invalid Virtual IP: %s. "
                                                                 "The Back IP: %s. The subnetMasks: %s"
                            % (configuredIp, backIp, subnetMasks[0]))
        # Configuring Virtual Ip
        cmd_LABEL = "ip addr | grep '%s:%d'" % (backIpNIC, vipNo)
        (status, output) = subprocess.getstatusoutput(cmd_LABEL)
        if status == 0 or self.is_label_configured(backIpNIC, vipNo):
            vipNo += 1
        netmask = int(g_network.getNetmask(backIp))
        cmd = "ip addr add %s/%d label %s:%d dev %s" % (configuredIp, netmask, backIpNIC, vipNo, backIpNIC)
        self.logger.debug("The cmd is %s." % cmd)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)
        gs_platform = Platform()
        distname, _, _ = gs_platform.dist()
        if distname == "SuSE":
            if self.is_ip_configured(backIpNIC, configuredIp, vipNo, True) == 0:
                cmd = ""
            elif self.is_ip_configured(backIpNIC, configuredIp, vipNo, True) == 1:
                vipNo += 1
                cmd = "sed -i '$a\\\nIPADDR_%d=%s\\nNETMASK_%d=%s\\nLABEL_%d=%d' /etc/sysconfig/network/ifcfg-%s \
                                        " % (vipNo, configuredIp, vipNo, subnetMask, vipNo, vipNo, backIpNIC)
            else:
                cmd = "sed -i '$a\\\nIPADDR_%d=%s\\nNETMASK_%d=%s\\nLABEL_%d=%d' /etc/sysconfig/network/ifcfg-%s \
                                        " % (vipNo, configuredIp, vipNo, subnetMask, vipNo, vipNo, backIpNIC)

        else:
            vip_nic = "%s:%d" % (backIpNIC, vipNo)
            nicFile = "/etc/sysconfig/network-scripts/ifcfg-%s" % vip_nic
            networkConfiguredFile = DefaultValue.getNetworkConfiguredFile(configuredIp)
            if networkConfiguredFile == "":
                networkConfiguredFile = nicFile
            cmd = "rm -rf '%s' && touch '%s' && chmod %s '%s' && echo -e 'DEVICE=%s\nIPADDR=%s\nNETMASK=%s' >> %s" % \
                  (networkConfiguredFile, nicFile, DefaultValue.HOSTS_FILE,
                   nicFile, vip_nic, configuredIp, subnetMask, nicFile)
        if cmd != "" and cmd is not None:
            self.logger.debug("The cmd is %s." % cmd)
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50223"] % nicFile + " Error: \n%s" % output)
            print("%s" % configuredIp, file=tmpFileFp)

    def set_ipv6_vip(self, configuredIp, vipNo, back_ip_nic, net_mask):
        """
        function: creating virtual ipv6 for SUSE
        input : configuredIp, vipNo, back_ip_nic, net_mask
        output: NA
        """
        # add virtual ip
        cmd = "ip addr add %s/%d label %s:%d dev %s preferred_lft 0" % (configuredIp, net_mask,
                                                                        back_ip_nic, vipNo, back_ip_nic)
        (status, output) = subprocess.getstatusoutput(cmd)
        self.logger.debug("The cmd is %s." % cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)

    def config_vip_with_suse(self, config_vip):
        """
        """
        if self.is_ip_configured(config_vip.back_ip_nic, config_vip.configured_ip, config_vip.vip_num, False) == 0:
            cmd = ""
        elif self.is_ip_configured(config_vip.back_ip_nic, config_vip.configured_ip, config_vip.vip_num, False) == 1:
            config_vip.vip_num += 1
            cmd = "sed -i '$a\\\nIPADDR_%dIPV6=%s/%d\\nLABEL_%d=%d' /etc/sysconfig/network/ifcfg-%s \
                                    " % (config_vip.vip_num, config_vip.configured_ip, config_vip.net_mask,
                                         config_vip.vip_num, config_vip.vip_num, config_vip.back_ip_nic)
        else:
            cmd = "sed -i '$a\\\nIPADDR_%dIPV6=%s/%d\\nLABEL_%d=%d' /etc/sysconfig/network/ifcfg-%s \
                                    " % (config_vip.vip_num, config_vip.configured_ip, config_vip.net_mask,
                                         config_vip.vip_num, config_vip.vip_num, config_vip.back_ip_nic)
        status, output = subprocess.getstatusoutput(cmd)
        self.logger.debug("The cmd is %s. % cmd")
        if status != 0:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50223"] % "/etc/sysconfig/network/" +
                            " Error: \n%s" % output)
        print("%s" % config_vip.configured_ip, file=config_vip.tmp_file)

    @staticmethod
    def config_vip_with_redhat(virtualIps, values):
        """
        function: creating virtual Ip for ipv6 for Redhat Euleros
        :param virtualIps
        :param values
        :return:NA
        """
        pre_str = ""
        backIpNIC = DefaultValue.getNICNum(g_nodeInfo.backIps[0])
        nicFile = "/etc/sysconfig/network-scripts/ifcfg-%s" % backIpNIC
        networkConfiguredFile = DefaultValue.getNetworkConfiguredFile(virtualIps[0])
        if networkConfiguredFile == "":
            networkConfiguredFile = nicFile
        if len(values) > 0:
            with open(networkConfiguredFile, "r") as f:
                fp = f.readlines()
                for line in fp:
                    if line.find("IPV6ADDR_SECONDARIES") >= 0:
                        pre_str = line.split("\"")[1]
            ipv6Str = "IPV6ADDR_SECONDARIES=\\\"%s %s\\\"" % (" ".join(values), pre_str)
            g_file.deleteLine(networkConfiguredFile, "IPV6ADDR_SECONDARIES")
            echocmd = "echo %s >> %s" % (ipv6Str, networkConfiguredFile)
            status, _ = subprocess.getstatusoutput(echocmd)
            if status != 0:
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50205"] % networkConfiguredFile)

    @staticmethod
    def set_os_line_info():
        """
        sed ipv6 line info for Redhat Euleros platform
        input: NA
        output:NA
        """
        ipv6_up_file = "/etc/sysconfig/network-scripts/ifup-ipv6"
        cmd = "grep -rn 'ipv6_add_addr_on_device $DEVICE $ipv6addr' %s" % ipv6_up_file
        (status, output) = subprocess.getstatusoutput(cmd)
        output_list = output.split("\n")
        if status != 0 or len(output_list) != 1:
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)
        line_number = int(output_list[0].split(":")[0])
        line_info = "ip -6 addr change \\$ipv6addr dev \"\\$DEVICE\" preferred_lft 0"
        g_file.deleteLine(ipv6_up_file, "ip -6 addr change")
        cmd = "sed -i \"%di\  %s\" %s" % (line_number + 1, line_info, ipv6_up_file)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50223"] % ipv6_up_file + " Error: \n%s" % output)

    @staticmethod
    def get_net_mask(configured_ip):
        """
        """
        backIp = g_nodeInfo.backIps[0]
        # get netmask
        net_mask = g_network.getNetmask(backIp)
        backIp_dir = backIp + '/' + net_mask
        configuredIp_dir = configured_ip + '/' + net_mask
        if not g_network.isInSameNetSegment(backIp_dir, configuredIp_dir):
            raise Exception(ErrorCode.GAUSS_512["GAUSS_51226"] + "Invalid Virtual IP: %s." % configured_ip)
        netmask = int(net_mask)
        return netmask

    def setVirtualIp(self):
        """
        function: creating Virtual Ip
        input : NA
        output: NA
        """
        # The node instance initialization information
        flags = os.O_RDWR | os.O_CREAT
        modes = stat.S_IWUSR | stat.S_IRUSR
        self.initNodeInfo()
        gs_platform = Platform()
        distname, _, _ = gs_platform.dist()
        # Add temporary files, save the virtual IP The actual configuration for the failure rollback
        if os.path.exists(self.tmpFile):
            g_file.removeFile(self.tmpFile)
        tmpFileFp = None
        # If this node is not configured virtual IP, exit
        if not g_nodeInfo.virtualIp:
            return
        # Check whether have configured the virtual ip
        self.checkVirtualIp()
        # If the current node virtual iP are configured, Exit
        if not configuredIps:
            self.logger.debug("All virtual IP are configured.")
            return
        self.logger.debug("Start setting virtual IP...")
        try:
            # check if the file is a link
            g_OSlib.checkLink(self.tmpFile)
            # Get this node net card identifier already existing net card
            vipNo = 0
            # start setting virtual IP
            values = []
            tmpFileFp = os.fdopen(os.open(self.tmpFile, flags, modes), "w+")
            backIpNIC = DefaultValue.getNICNum(g_nodeInfo.backIps[0])
            for configuredIp in configuredIps:
                net_mask = self.get_net_mask(configuredIp)
                if g_network.getIPType(configuredIp) == 4:
                    vipNo = self.get_virtual_ip_num_for_ipv4()
                    self.set_ipv4_vip(configuredIp, vipNo, tmpFileFp)
                    vipNo += 1
                elif g_network.getIPType(configuredIp) == 6:
                    self.set_ipv6_vip(configuredIp, vipNo, backIpNIC, net_mask)
                    if distname == "SuSE":
                        config_vip = ConfigVip(backIpNIC, vipNo, configuredIp, net_mask, tmpFileFp)
                        self.config_vip_with_suse(config_vip)
                        values.append("%s/%s" % (configuredIp, net_mask))
                        vipNo += 1
                    else:
                        self.config_vip_with_redhat(configuredIps, values)
                        self.set_os_line_info()
                else:
                    raise Exception(ErrorCode.GAUSS_506["GAUSS_50603"])
            tmpFileFp.flush()
            tmpFileFp.close()
            g_file.changeMode(DefaultValue.KEY_FILE_MODE, self.tmpFile)
        except Exception as e:
            self.rm_temp_file(tmpFileFp)
            self.logger.logExit(str(e))
        self.logger.debug("Successfully set virtual IP.")

    @staticmethod
    def get_virtual_ip_num_for_ipv4():
        """
        """
        vipNo = 0
        backIpNIC = DefaultValue.getNICNum(g_nodeInfo.backIps[0])
        cmd = "ip a | grep 'scope global secondary %s:' | awk '{print $NF}'" % backIpNIC
        status, output = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_506["GAUSS_50604"] % g_nodeInfo.backIps[0] + " Error: \n%s" % output)
        # Gets the currently available virtual NIC
        nicList = output.split('\n')
        flagValues = []
        for nic in nicList:
            if nic.find(':') >= 0:
                flagList = nic.split(':')
                flag = flagList[1].strip()
                if flag.isdigit():
                    flagValues.append(int(flag))
        if flagValues:
            flagValues.sort()
            vipNo = flagValues[-1] + 1
        return vipNo

    @staticmethod
    def is_ip_configured(back_ip_nic, configured_ip, i, is_ipv4=True):
        """
        function: check has the ip or LABEL been configured ,if the ip has been configured return 0 ,
        else if the LABEL has been configured  return 1, else return 2
        input :backIpNIC,  configuredIp, LABEL number
        output: 0, 1, 2
        """
        network_file = '/etc/sysconfig/network/ifcfg-' + back_ip_nic
        LABEL = "LABEL_" + str(i) + "=" + str(i)
        # check if the file is a link
        g_OSlib.checkLink(network_file)
        fp = open(network_file, "r")
        for line in fp:
            if is_ipv4:
                line_split = line.split("=")[1].strip()
            else:
                line_split = line.split("=")[1].strip().split("/")[0]
            if g_network.isSameIP(line_split, configured_ip):
                fp.close()
                return 0
            elif LABEL in line:
                fp.close()
                return 1
        fp.close()
        return 2

    @staticmethod
    def is_label_configured(back_ip_nic, i):
        """
        function: check does the label exists already in network file, if yes, return True, if no, return False
        input : backIpNIC ,LABEL number
        output: bool
        """
        network_file = '/etc/sysconfig/network/ifcfg-' + back_ip_nic
        cmd = "cat '%s' | grep LABEL_%d=%d" % (network_file, i, i)
        (status, _) = subprocess.getstatusoutput(cmd)
        if status == 0:
            return True
        else:
            return False

    def checkRemoveIpc(self):
        """
        function: Checking RemoveIpc
        input : NA
        output: NA
        """
        self.logger.debug("Checking RemoveIpc.")
        ipcPath = "/etc/systemd/logind.conf"
        if not os.path.exists(ipcPath):
            return
        gs_platform = Platform()
        distname, version, _ = gs_platform.dist()
        ipcList = g_file.readFile(ipcPath)
        ipcFlag = noFlag = False
        for line in ipcList:
            if "RemoveIPC" in line:
                ipcFlag = True
                self.logger.debug("Find the removeIPC in file /etc/systemd/logind.conf, the content is: %s." % line)
                if "no" in line.lower() and not line.startswith("#"):
                    self.logger.debug("The value of removeIPC is no.")
                    noFlag = True
                if "yes" in line.lower() and noFlag:
                    if not line.startswith("#"):
                        self.logger.debug("The value of removeIPC is yes.")
                        self.logger.logExit(ErrorCode.GAUSS_523["GAUSS_52301"] + " The value of removeIPC must be no.")
                if "yes" in line.lower() and not noFlag:
                    if not line.startswith("#"):
                        self.logger.debug("The value of removeIPC is yes.")
                        self.logger.logExit(ErrorCode.GAUSS_523["GAUSS_52301"] + " The value of removeIPC must be no.")
                    # In Redhat/Centos 7.2, RemoveIPC default value is yes.
                    elif distname.lower() in support_platform.RHEL_MASTER_PLATFORM_LIST and version in "7.2":
                        self.logger.debug("The value of removeIPC is yes.")
                        self.logger.logExit(ErrorCode.GAUSS_523["GAUSS_52301"] +
                                            " The value of removeIPC must be no in Redhat/Centos 7.2.")
        if not ipcFlag:
            # In Redhat/Centos 7.2, RemoveIPC default value is yes.
            if distname.lower() in support_platform.RHEL_MASTER_PLATFORM_LIST and version in "7.2":
                self.logger.debug("The value of removeIPC is yes.")
                self.logger.logExit(ErrorCode.GAUSS_523["GAUSS_52301"] +
                                    " The value of removeIPC can not be empty in Redhat/Centos 7.2, it must be no.")
            else:
                self.logger.debug("Do not find RemoveIPC.")
        self.logger.debug("Successfully check RemoveIpc.")

    def checkAbrt(self):
        """
        function: Checking abrt, make sure abrt-hook-ccpp does not work.
        input : NA
        output: NA
        """
        self.logger.debug("Checking core_pattern.")
        sysFile = "/etc/sysctl.conf"
        coreFile = "/proc/sys/kernel/core_pattern"
        coreFlag = False

        coreList = g_file.readFile(sysFile)
        for line in coreList:
            if "kernel.core_pattern" in line and not line.startswith("#"):
                coreFlag = True
                self.logger.debug("Find the kernel.core_pattern in file /etc/sysctl.conf, the content is: %s." % line)
                if "|" in line and "abrt-hook-ccpp" in line:
                    self.logger.logExit(ErrorCode.GAUSS_523["GAUSS_52301"] +
                                        " The value of kernel.core_pattern"
                                        " can not combine with abrt-hook-ccpp in sysctl file.")

        if not coreFlag:
            coreList = g_file.readFile(coreFile)
            for line in coreList:
                if "|" in line and "abrt-hook-ccpp" in line and not line.startswith("#"):
                    self.logger.debug("Find the abrt-hook-ccpp in file /proc/sys/kernel/core_pattern,"
                                      " the content is: %s." % line)
                    self.logger.logExit(ErrorCode.GAUSS_523["GAUSS_52301"] +
                                        " Core_pattern file can not use abrt-hook-ccpp to dump core.")
        self.logger.debug("Successfully check core_pattern.")

    def initGaussLog(self):
        """
        function: creating GaussLog path. Before we modify the owner of the path, we must create the path
        input : NA
        output: NA
        """
        sys.exit(0)

    def check_env_file(self):
        """
        """
        checkstatus, checkoutput = DefaultValue.checkEnvFile(self.mpprcFile)
        if self.mpprcFile != "":
            envfile = self.mpprcFile + " and /etc/profile"
        else:
            envfile = "/etc/profile and ~/.bashrc"
        if not checkstatus:
            self.logger.logExit(ErrorCode.GAUSS_518["GAUSS_51808"] % checkoutput + "Please check %s." % envfile)

    def run(self):
        try:
            self.parseCommandLine()
            self.checkParameter()
            self.initGlobals()
        except Exception as e:
            GaussLog.exitWithError(str(e))

        try:
            function_dict = {
                ACTION_CHECK_OS_VERSION: self.checkOSVersion,
                ACTION_CREATE_OS_USER: self.createOSUser,
                ACTION_CHECK_HOSTNAME_MAPPING: self.checkMappingForHostName,
                ACTION_CREATE_CLUSTER_PATHS: self.createClusterPaths,
                ACTION_SET_TOOL_ENV: self.setToolEnv,
                ACTION_SET_USER_ENV: self.setDBUerProfile,
                ACTION_PREPARE_USER_CRON_SERVICE: self.prepareUserCronService,
                ACTION_PREPARE_USER_SSHD_SERVICE: self.prepareUserSshdService,
                ACTION_SET_WARNING_ENV: self.setWarningEnv,
                ACTION_SET_LIBRARY: self.setLibrary,
                ACTION_SET_CGROUP: self.setCgroup,
                ACTION_INIT_GAUSSLOG: self.initGaussLog, }

            function_keys = function_dict.keys()
            if self.action in function_keys:
                function_dict[self.action]()
            elif self.action == ACTION_PREPARE_PATH:
                self.prepareGivenPath(self.preparePath, self.checkEmpty)
            elif self.action == ACTION_CHECK_OS_USER:
                global checkOSUser
                checkOSUser = True
                self.createOSUser()
            elif self.action == ACTION_SET_FINISH_FLAG:
                self.checkAbrt()
                self.checkRemoveIpc()
                self.setOSSar()
                # NIC multi queue configuration is lost after reboot, add it to the init file
                self.add_multi_queue_config_to_init_file()
                self.setFinishFlag()
                self.unsetHPMonitor()
            elif self.action == ACTION_SET_VIRTUALIP:
                DefaultValue.modifyFileOwnerFromGPHOME(self.logger.logFile)
                self.setVirtualIp()
            elif self.action == ACTION_SET_ARM_OPTIMIZATION:
                self.checkPlatformArm()
                if ARM_PLATE:
                    self.setArmOptimization()
                    try:
                        self.setCpuAffi()
                    except Exception as e:
                        self.logger.debug("Warning set cpu affinity failed. Error:\n%s" % str(e))
                else:
                    self.logger.debug("The plate is not arm, skip set arm options.")
            elif self.action == ACTION_CHECK_ENVFILE:
                self.check_env_file()
            else:
                self.logger.logExit(ErrorCode.GAUSS_500["GAUSS_50000"] % self.action)
        except Exception as e:
            self.logger.logExit(str(e))


if __name__ == '__main__':
    # main function
    try:
        preInstallUtility = PreInstall()
        preInstallUtility.run()
    except Exception as me:
        GaussLog.exitWithError(str(me))

