#!/usr/bin/env python3
# -*- coding:utf-8 -*-
#############################################################################
# Copyright (c) 2020 Huawei Technologies Co.,Ltd.
#
# openGauss is licensed under Mulan PSL v2.
# You can use this software according to the terms
# and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#
#          http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
# ----------------------------------------------------------------------------
# Description : PreInstallUtility.py is a utility to
# install the cluster on local node.
#############################################################################

import getopt
import sys
import os
import shutil
import subprocess
import time
import pwd
import grp
import configparser
import re
import platform
from multiprocessing.dummy import Pool as ThreadPool


sys.path.append(sys.path[0] + "/../")
from gspylib.common.GaussLog import GaussLog
from gspylib.common.ParameterParsecheck import Parameter
from gspylib.common.Common import DefaultValue
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 os_platform.gsservice import g_service
from base_utils.executor.cmd_executor import CmdExecutor
from domain_utils.cluster_file.cluster_config_file import ClusterConfigFile
from base_utils.os.cmd_util import CmdUtil
from domain_utils.cluster_file.cluster_dir import ClusterDir
from domain_utils.cluster_file.cluster_log import ClusterLog
from base_utils.os.file_util import FileUtil
from base_utils.os.disk_util import DiskUtil
from domain_utils.cluster_file.profile_file import ProfileFile
from domain_utils.cluster_file.version_info import VersionInfo
from domain_utils.cluster_file.package_info import PackageInfo
from base_utils.os.sshd_config import SshdConfig
from base_utils.os.env_util import EnvUtil
from base_utils.os.net_util import NetUtil
from domain_utils.domain_common.cluster_constants import ClusterConstants
from os_platform.linux_distro import LinuxDistro
from domain_utils.cluster_os.cluster_user import ClusterUser
from gspylib.common.aes_cbc_util import AesCbcUtil
from base_utils.os.user_util import UserUtil
from gspylib.component.DSS.dss_comp import DssInitCfg, Dss, UdevContext
from gspylib.component.DSS.dss_checker import DssConfig

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_LIBRARY = "set_library"
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"
ACTION_CHECK_DISK_SPACE = "check_disk_space"
ACTION_SET_WHITELIST = "set_white_list"
ACTION_CHECK_OS_SOFTWARE = "check_os_software"
ACTION_FIX_SERVER_PACKAGE_OWNER = "fix_server_package_owner"
ACTION_CHANGE_TOOL_ENV = "change_tool_env"
ACTION_SET_CGROUP = "set_cgroup"
ACTION_CHECK_CONFIG = "check_config"
ACTION_DSS_NIT = "dss_init"
ACTION_CHECK_CPU_INSTRUCTIONS = "check_cpu_instructions"
ACTION_CHECK_NOFILE_LIMIT = "check_nofile_limit"

g_nodeInfo = None
envConfig = {}
configuredIps = []
checkOSUser = False
instance_type_set = ()
software_list = ["bzip2"]

ARM_PLATE = False


def get_package_path():
    """
    get package path
    :return:
    :return:
    """
    dir_name = os.path.dirname(os.path.realpath(__file__))
    package_path = os.path.join(dir_name, "./../../")
    package_path = os.path.realpath(package_path)
    return package_path


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

    def __init__(self):
        """
        function: constructor
        """
        self.action = ""
        self.userInfo = ""
        self.user = ""
        self.group = ""
        self.clusterConfig = ""
        self.preparePath = ""
        self.checkEmpty = False
        self.envParams = []
        self.logFile = ""
        self.mpprcFile = ""
        self.user_env_file = ""
        self.clusterToolPath = ""
        self.tmpFile = ""
        self.clusterAppPath = ""
        self.white_list = {}
        self.logger = None
        self.current_user_root = False
        self.cluster_core_path = ""

    def get_current_user(self):
        """
        get current user
        """
        user_info = UserUtil.getUserInfo()
        if user_info['uid'] == 0:
            self.current_user_root = True

    def initGlobals(self):
        """
        init global variables
        input : NA
        output: NA
        """
        global instance_type_set

        self.logger = GaussLog(self.logFile, self.action)
        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 = NetUtil.GetHostIpOrName()
        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.
    -e "envpara=value"                The OS user environment variable.
    --check_empty                     Check path empty.
    -s                                The path of MPP environment file.
    -l                                The path of log file.
    -R                                The path of cluster install path.
    -C                                The path of cluster core path.
    --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:e:s:l:f:R:C:",
                                       ["check_empty", "help"])
        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,
                         "-s": self.mpprcFile, "-f": self.tmpFile,
                         "-R": self.clusterAppPath, "-C": self.cluster_core_path}
        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)
                self.tmpFile = 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.mpprcFile = parameter_map["-s"]
        self.tmpFile = parameter_map["-f"]
        self.clusterAppPath = parameter_map["-R"]
        self.cluster_core_path = parameter_map["-C"]

    def checkParameter(self):
        """
        function: Check parameter from command line
        input : NA
        output: NA
        """
        if (self.user == "" and self.action not in [ACTION_SET_VIRTUALIP,
                                                    ACTION_SET_WHITELIST]):
            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):
                ClusterUser.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_CHECK_OS_SOFTWARE, \
                          ACTION_SET_ARM_OPTIMIZATION,
                          ACTION_CHECK_DISK_SPACE, ACTION_SET_WHITELIST,
                          ACTION_FIX_SERVER_PACKAGE_OWNER, ACTION_DSS_NIT,
                          ACTION_CHANGE_TOOL_ENV, ACTION_CHECK_CONFIG, ACTION_CHECK_CPU_INSTRUCTIONS,
                          ACTION_CHECK_NOFILE_LIMIT]
        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_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)
        else:
            self.mpprcFile = os.path.normpath(os.path.join(os.path.expanduser("~%s" % self.user), ".bashrc"))

        if self.logFile == "":
            self.logFile = ClusterLog.getOMLogPath(
                ClusterConstants.LOCAL_LOG_FILE, self.user, "", self.clusterConfig)

    def prepareMpprcFile(self):
        """
        function: prepare MPPRC file, include path and permission
        input : NA
        output: NA
        """
        mpprcFilePath, mpprcFileName = 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.
            FileUtil.createDirectory(mpprcFilePath, True)
            if os.path.exists(self.mpprcFile):
                pass
            else:
                FileUtil.createFile(self.mpprcFile, False)
            FileUtil.changeMode(DefaultValue.KEY_DIRECTORY_MODE, ownerPath, True,
                              "shell")
            FileUtil.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 != "":
                FileUtil.changeOwner(self.user, ownerPath, True, "shell", link=True)
        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' + ".")

    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
            FileUtil.checkPathandChangeOwner(
                onePath, self.user,
                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:
            FileUtil.checkLink(ownerPath)
            if ownerPath != onePath:
                FileUtil.changeOwner(self.user, ownerPath, True, "shell", link=True)
                FileUtil.changeMode(DefaultValue.KEY_DIRECTORY_MODE, ownerPath,
                                  True, "shell")
            else:
                FileUtil.changeOwner(self.user, ownerPath, False, "shell", link=True)
        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
        try_flag = False
        while True:
            try_flag = FileUtil.createDirectory(onePath, True, dirMode)
            if try_flag:
                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 permisson error about GPHOME
        FileUtil.checkPathandChangeOwner(originalPath, self.user,
                                             DefaultValue.KEY_DIRECTORY_MODE)
        cmd = "cd %s" % originalPath
        cmd = CmdUtil.get_user_exec_cmd(self.current_user_root, username, cmd)
        status = subprocess.getstatusoutput(cmd)[0]
        if status != 0:
            return False

        if check_enter_only:
            return True

        testFile = os.path.join(originalPath, "touch.tst")
        cmd = "touch %s && chmod %s %s >/dev/null 2>&1" % (
                testFile, DefaultValue.KEY_FILE_MODE, testFile)
        cmd = CmdUtil.get_user_exec_cmd(self.current_user_root, username, cmd)
        status = subprocess.getstatusoutput(cmd)[0]
        if status != 0:
            return False

        cmd = "echo test > %s >/dev/null 2>&1" % testFile
        cmd = CmdUtil.get_user_exec_cmd(self.current_user_root, username, cmd)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            cmd = "rm -f '%s' >/dev/null 2>&1" % testFile
            subprocess.getstatusoutput(cmd)
            return False

        cmd = "rm -f '%s' >/dev/null 2>&1" % testFile
        (status, output) = subprocess.getstatusoutput(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.")
        if os.getuid() == 0:
            self.logger.debug("Change file[/etc/hosts] mode.")
            FileUtil.changeMode(DefaultValue.HOSTS_FILE, "/etc/hosts")
        try:
            node_names = self.clusterInfo.getClusterNodeNames()
            pool = ThreadPool(DefaultValue.getCpuSet())
            pool.map(self.check_hostname, node_names)
            pool.close()
            pool.join()
        except Exception as e:
            self.logger.logExit(str(e))

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

    def check_hostname(self, node_name):
        """
        function: Checking hostname mapping
        input : NA
        output: NA
        """
        retry = 1
        cmd = "source %s;pssh -s -H %s hostname" % (self.mpprcFile, node_name)
        while True:
            (status, output) = subprocess.getstatusoutput(cmd)
            self.logger.debug("Checking hostname mapping for node [%s]. output: %s" % (node_name, output))
            if status == 0 and output.find(node_name) >= 0:
                break
            if retry >= 3:
                raise Exception(ErrorCode.GAUSS_512["GAUSS_51222"]
                                + " Command: \"%s\". Error: \n%s"
                                % (cmd, output))
            retry += 1
            time.sleep(1)

    def checkPasswdIsExpires(self):
        """
        function: Check if user password is expires
        input : NA
        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 : filename
        output: NA
        """
        try:
            if os.path.isfile(filename):
                FileUtil.removeFile(filename, "shell")
        except Exception as e:
            raise Exception(str(e))

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

        # No results found. "grep" returns non-zero if nothing grepped.
        # AllowItem in sshd_config is disabled.
        if (status != 0) and (output is None or len(output) == 0):
            self.logger.debug("'%s' of sshd_config is disabled." % allow_item)
            return 0
        elif status != 0:
            # It really failed.
            self.logger.logExit(
                ErrorCode.GAUSS_503["GAUSS_50321"] % allow_item + " Command: %s. Error: \n%s"
                % (allow_item_cmd, output))
            return 0
        else:
            allow_item_res = str(output).lstrip().lstrip("\t")
            if allow_item_res.find('#') == 0:
                return 0
            elif allow_item_res.find('#') > 0:
                allow_item_res = allow_item_res[0: allow_item_res.find('#')]
            if item_value not in allow_item_res.split(' '):
                set_allow_item_cmd = "sed -i '/\\<%s\\>/d' %s" % (allow_item, sshd_config)
                (status, output) = subprocess.getstatusoutput(set_allow_item_cmd)
                if status != 0:
                    self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % set_allow_item_cmd +
                                        " Error:\n%s" % output)
                SshdConfig.setKeyValueInSshd(allow_item_res, item_value)
        # Attention: here we will not restart sshd service,
        # as it will be done in "prepareUserSshdService".
        self.logger.debug("item_value '%s' added to '%s' of %s successfully." %
                          (item_value, allow_item, sshd_config))
        return 1

    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 = 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
        needChgOwner = False
        if userstatus == 1:
            userHomePath = "/home/%s" % self.user
            if os.path.exists(userHomePath):
                try:
                    homePathUser = FileUtil.getfileUser(userHomePath)[0]
                    if homePathUser != self.user:
                        needChgOwner = True
                except Exception:
                    needChgOwner = True

        # Check if group exists
        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)

        # user exists and input group not exists
        if userstatus == 0 and groupstatus != 0:
            self.logger.logExit(ErrorCode.GAUSS_503["GAUSS_50305"]
                                + " User:Group[%s:%s]"
                                % (self.user, self.group))

        # 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:
            self.logger.debug("checkOSUser is[%s] and abnormal exit!" %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))
        if needChgOwner:
            userProfile = ClusterConstants.HOME_USER_BASHRC % self.user
            if not os.path.exists(userProfile):
                cmd = g_file.SHELL_CMD_DICT["copyFile"] % \
                      ("/etc/skel/.bash*", "/home/%s/" % self.user)
                status, output = subprocess.getstatusoutput(cmd)
                if status != 0:
                    self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50214"]
                                        % userProfile + " Error: " + output)
            FileUtil.changeOwner(self.user, "/home/%s/" % self.user, True)

        self.logger.debug("Changing user password.")
        try:
            # check if the file is a link
            tmp_path = "/tmp/os_user_pwd"
            password = AesCbcUtil.aes_cbc_decrypt_with_multi(*AesCbcUtil.format_path(tmp_path))
            cmd = "rm -rf %s" % tmp_path
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                raise Exception(ErrorCode.GAUSS_511["GAUSS_51103"] % cmd)
        except Exception as e:
            self.delTempFile(tempFile)
            self.logger.debug("Changing user password failed. %s" % str(e))
            self.logger.logExit(ErrorCode.GAUSS_503["GAUSS_50311"] % "user")

        cmd = "echo '%s:%s' | chpasswd" % (self.user, password)
        (status, output) = CmdUtil.getstatusoutput_by_fast_popen(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.prepare_om_tools_bin_path()
        self.prepareGaussLogPath()
        self.prepareInstallPath(needCheckEmpty)
        self.prepareTmpPath(needCheckEmpty)
        self.prepareDataPath(needCheckEmpty)
        if self.clusterInfo.enable_dss == 'on':
            idx = DssConfig.get_current_dss_id_by_dn(self.clusterInfo.dbNodes,
                                                     self.dbNodeInfo)
            if idx != -1 and not EnvUtil.is_fuzzy_upgrade(
                    self.user, self.logger, self.mpprcFile):
                self.prepare_dss_home_path(idx)
            else:
                self.logger.debug('In dss-mode, the dn does not ' \
                     'exist on the current node or in upgrade.')

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


    def prepare_dss_inst_ini(self, dss_home, dss_id):
        '''
        Preparing the DSS Configuration File
        '''

        dss_inst_ini = os.path.realpath(
            os.path.join(dss_home, 'cfg', 'dss_inst.ini'))
        context = list(
            DssInitCfg(dss_id,
                       dss_home,
                       self.clusterInfo.dss_config,
                       dss_ssl=False))
        FileUtil.write_custom_context(
            dss_inst_ini, context, authority=DefaultValue.KEY_FILE_MODE_IN_OS)

    def prepare_dss_vg_ini(self, dss_home):
        '''
        Preparing the VG Configuration File
        '''
        dss_vg_ini = os.path.realpath(
            os.path.join(dss_home, 'cfg', 'dss_vg_conf.ini'))

        context = [
            ':'.join([k, v]) for k, v in {
                **self.clusterInfo.dss_shared_disks,
                **self.clusterInfo.dss_pri_disks
            }.items()
        ]
        FileUtil.write_custom_context(
            dss_vg_ini, context, authority=DefaultValue.KEY_FILE_MODE_IN_OS)

    def prepare_cm_vg_ini(self, dss_home):
        '''
        Preparing the VG Configuration File
        '''
        dss_vg_ini = os.path.realpath(
            os.path.join(dss_home, 'cfg', 'dss_cm_conf.ini'))

        context = [
            self.clusterInfo.cm_share_disk,
            self.clusterInfo.cm_vote_disk
        ]
        FileUtil.write_custom_context(
            dss_vg_ini, context, authority=DefaultValue.KEY_FILE_MODE_IN_OS)

    def prepare_dss_home_path(self, dss_id):
        '''
        Preparing the DSS Home Directory
        '''

        dss_home = self.clusterInfo.dss_home
        dss_cfg = os.path.join(dss_home, 'cfg')
        dss_log = os.path.join(dss_home, 'log')
        self.prepareGivenPath(dss_cfg, False)
        self.prepareGivenPath(dss_log, False)
        self.prepare_dss_inst_ini(dss_home, dss_id)
        # this function does not need to be detected under multipath
        self.prepare_dss_vg_ini(dss_home)
        self.prepare_cm_vg_ini(dss_home)


    def prepare_dss_soft_link(self):
        '''
        Creating a disk soft link
        '''

        self.logger.debug("Creating dss disk link.")
        context = list(
            UdevContext((self.user, self.group), self.clusterInfo,
                        DiskUtil.get_disk_dev_id, DiskUtil.get_disk_dev_name))

        self.logger.debug("Checking dss udev directory.")
        if os.path.isdir(UdevContext.DSS_UDEV_DIR):
            rule_file = os.path.join(UdevContext.DSS_UDEV_DIR,
                                     UdevContext.DSS_UDEV_NAME) % self.user

            for disk in UdevContext.get_all_phy_disk(self.clusterInfo):
                cmd = "cd %s; grep -iro '%s' | grep -v grep | grep -v '%s'" % (
                    UdevContext.DSS_UDEV_DIR, DiskUtil.get_disk_dev_id(disk),
                    UdevContext.DSS_UDEV_NAME % self.user)
                sts, out = subprocess.getstatusoutput(cmd)
                if sts == 1:
                    continue
                if sts != 0 :
                    raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd +
                                    "Error: \n%s" % out)
                if out.strip():
                    raise Exception(ErrorCode.GAUSS_514["GAUSS_51406"] %
                                    (disk, UdevContext.DSS_UDEV_DIR) +
                                    " Error information: \n%s." % out)
        else:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] %
                            UdevContext.DSS_UDEV_DIR)

        if os.path.isfile(rule_file):
            os.remove(rule_file)
        FileUtil.write_custom_context(rule_file,
                                      context,
                                      authority=DefaultValue.KEY_HOSTS_FILE)
        FileUtil.changeMode(DefaultValue.SQL_FILE_MODE, rule_file)
        FileUtil.changeOwner('root', rule_file)

        retry = 30
        for times in range(retry):
            DiskUtil.active_udev()
            flags = all([
                os.path.islink(link) for link in UdevContext.get_all_disk_alias(
                    self.user, self.group, self.clusterInfo)
            ])
            if not flags and times == retry - 1:
                raise Exception(ErrorCode.GAUSS_516['GAUSS_51656'])
            elif not flags:
                time.sleep(1)
            elif flags:
                break
        self.logger.debug("Successfully created dss disk link.")

    def prepare_om_tools_bin_path(self):
        """
        function: Prepare om tools bin path
        input : NA
        output: NA
        """
        self.logger.debug("Creating om tools bin path.")
        bin_path = os.path.join(self.clusterToolPath, "bin")
        # check bin path
        self.logger.debug("Checking %s directory [%s]." % (VersionInfo.PRODUCT_NAME, bin_path))
        if not os.path.exists(bin_path):
            self.makeDirsInRetryMode(bin_path, DefaultValue.MAX_DIRECTORY_MODE)
        try:
            FileUtil.checkLink(bin_path)
            FileUtil.changeMode(DefaultValue.MAX_DIRECTORY_MODE, bin_path, False, "shell")
            FileUtil.changeOwner(self.user, bin_path, False, "shell", link=True)
        except Exception as e:
            raise Exception(str(e))

    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
            FileUtil.checkLink(gaussdb_dir)
            FileUtil.changeMode(DefaultValue.DIRECTORY_MODE, gaussdb_dir, False,
                              "shell")
            FileUtil.changeOwner(self.user, gaussdb_dir, False, "shell", link=True)
        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
        FileUtil.getchangeFileModeCmd(user_dir)

        # change user log dir owner
        try:
            FileUtil.changeOwner(self.user, user_dir, True, "shell",
                               retry_flag=True, retry_time=15, waite_time=1, link=True)
        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.")
        if g_nodeInfo.cmDataDir:
            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 database node 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 database node XLOG PATH configuration.")
        for dnInst in g_nodeInfo.datanodes:
            if dnInst.xlogdir != '':
                self.prepareGivenPath(dnInst.xlogdir, 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
        if os.path.exists(installPath) and not os.path.islink(installPath):
            self.logger.logExit(ErrorCode.GAUSS_502[
                                    "GAUSS_50200"] % installPath
                                + " Please remove it."
                                  " It should be a symbolic link to "
                                  "$GAUSSHOME if it exists")
        versionFile = VersionInfo.get_version_file()
        commitid = VersionInfo.get_version_info(versionFile)[2]
        installPath = installPath + "_" + commitid
        if not needCheckEmpty:
            # check the upgrade app directory, if we set up a new
            # directory for upgrade, we must check empty
            gaussHome = ClusterDir.getInstallDir(self.user)
            if os.path.islink(gaussHome):
                actualPath = os.path.realpath(gaussHome)
                oldCommitId = actualPath[-8:]
                if oldCommitId != commitid and os.path.isdir(installPath):
                    fileList = os.listdir(installPath)
                    # mat have upgrade some node, so the dir should
                    # have the binary info
                    # if use other version to preinstall when upgrade
                    # is not finished, then we need to preinstall
                    # current upgrade version
                    if "bin" in fileList and "etc" in fileList and \
                            "include" in fileList:
                        pass
                    else:
                        needCheckEmpty = True

        self.logger.debug("Install path %s." % installPath)
        self.prepareGivenPath(installPath, needCheckEmpty)
        self.checkUpperPath(needCheckEmpty, installPath)

        if self.clusterInfo.enable_dss:
            dss_app = os.path.realpath(
                os.path.join(os.path.dirname(installPath),
                             f'dss_app_{commitid}'))
            self.logger.debug("Dss app path %s." % dss_app)
            self.prepareGivenPath(dss_app, False)

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

    def checkUpperPath(self, needCheckEmpty, installPath):
        """
        if first prepare the path, we should have the permission to
         write file with self.user, so we can create
        symbolic link in install process
        :param needCheckEmpty: get GAUSS_ENV is 2, we have successfully
        install the cluster, so needCheckEmpty is False
        :param installPath: is same with $GAUSSHOME
        :return: NA
        """
        if not needCheckEmpty:
            return
        upperDir = os.path.dirname(installPath)
        cmd = "if [ -w %s ];then echo 1; else echo 0;fi" % upperDir
        cmd = CmdUtil.get_user_exec_cmd(self.current_user_root, self.user, cmd)
        self.logger.debug(
            "Command to check if we have write permission for upper path:"
            " %s" % cmd)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(
                ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + "Error: \n%s" % str(
                    output))
        if output:
            output = output.splitlines()[-1]
        if output == "1":
            return
        fileList = os.listdir(upperDir)
        if installPath in fileList:
            fileList.remove(installPath)
        if len(fileList) != 0:
            self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50202"] % upperDir +
                                " Or user [%s] has write"
                                " permission to directory %s."
                                " Because it will create "
                                "symbolic link [%s] to install path [%s] "
                                "in gs_install process with this user."
                                % (self.user, upperDir,
                                   self.clusterInfo.appPath, installPath))
        self.logger.log("The path [%s] is empty, change the owner to %s." % (
            upperDir, self.user))
        FileUtil.changeOwner(self.user, upperDir, False, "shell", link=True)
        self.logger.log("Successfully change the owner.")

    def prepareUserCronService(self):
        """
        function:
        1.set cron bin permission
        2.check and make sure user have pemission to use cron
        3.restart cron service
        input : NA
        output: NA
        """
        if not self.current_user_root:
            return
        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
        FileUtil.changeOwner("root", crontabFile)
        FileUtil.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):
            FileUtil.createFile(cron_allow_file)
        FileUtil.changeMode(DefaultValue.KEY_FILE_MODE, cron_allow_file)
        FileUtil.changeOwner("root", cron_allow_file)

        FileUtil.deleteLine(cron_allow_file, "^\\s*%s\\s*$" % self.user)
        FileUtil.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 > 1:
                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 prepareUserSshdService(self):
        """
        function: set MaxStartups to 1000.
        input : NA
        output: NA
        """
        if not self.current_user_root:
            return
        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)
            SshdConfig.setKeyValueInSshd('MaxStartups', '1000')
            self.logger.debug("Write MaxStartups value.")
            sshdNeedReload = True

        # Check if is DWS mode.
        OsVersionFlag = False
        rdsFlag = False
        chrootFlag = False
        distname = LinuxDistro.linux_distribution()[0]
        if distname in "euleros":
            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)
            SshdConfig.setKeyValueInSshd('ClientAliveInterval', '0')
            self.logger.debug("Write ClientAliveInterval value.")
            sshdNeedReload = True

        # 3. add cluster owner to 'AllowUsers' or 'AllowGroups' to
        # /etc/ssh/sshd_config if necessary.
        if self.addAllowItemValue(allow_item="AllowUsers", item_value=self.user) > 0:
            sshdNeedReload = True

        if self.addAllowItemValue(allow_item="AllowGroups", item_value=self.group) > 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 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
        hiden:
          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
        self.user_env_file = ProfileFile.get_user_bashrc(self.user)
        if self.mpprcFile != "" and self.mpprcFile is not None:
            userProfile = self.mpprcFile
        else:
            # check if user profile exist
            userProfile = self.user_env_file
            if not os.path.exists(userProfile):
                self.logger.logExit(ErrorCode.GAUSS_502[
                                        "GAUSS_50201"] % 'user profile'
                                    + " Please create %s." % userProfile)

        # clean user's environmental variable
        self.logger.debug("Deleting user's environmental variable.")
        DefaultValue.cleanUserEnvVariable(userProfile,
                                          cleanGS_CLUSTER_NAME=False, cleanLD_LIBRARY=False)
        self.logger.debug("Successfully delete user's environmental variable.")
        if self.mpprcFile:
            # import environment variable separation scene to bashrc
            FileUtil.deleteLine(self.user_env_file,
                                "^\\s*export\\s*%s=.*$" % DefaultValue.MPPRC_FILE_ENV)
            context = "export %s=%s" % (DefaultValue.MPPRC_FILE_ENV, self.mpprcFile)
            FileUtil.writeFile(self.user_env_file, [context])
            self.logger.debug("Successfully flush 'export MPPRC' in bashrc")

        # user's environmental variable
        self.logger.debug("Seting user's environmental variable.")
        installPath = self.clusterInfo.appPath
        tmpPath = ClusterConfigFile.readClusterTmpMppdbPath(self.user,
                                                           self.clusterConfig)
        logPath = "%s/%s" % (
            ClusterConfigFile.readClusterLogPath(self.clusterConfig), self.user)
        agentPath = self.clusterInfo.agentPath
        agentLogPath = self.clusterInfo.agentLogPath
        FileUtil.checkLink(userProfile)
        DefaultValue.setUserEnvVariable(userProfile, installPath, tmpPath,
                                        logPath, agentPath, agentLogPath)

        if (os.path.exists('/var/chroot/') and os.path.exists(
                '/rds/datastore/')):
            clusterName = self.clusterInfo.name
            ProfileFile.updateUserEnvVariable(userProfile, "GS_CLUSTER_NAME",
                                               clusterName)

        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
        distname, version, idnum = LinuxDistro.linux_distribution()
        # check if OS version is Euler
        if distname in "euleros":
            OsVersionFlag = True
        if os.path.exists("/rds/"):
            rdsFlag = True
        if os.path.exists("/var/chroot/"):
            chrootFlag = True
        # 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)
        FileUtil.changeOwner(self.user, user_dir, True, "shell", retry_flag=True,
                           retry_time=15, waite_time=1, link=True)
        omLogPath = os.path.dirname(self.logFile)
        self.logger.debug(
            "Changing the owner of preinstall log path: %s." % omLogPath)
        if os.path.exists(omLogPath):
            FileUtil.changeOwner(self.user, omLogPath, True, "shell",
                               retry_flag=True, retry_time=15, waite_time=1, link=True)
        self.logger.debug("Checking the permission of GPHOME: %s." % user_dir)
        cmd = "cd %s" % user_dir
        cmd = CmdUtil.get_user_exec_cmd(self.current_user_root, self.user, cmd)
        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.")

        # get the value of GAUSS_ENV
        self.logger.debug("Setting finish flag.")
        cmd = "source %s;echo $GAUSS_ENV 2>/dev/null" % userProfile
        cmd = CmdUtil.get_user_exec_cmd(self.current_user_root, self.user, cmd)
        (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":
            ProfileFile.updateUserEnvVariable(userProfile, "GAUSS_ENV", "1")

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

    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
            cmd = CmdUtil.get_user_exec_cmd(self.current_user_root, self.user, cmd)
        else:
            cmd = "source ~/.bashrc;echo $GAUSS_ENV 2>/dev/null"
            cmd = CmdUtil.get_user_exec_cmd(self.current_user_root, self.user, cmd)
        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, 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 profile exist
            userProfile = ProfileFile.get_user_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:
            FileUtil.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])
            FileUtil.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
            user_profile = self.mpprcFile
            if not os.path.exists(user_profile):
                FileUtil.createFile(user_profile)
                FileUtil.changeMode(DefaultValue.DIRECTORY_MODE, user_profile)
            FileUtil.changeOwner(self.user, user_profile)
        else:
            # check if os profile exist
            user_profile = ProfileFile.get_user_bashrc(self.user)
            if not os.path.exists(user_profile):
                self.logger.debug(
                    "Profile does not exist. Please create %s." % user_profile)
                FileUtil.createFile(user_profile)
                FileUtil.changeMode(DefaultValue.DIRECTORY_MODE, user_profile)
        return user_profile

    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("=", 1)
            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(envConfig)

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

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

        # clean GPHOME
        FileUtil.deleteLine(userProfile, "^\\s*export\\s*GPHOME=.*$")
        # clean COREPATH
        FileUtil.deleteLine(userProfile, "^\\s*export\\s*COREPATH=.*$")
        # clean UNPACKPATH
        FileUtil.deleteLine(userProfile, "^\\s*export\\s*UNPACKPATH=.*$")
        self.logger.debug(
            "Deleting crash GPHOME in user environment variables.")
        # clean PGDATA
        FileUtil.deleteLine(userProfile, "^\\s*export\\s*PGDATA*")
        # clean PGPORT
        FileUtil.deleteLine(userProfile, "^\\s*export\\s*PGPORT*")
        # clean PGDATABASE
        FileUtil.deleteLine(userProfile, "^\\s*export\\s*PGDATABASE*")
        # clean LD_LIBRARY_PATH
        FileUtil.deleteLine(userProfile,
                          "^\\s*export\\s*LD_LIBRARY_PATH=\\$GPHOME\\/script"
                          "\\/gspylib\\/clib:\\$LD_LIBRARY_PATH$")
        FileUtil.deleteLine(userProfile,
                          "^\\s*export\\s*LD_LIBRARY_PATH=\\$GPHOME\\/lib:"
                          "\\$LD_LIBRARY_PATH$")
        self.logger.debug(
            "Deleting crash LD_LIBRARY_PATH in user environment variables.")

        # clean PATH
        if userProfile is ClusterConstants.ETC_PROFILE:
            FileUtil.deleteLine(userProfile,
                                "^\\s*export\\s*PATH=\\$PATH:\\$GPHOME\\/pssh-2.3.1\\/bin:"
                                "\\$GPHOME\\/script$")
            FileUtil.deleteLine(userProfile,
                                "^\\s*export\\s*PATH=\\$PATH:\\$GPHOME\\/script\\/gspylib\\"
                                "/pssh\\/bin:\\$GPHOME\\/script$")
            FileUtil.deleteLine(userProfile,
                                "^\\s*export\\s*PATH=\\$PATH:\\/root\\/gauss_om\\/%s\\"
                                "/script$" % self.user)
        FileUtil.deleteLine(userProfile,
                          "^\\s*export\\s*PATH=\\$GPHOME\\/pssh-2.3.1\\/bin:"
                          "\\$GPHOME\\/script:\\$PATH$")
        FileUtil.deleteLine(userProfile,
                          "^\\s*export\\s*PATH=\\$GPHOME\\/script\\/gspylib\\"
                          "/pssh\\/bin:\\$GPHOME\\/script:\\$PATH$")
        FileUtil.deleteLine(userProfile,
                          "^\\s*export\\s*PATH=\\/root\\/gauss_om\\/%s\\"
                          "/script:\\$PATH$" % self.user)
        self.logger.debug("Deleting crash PATH in user environment variables.")
        # clean PYTHONPATH
        FileUtil.deleteLine(userProfile,
                          "^\\s*export\\s*PYTHONPATH=\\$GPHOME\\/lib")
        self.logger.debug(
            "Deleting crash PYTHONPATH in user environment variables.")

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

        self.clearToolEnv(userProfile)

        # 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
            FileUtil.checkLink(userProfile)
            # set mpprc file
            if self.mpprcFile != "":
                context = "export %s=%s" % (
                    DefaultValue.MPPRC_FILE_ENV, self.mpprcFile)
                FileUtil.writeFile(userProfile, [context])
            # set GPHOME
            FileUtil.writeFile(userProfile,
                             ["export GPHOME=%s" % self.clusterToolPath])
            package_dir = os.path.realpath(os.path.join(os.path.realpath(__file__), "../../../"))
            FileUtil.writeFile(userProfile, ["export UNPACKPATH=%s" % package_dir])
            # set PGDATA
            hostName = NetUtil.GetHostIpOrName()
            node_info = self.clusterInfo.getDbNodeByName(hostName)
            datadir = node_info.datanodes[0].datadir
            FileUtil.writeFile(userProfile,
                             ["export PGDATA=%s" % datadir])
            
            # set COREPATH
            FileUtil.writeFile(userProfile, ["export COREPATH=%s" % self.cluster_core_path])
            # set PGDATABASE
            FileUtil.writeFile(userProfile, ["export PGDATABASE=%s" % "postgres"])

            # set PGPORT
            basePort = node_info.datanodes[0].port
            FileUtil.writeFile(userProfile, ["export PGPORT=%d" % basePort])

            # set PATH
            if userProfile is ClusterConstants.ETC_PROFILE:
                FileUtil.writeFile(userProfile, [
                    "export PATH=$PATH:$GPHOME/script/gspylib/pssh/bin:"
                    "$GPHOME/script"])
            else:
                FileUtil.writeFile(userProfile, [
                    "export PATH=$GPHOME/script/gspylib/pssh/bin:"
                    "$GPHOME/script:$PATH"])
            # set LD_LIBRARY_PATH
            FileUtil.writeFile(userProfile, [
                "export LD_LIBRARY_PATH="
                "$GPHOME/script/gspylib/clib:$LD_LIBRARY_PATH"])
            FileUtil.writeFile(userProfile, [
                "export LD_LIBRARY_PATH=$GPHOME/lib:$LD_LIBRARY_PATH"])
            # set PYTHONPATH
            FileUtil.writeFile(userProfile, ["export PYTHONPATH=$GPHOME/lib"])


        except Exception as e:
            self.logger.logExit(str(e))
        self.logger.debug("Successfully set tool ENV.")

    def setLibrary(self):
        """
        function: Setting Library
        input : NA
        output: NA
        """
        if not self.current_user_root:
            return
        self.logger.debug("Setting Library.")
        config_file_dir = "/etc/ld.so.conf"
        alreadySet = False
        # check if the file is a link
        FileUtil.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 needSetCgroup(self):
        """
        function: Determine whether the current node needs to set Cgroup
        input : NA
        output: True     #need to set cgroup
                False    #not need to set cgroup
        """
        #Determine whether action is expansion.
        hostName = NetUtil.GetHostIpOrName()
        if len(self.clusterInfo.newNodes) == 0:
            return True
        #Determine whether the current node is a new node
        for node in self.clusterInfo.newNodes:
            if hostName == node.name:
                return True
        self.logger.debug("The current node is the old node for expansion, no need to set cgroup.")
        return False

    def decompressPkg2Cgroup(self):
        """
        function: decompress server package to libcgroup path. gs_cgroup will be used in preinstall
                  step.
        input: NA
        output: NA
        """
        self.logger.debug("decompress server package to libcgroup path.")

        bz2FileName = PackageInfo.get_package_file_path()
        curPath = os.path.dirname(os.path.realpath(__file__))
        libCgroupPath = os.path.realpath("%s/../../libcgroup" % curPath)
        if not os.path.exists(libCgroupPath):
            os.makedirs(libCgroupPath)

        cmd = "tar -xf %s -C %s" % (bz2FileName, libCgroupPath)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50217"] % bz2FileName +
                                " Error: \n%s" % output)

        # load library path env
        ld_path = os.path.join(libCgroupPath, "lib")
        if 'LD_LIBRARY_PATH' not in os.environ:
            os.environ['LD_LIBRARY_PATH'] = ld_path
            os.execve(os.path.realpath(__file__), sys.argv, os.environ)
        if not os.environ.get('LD_LIBRARY_PATH').startswith(ld_path):
            os.environ['LD_LIBRARY_PATH'] = ld_path + ":" + os.environ['LD_LIBRARY_PATH']
            os.execve(os.path.realpath(__file__), sys.argv, os.environ)

    def setCgroup(self):
        """
        function: Setting Cgroup
        input : NA
        output: NA
        """
        if not self.needSetCgroup():
            return
        self.logger.debug("Setting Cgroup.")
        # decompress server pakcage
        self.decompressPkg2Cgroup()
        #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.realpath("%s/../../libcgroup/lib/libcgroup.so" % dirName)
        cgroup_exe_dir = os.path.realpath("%s/../../libcgroup/bin/gs_cgroup" % dirName)
        cmd = "rm -rf '%s/%s'" % (self.clusterToolPath, self.user)
        (status, output) = CmdUtil.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 -h;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)

        # check or prepare libcgroup lib
        libcgroup_target = "/usr/local/lib/libcgroup.so.1"
        cmd = "ldd %s | grep 'libcgroup.so.1'" % cgroup_exe_dir
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)
        elif str(output).find("not found") != -1:
            cmd = "cp '%s' '%s' && ldconfig" % (libcgroup_dir, libcgroup_target)
            self.logger.debug("Need copy libcgroup.so.1 from %s to %s." %
                              (libcgroup_dir, libcgroup_target))
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50214"] % libcgroup_target +
                                    " Error: \n%s" % output)

        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)

        #create cgroup log file.
        binPath = self.clusterInfo.logPath + "/%s/bin/gs_cgroup/" % self.user
        if not os.path.exists(binPath):
            FileUtil.createDirectory(binPath)
        cgroupLog = binPath + "gs_cgroup.log"
        c_logger = GaussLog(cgroupLog, "gs_cgroup")

        #Get OS startup file
        initFile = DefaultValue.getOSInitFile()
        if initFile == "":
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % "startup file of current OS" +
                            "The startup file for euleros OS is /etc/rc.d/rc.local.")

        # call cgroup
        # generate cgroup config file under cluster tool path.
        # and then copy it to GAUSSHOME path in gs_install step.
        execute_cmd = "%s -U %s --upgrade -c -H %s/%s" % (cgroup_exe_dir, self.user,
                                                          self.clusterToolPath, self.user)
        c_logger.debug("Command for executing gs_cgroup: %s\n" % execute_cmd)
        (status, output) = subprocess.getstatusoutput(execute_cmd)
        c_logger.debug("The result of execute gs_cgroup is:\n%s." % output)

        # set cgroup cmd to OS initFile. it will be executed at restart os system.
        gauss_home = self.clusterInfo.appPath
        init_cmd = "export LD_LIBRARY_PATH=%s/lib/ && %s/bin/gs_cgroup -U %s --upgrade -c -H %s" % \
             (gauss_home, gauss_home, self.user, gauss_home)
        set_init_cmd = "sed -i \"/.* -U %s .* -c -H .*/d\" %s && " % (self.user, initFile)
        set_init_cmd += "echo \"%s\" >> %s" % (init_cmd, initFile)
        c_logger.debug("Command for call cgroup cmd to init file: %s\n" % set_init_cmd)

        (status, output) = subprocess.getstatusoutput(set_init_cmd)
        c_logger.debug("The result of init gs_cgroup is:\n%s." % output)
        c_logger.debug(str(output))
        #Change the owner and permission.
        FileUtil.checkLink(binPath)
        FileUtil.changeOwner(self.user, binPath, True, retry_flag=True, link=True)
        FileUtil.changeMode(DefaultValue.KEY_DIRECTORY_MODE, binPath, retry_flag=True)
        FileUtil.changeMode(DefaultValue.KEY_FILE_MODE, (binPath + "*"), retry_flag=True)
        if self.clusterInfo.logPath.strip() != "":
            pre_bin_path = self.clusterInfo.logPath + "/%s/bin" % self.user
            FileUtil.changeOwner(self.user, pre_bin_path, True, retry_flag=True, link=True)
        c_logger.closeLog()
        if status != 0:
            self.logger.logExit(str(output))

        self.logger.debug("Successfully set Cgroup.")

    def checkaio(self):
        # check libaio.so file exist
        cmd = "ls /usr/local/lib | grep '^libaio.so' | wc -l"
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)
        elif int(output) == 0:
            cmd = "ls /usr/lib64 | grep '^libaio.so' | wc -l"
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd +
                                    " Error: \n%s" % output)
            elif int(output) == 0:
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % "libaio.so or libaio.so.*")

    def check_config(self):
        """
        function: Check the XML file information on the remote execution node.
        input : NA
        output: NA
        """
        self.initNodeInfo()
        app_path = self.clusterInfo.appPath
        tmp_path = ClusterConfigFile.readClusterTmpMppdbPath(self.user, self.clusterConfig)
        tool_path = self.clusterToolPath
        for path in [app_path, tmp_path, tool_path]:
            UserUtil.check_path_owner(path)
        # check cm, cn, gtm, etcd, dn
        # check cm
        UserUtil.check_path_owner(g_nodeInfo.cmDataDir)
        for cma_inst in g_nodeInfo.cmagents:
            UserUtil.check_path_owner(cma_inst.datadir)
        for cms_inst in g_nodeInfo.cmservers:
            UserUtil.check_path_owner(cms_inst.datadir)
        # check gtm
        for gtm_inst in g_nodeInfo.gtms:
            UserUtil.check_path_owner(gtm_inst.datadir)
        # check cn
        for coo_inst in g_nodeInfo.coordinators:
            UserUtil.check_path_owner(coo_inst.datadir)
            if len(coo_inst.ssdDir) != 0:
                UserUtil.check_path_owner(coo_inst.ssdDir)
        # check dn
        for dn_inst in g_nodeInfo.datanodes:
            UserUtil.check_path_owner(dn_inst.datadir)
            if len(dn_inst.ssdDir) != 0:
                UserUtil.check_path_owner(dn_inst.ssdDir)
        # check dn xlog
        for dn_inst in g_nodeInfo.datanodes:
            if dn_inst.xlogdir != '':
                UserUtil.check_path_owner(dn_inst.xlogdir)
        # check etcd
        for etcd_inst in g_nodeInfo.etcds:
            UserUtil.check_path_owner(etcd_inst.datadir)

    def check_cpu_instructions(self):
        """
        function: Check if CPU instructions support rdtscp and avx
        input:NA
        output:NA
        """
        if "x86_64" not in platform.machine():
            return
        self.logger.debug("Checking cpu instructions.")
        cpu_mission = "Warning: This cluster is missing the rdtscp or avx instruction."
        try:
            cmd = "lscpu | grep rdtscp && lscpu | grep avx"
            # Checking cpu instructions
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0 or not output:
                raise Exception(cpu_mission)
            else:
                self.logger.debug("Successfully checked cpu instructions.")
        except Exception as e:
            self.logger.debug(cpu_mission)
            raise Exception(cpu_mission)
    
    def check_nofile_limit(self):
        """
        function: Check nofile limit
        input:NA
        output:NA
        """
        self.logger.debug("Checking nofile limit.")
        if os.getuid() == 0:
            cmd = "su - %s -c \'ulimit -n\'" % self.user
        else:
            cmd = "ulimit -n"
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error: \n%s" % output)
        ulimit_value = int(output.strip())
        if ulimit_value < DefaultValue.NOFILE_LIMIT:
            raise Exception("Deploy cm, the number of file handles for %s user must be greater than %s" % (self.user, DefaultValue.NOFILE_LIMIT))
        self.logger.debug("Successfully checked nofile limit.")

    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
        """
        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 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 = NetUtil.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)
        except Exception as e:
            self.logger.logExit(str(e))
        self.logger.debug("Successfully check virtual IP.")

    # IP do operation with netmask
    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 setVirtualIp(self):
        """
        function: creating Virtual Ip
        input : NA
        output: NA
        """
        # The node instance initialization information
        self.initNodeInfo()
        # Add temporary files, save the virtual IP The actual
        # configuration for the failure rollback
        if os.path.exists(self.tmpFile):
            FileUtil.removeFile(self.tmpFile)
        tmpFileFp = None
        # If this node is not configured virtual IP, exit
        if g_nodeInfo.virtualIp == []:
            return
        # Check whether have configured the virtual ip
        self.checkVirtualIp()
        # If the current node virtual iP are configured, Exit
        if 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
            FileUtil.checkLink(self.tmpFile)
            tmpFileFp = open(self.tmpFile, "w+")
            # Obtain network interface card of backIp,
            # get this virtual IP network adapter card through it.
            backIpNIC = NetUtil.getNICNum(g_nodeInfo.backIps[0])

            # Get this node netcard identifier already existing netcard
            cmd = "/sbin/ifconfig -a | grep '%s' | awk '{print $1}'" \
                  % 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))
            vipNo = 0
            if flagValues != []:
                flagValues.sort()
                vipNo = flagValues[-1] + 1
            # Determine whether the same IP network segment.
            subnetMasks = []
            for backIp in g_nodeInfo.backIps:
                # Get backIP subnet mask
                subnetMask = ""
                allNetworkInfo = NetUtil.getAllNetworkInfo(NetUtil.get_ip_version(backIp))
                for network in allNetworkInfo:
                    if 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"])
            # start setting virtual IP
            backIp = g_nodeInfo.backIps[0]
            # get network startup file
            # On SuSE12.X there is no /etc/init.d/network. so skip it
            distname, version = LinuxDistro.linux_distribution()[0:2]
            if not (distname == "SuSE" and version == "12"):
                network_startupFile = "/etc/init.d/network"
                if not os.path.exists(network_startupFile):
                    raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] %
                                    ("startup file of the node network [%s]"
                                     % network_startupFile))
                if not os.path.isfile(network_startupFile):
                    raise Exception(ErrorCode.GAUSS_502["GAUSS_50210"] %
                                    ("startup file of the node network [%s]"
                                     % network_startupFile))

            # Get OS startup file
            OS_initFile = DefaultValue.getOSInitFile()
            if OS_initFile == "":
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"]
                                % "startup file of current OS" +
                                " The startup file for SUSE OS is "
                                "/etc/init.d/boot.local.The startup file"
                                " for Redhat OS is /etc/rc.d/rc.local.")
            for configuredIp in configuredIps:
                # Check with backup virtual IP on the same network segment
                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 = "ifconfig -a | grep '%s:%d'" % (backIpNIC, vipNo)
                (status, output) = subprocess.getstatusoutput(cmd_LABEL)
                if status == 0 or self.IsLABELconfigured(backIpNIC, vipNo):
                    vipNo += 1
                cmd = "/sbin/ifconfig %s:%d %s netmask %s up" % (backIpNIC,
                                                                 vipNo,
                                                                 configuredIp,
                                                                 subnetMask)
                (status, output) = subprocess.getstatusoutput(cmd)
                if status != 0:
                    raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd
                                    + " Error: \n%s" % output)

                # Virtual IP configuration write OS startup file
                lineInfo = '^\\/sbin\\/ifconfig .* %s netmask .* up$' \
                           % configuredIp
                FileUtil.deleteLine(OS_initFile, lineInfo)
                if distname == "SuSE":
                    if version == "11":
                        # get configure virtual IP line number position
                        # of network startup file for suse OS
                        cmd = "grep -rn '[ ]*$FAKE ifup-route noiface -o" \
                              " rc $MODE' /etc/init.d/network"
                        (status, output) = subprocess.getstatusoutput(cmd)
                        outputlist = output.split("\n")
                        if status != 0 or len(outputlist) != 1:
                            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"]
                                            % cmd + " Error: \n%s" % output)
                        LineNumber = int(outputlist[0].split(":")[0])
                        lineInfo = '[ ]*\\/sbin\\/ifconfig .* %s netmask' \
                                   ' .* up$' % configuredIp
                        FileUtil.deleteLine(network_startupFile, lineInfo)
                        cmd = "sed -i \"%di\                        %s\" %s \
                            " % (LineNumber + 1, cmd, network_startupFile)
                        (status, output) = subprocess.getstatusoutput(cmd)
                        if status != 0:
                            raise Exception(ErrorCode.GAUSS_502["GAUSS_50223"]
                                            % OS_initFile + " Error: \n%s"
                                            % output)
                    # if the Ip has been configured, do nothing,
                    # else if the ip not configured but the LABEL
                    # has been configured LABEL number +1,else do as privous
                    if (self.IsIPconfigured(backIpNIC,
                                            configuredIp, vipNo) == 0):
                        cmd = ""
                    elif (self.IsIPconfigured(backIpNIC,
                                              configuredIp, vipNo) == 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 = \
                        NetUtil.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.FILE_MODE, nicFile, vip_nic,
                             configuredIp, subnetMask, nicFile)
                if cmd != "" and cmd is not None:
                    (status, output) = subprocess.getstatusoutput(cmd)
                    if status != 0:
                        raise Exception(ErrorCode.GAUSS_502["GAUSS_50223"]
                                        % OS_initFile + " Error: \n%s"
                                        % output)
                    print("%s" % configuredIp, file=tmpFileFp)
                vipNo += 1
            tmpFileFp.flush()
            tmpFileFp.close()
            FileUtil.changeMode(DefaultValue.KEY_FILE_MODE, self.tmpFile)
        except Exception as e:
            if tmpFileFp:
                tmpFileFp.close()
            if os.path.exists(self.tmpFile):
                os.remove(self.tmpFile)
            self.logger.logExit(str(e))
        self.logger.debug("Successfully set virtual IP.")

    def IsIPconfigured(self, backIpNIC, configuredIp, i):
        """
        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
        """
        networkfile = '/etc/sysconfig/network/ifcfg-' + backIpNIC
        LABEL = "LABEL_" + str(i) + "=" + str(i)
        # check if the file is a link
        FileUtil.checkLink(networkfile)
        with open(networkfile, "r") as fp:
            for line in fp:
                if line.split("=")[1].strip() == configuredIp:
                    return 0
                elif LABEL in line:
                    return 1
        return 2

    def IsLABELconfigured(self, backIpNIC, 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
        """
        networkfile = '/etc/sysconfig/network/ifcfg-' + backIpNIC
        cmd = "cat '%s' | grep LABEL_%d=%d" % (networkfile, i, i)
        status = subprocess.getstatusoutput(cmd)[0]
        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
        distname, version = LinuxDistro.linux_distribution()[0:2]
        ipcList = FileUtil.readFile(ipcPath)
        ipcFlag = False
        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
        for line in ipcList:
            if "RemoveIPC" in line:
                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 in ("redhat", "centos") 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 in ("redhat", "centos") 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 = FileUtil.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 = FileUtil.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 checkDiskSpace(self):
        """
        function: check the disk if it has enough space to decompress
        input : NA
        output: NA
        """
        self.logger.debug("Checking available space.")
        versionFile = VersionInfo.get_version_file()
        version, number, commitid = VersionInfo.get_version_info(versionFile)
        actualPath = self.clusterAppPath + "_" + commitid
        if not os.path.exists(actualPath):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % actualPath)
        cmd = "df -h %s | awk '{print $4}' | xargs" % actualPath
        self.logger.debug("Command to check available disk space is:\n%s"
                          % cmd)
        # output is this format: "Avail 104G"
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd
                                + "Error: output is '%s'." % output)
        self.logger.debug(
            "The result of checking available disk space is:\n%s" % output)
        size = output.split(" ")[1][:-1]
        if not size.isdigit():
            self.logger.logExit(ErrorCode.GAUSS_516["GAUSS_51633"]
                                % "available disk space")
        if int(size) < DefaultValue.GREY_DISK_SIZE:
            raise Exception(ErrorCode.GAUSS_504["GAUSS_50411"]
                            % (DefaultValue.GREY_DISK_SIZE + 'G'))
        self.logger.debug("Successfully check host available space.")

    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 getWhiteList(self, confFile):
        """
        function: get whiteList
        input  : NA
        output : NA
        """
        print(confFile)
        fp = configparser.RawConfigParser()
        fp.read(confFile)

        optionList = fp.options("WHITELIST")
        white_dict = {}
        for key in optionList:
            value = fp.get("WHITELIST", key)
            ip_list = value.strip("\"").split(',')
            white_dict[key] = ip_list
        self.white_list = white_dict

    def setDefaultIptables(self):
        """
        function: set default ip tables
        input  : NA
        output : NA
        """
        cmd = "iptables -A INPUT -s 0.0.0.0/0 -d 0.0.0.0/0 -p tcp" \
              " --dport 49537 -j ACCEPT && "
        cmd += "iptables -A INPUT -s 0.0.0.0/0 -d 0.0.0.0/0 -p udp" \
               " --dport 60129 -j ACCEPT && "
        cmd += "iptables -A INPUT -s 0.0.0.0/0 -d 0.0.0.0/0 -p tcp" \
               " --dport 49537 -j ACCEPT"
        status, output = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd
                            + " Error: \n%s" % output)
        self.logger.debug("Set default iptables successfully.")

    def checkWhiteList(self):
        """
        function: check whiteList
        input  : NA
        output : NA
        """
        if len(self.white_list) != 2:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50205"]
                            % "White list, please check confFile.")
        if ("inner" not in self.white_list.keys() or
                "outter" not in self.white_list.keys()):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50205"]
                            % "White list file with key error.")
        if '' in self.white_list['inner']:
            self.white_list['inner'].remove("")
        if '' in self.white_list['outter']:
            self.white_list['outter'].remove("")
        if (len(self.white_list['inner']) > 0 or
            len(self.white_list['outter'])) > 0:
            self.logger.debug("Inner white list is %s"
                              % self.white_list['inner'])
            self.logger.debug("Outter white list is %s"
                              % self.white_list['outter'])
            for ip in self.white_list['inner']:
                NetUtil.isIpValid(ip)
            for ip in self.white_list['outter']:
                NetUtil.isIpValid(ip)
            compare_list = [ip for ip in self.white_list['inner']
                            if ip in self.white_list['outter']]
            if len(compare_list) > 0:
                raise Exception(ErrorCode.GAUSS_527["GAUSS_52708"] +
                                "Inner IP and Outter IP have the same node.%s"
                                % compare_list)
            return True
        elif len(self.white_list['inner']) == 0 and \
                len(self.white_list['outter']) == 0:
            self.clearIptables()
            self.setDefaultIptables()
            return False
        else:
            return False

    def clearIptablesItem(self, clear_length, chain_type):
        """
        function: clear Iptables item
        input  : NA
        output : NA
        """
        exe_cmd = ""
        cmd = "iptables -D %s 1" % chain_type
        if clear_length.isdigit():
            for i in range(int(clear_length)):
                if (i + 1) == int(clear_length):
                    exe_cmd += cmd
                else:
                    exe_cmd += cmd + " && "
            self.logger.debug("Execute command: %s" % exe_cmd)
            status, output = subprocess.getstatusoutput(exe_cmd)
            if status != 0:
                raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % exe_cmd
                                + " Error: \n%s" % output)
        self.logger.debug("Clear %s in iptables success." % chain_type)

    def clearIptablesChain(self, tables_str, chain_type):
        """
        function: clear ip tables chain
        input  : NA
        output : NA
        """
        output_result = tables_str.split("Chain %s (policy ACCEPT)"
                                         % chain_type)[1]
        if output_result.find("Chain") >= 0:
            output_result = output_result.split("Chain")[0]
        self.logger.debug("RESULT IS %s" % output_result)
        if len(output_result.strip().split('\n')) == 1:
            self.logger.debug("no need to clear iptables.")
            return
        self.logger.debug(output_result.strip().split('\n')[-1])
        output_length = output_result.strip().split('\n')[-1].split()[0]
        self.clearIptablesItem(output_length, chain_type)

    def clearWhiteListChain(self, tables_str):
        """
        function: clear white list chain
        input  : NA
        output : NA
        """
        if "Chain whitelist" in tables_str:
            old_white_str = tables_str.split("Chain whitelist")[1]
            if "Chain " in old_white_str:
                old_white_str = old_white_str.split("Chain ")[0]
            white_length = old_white_str.split('\n')[-1].strip().split()[0]
            self.clearIptablesItem(white_length, "whitelist")
            cmd = "iptables -X whitelist"
            status, output = subprocess.getstatusoutput(cmd)
            if status != 0:
                raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd
                                + " Error: \n%s" % output)
        else:
            self.logger.debug("There is no white list chain.")

    def clearIptables(self):
        """
        function: clear ip tables
        input  : NA
        output : NA
        """
        self.logger.debug("Start clear IP tables chain list.")
        cmd = "iptables -nL --line-number"
        status, output = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd
                            + " Error: \n%s" % output)
        # clear INPUT
        self.clearIptablesChain(output, "INPUT")
        # clear FORWARD
        self.clearIptablesChain(output, "FORWARD")
        # clear OUTPUT
        self.clearIptablesChain(output, "OUTPUT")
        # clear whitelist
        self.clearWhiteListChain(output)

        self.logger.debug("Clear IP tables successfully.")

    def setWhiteList(self):
        """
        function: set white list
        input  : NA
        output : NA
        """
        white_list = []
        white_list.extend(self.white_list['inner'])
        white_list.extend(self.white_list['outter'])
        cmd = "iptables -N whitelist && "
        for ip in white_list:
            cmd += "iptables -A whitelist -s %s -j ACCEPT && " % ip

        cmd += "iptables -A INPUT -m state --state RELATED," \
               "ESTABLISHED -j ACCEPT && "
        cmd += "iptables -A INPUT -p all -j whitelist && "
        cmd += "iptables -A INPUT -i lo -j ACCEPT && "
        cmd += "iptables -A INPUT -j REJECT --reject-with " \
               "icmp-host-prohibited"

        status, output = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd
                            + " Error: \n%s" % output)
        self.logger.debug("Set white list success.")

    def checkOSSoftware(self):
        """
        function: Check whether software meets the installation requirements
        input : NA
        output: NA
        """
        self.logger.debug("Checking os software.")
        no_install_soft_list = []
        for softname in software_list:
            if softname.startswith("bzip2"):
                cmd = "which bzip2"
            else:
                cmd = "rpm -qa|grep -c " + softname
            self.logger.debug("Command to check %s by %s" \
                              % (softname, cmd))
            # output is num of softname
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.debug(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd
                                  + "Error: output is '%s'." % output)
                no_install_soft_list.append(softname)
        if len(no_install_soft_list) > 0:
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51405"] % \
                            str(no_install_soft_list))
        self.logger.debug("Successfully check OS software.")

    def backup_om_scripts(self):
        """
        fix packgae path permission and owner
        :return:
        """
        package_path = get_package_path()
        om_backup_path = os.path.dirname(package_path)
        check_backup_path = os.path.join("/home", self.user, "gauss_om")
        if om_backup_path == check_backup_path or not self.current_user_root:
            return

        self.logger.log("Backup om scripts.")
        self.logger.debug("Create backup_om path.")
        # /home/user/gauss_om/script
        dest_path = os.path.join("/home", self.user, "gauss_om")
        if os.path.exists(dest_path):
            shutil.rmtree(dest_path)
        os.makedirs(dest_path)
        # Change owner to appropriate user
        FileUtil.changeOwner(self.user, dest_path)

        # cp hosts file to /home/user/gauss_om/
        self.logger.debug("cp hosts file to /home/user/gauss_om.")
        cmd = "cp -rf %s/hosts %s" % (self.clusterToolPath, dest_path)
        CmdExecutor.execCommandLocally(cmd)

        # cp cgroup to /home/user/gauss_om/script
        self.logger.debug("cp cgroup to /home/user/gauss_om/script.")
        backup_lib_dir = os.path.join(dest_path, "lib")
        backup_bin_dir = os.path.join(dest_path, "bin")
        FileUtil.createDirectory(backup_lib_dir, mode=DefaultValue.KEY_DIRECTORY_MODE)
        FileUtil.createDirectory(backup_bin_dir, mode=DefaultValue.KEY_DIRECTORY_MODE)
        libcgroup_dir = os.path.realpath("%s/libcgroup/lib/libcgroup.so*" % package_path)
        cgroup_exe_dir = os.path.realpath("%s/libcgroup/bin/gs_cgroup" % package_path)
        cp_cmd = "cp -rf %s %s; cp -rf %s %s" % (libcgroup_dir, backup_lib_dir, cgroup_exe_dir, backup_bin_dir)
        CmdExecutor.execCommandLocally(cp_cmd)

        # cp $GPHOME script lib to /home/user/gauss_om/
        cmd = ("cp -rf %s/script %s/lib %s/version.cfg %s"
               % (self.clusterToolPath, self.clusterToolPath,
                  self.clusterToolPath, dest_path))
        CmdExecutor.execCommandLocally(cmd)

        backup_scripts = ["gs_postuninstall", "gs_preinstall",
                        "gs_checkos"]
        common_scripts = ["gs_sshexkey", "killall", "gs_checkperf"]
        # the script files are not stored in the env path
        backup_save_files = backup_scripts + common_scripts
        self.logger.debug("Delete user scripts in om backup_om path.")
        # delete user scripts in om backup_om path
        om_backup_path = os.path.join(dest_path, "script")
        backup_om_files = os.listdir(om_backup_path)
        for backup_file in backup_om_files:
            if backup_file.startswith("gs_"):
                if backup_file not in backup_save_files:
                    FileUtil.removeFile("%s/%s" % (om_backup_path, backup_file))
        FileUtil.changeMode(DefaultValue.KEY_DIRECTORY_MODE,
                            dest_path, recursive=True)
        self.logger.debug("Set user scripts in om user path.")

        # set om user script path
        userProfile = self.getUserProfile()
        if userProfile is ClusterConstants.ETC_PROFILE:
            FileUtil.writeFile(userProfile, ["export PATH=$PATH:%s" % dest_path])
        else:
            FileUtil.writeFile(userProfile, ["export PATH=%s/script:$PATH" % dest_path])

        # delete backup_om scripts in GPHOME
        om_user_path = os.path.join(self.clusterToolPath, "script")
        user_om_files = os.listdir(om_user_path)
        for user_file in user_om_files:
            if user_file.startswith("gs_"):
                if user_file in backup_scripts:
                    FileUtil.removeFile("%s/%s" % (om_user_path, user_file))
        FileUtil.changeOwner(self.user, dest_path, recursive=True)
        self.logger.debug("Delete cluster decompress package in user path.")

    def fixop_xml_and_mpp_file(self):
        """
        fix config file owner
        :return:
        """
        self.logger.log("change '%s' files permission and owner."
                        % self.clusterConfig)
        FileUtil.changeOwner(self.user, self.clusterConfig, link=True)
        FileUtil.changeMode(DefaultValue.KEY_FILE_MODE, self.clusterConfig)
        if self.mpprcFile:
            self.logger.log("change '%s' files permission and owner."
                            % self.mpprcFile)
            FileUtil.checkLink(self.mpprcFile)
            FileUtil.changeMode(DefaultValue.KEY_FILE_MODE, self.mpprcFile)
            FileUtil.changeOwner(self.user, self.mpprcFile, link=True)

    def fixop_tool_path(self):
        """
        fix cluster path owner
        :return:
        """
        toolPath = self.clusterToolPath
        self.logger.log("change '%s' files permission and owner." % toolPath)
        FileUtil.changeOwner(self.user, toolPath, recursive=True, link=True)
        FileUtil.changeMode(DefaultValue.KEY_DIRECTORY_MODE,
                          toolPath, recursive=True)
        FileUtil.changeMode(DefaultValue.SPE_FILE_MODE,
                          "%s/script/gs_*" % toolPath)
        FileUtil.changeMode(DefaultValue.BIN_FILE_MODE, "%s/*.sha256" % toolPath)
        FileUtil.changeMode(DefaultValue.BIN_FILE_MODE, "%s/*.tar.gz" % toolPath)
        FileUtil.changeMode(DefaultValue.BIN_FILE_MODE, "%s/*.tar.bz2" %
                          toolPath)
        FileUtil.changeMode(DefaultValue.BIN_FILE_MODE, "%s/version.cfg" %
                          toolPath)

    def fixop_package_path(self):
        """
        fix software path permission
        root permission
        :return:
        """
        package_path = get_package_path()
        gsom_path = os.path.dirname(package_path)
        if gsom_path != DefaultValue.ROOT_SCRIPTS_PATH:
            self.logger.log("Change file mode in path %s" % package_path)
            FileUtil.changeOwner(self.user, package_path, recursive=True, link=True)
            FileUtil.changeMode(DefaultValue.MAX_DIRECTORY_MODE, package_path)
            FileUtil.changeMode(DefaultValue.KEY_DIRECTORY_MODE,
                              "%s/script" % package_path, recursive=True)
            FileUtil.changeMode(DefaultValue.BIN_FILE_MODE, "%s/*.sha256" %
                              package_path)
            FileUtil.changeMode(DefaultValue.BIN_FILE_MODE, "%s/*.tar.gz" %
                              package_path)
            FileUtil.changeMode(DefaultValue.BIN_FILE_MODE, "%s/*.tar.bz2" %
                              package_path)
            FileUtil.changeMode(DefaultValue.BIN_FILE_MODE, "%s/version.cfg" %
                              package_path)

    def fix_dss_cap_permission(self):
        '''
        Modifying the dss binary cap permissions.
        '''
        self.logger.debug("Modifying dss cap permissions.")
        clib_app = os.path.realpath(
            os.path.join(self.clusterToolPath, "script/gspylib/clib",
                         f"dss_app_{VersionInfo.getCommitid()}"))

        dss_files = ['dsscmd', 'perctrl', 'dss_clear.sh']
        for file_ in dss_files:
            FileUtil.changeMode(DefaultValue.BIN_FILE_MODE,
                                os.path.join(clib_app, file_))

        FileUtil.change_caps(DefaultValue.CAP_WIO,
                             os.path.join(clib_app, 'cm_persist'))
        FileUtil.change_caps('{},{}'.format(DefaultValue.CAP_ADM, DefaultValue.CAP_WIO),
                             os.path.join(clib_app, 'perctrl'))
        self.logger.debug("Successfully modified dss cap permissions.")

    def fix_dss_dir_permission(self):
        '''
        Modify the permissions on some DSS-related directories and
        escalate the permissions in binary mode.
        '''
        self.logger.debug("Modifying dss home permissions.")
        dss_home = self.clusterInfo.dss_home
        cfg_dir = os.path.realpath(os.path.join(dss_home, 'cfg'))
        log_path = os.path.realpath(os.path.join(dss_home, 'log'))
        FileUtil.changeOwner(self.user, dss_home, link=True, recursive=True)

        dirs = [cfg_dir, log_path]
        for dir_ in dirs:
            FileUtil.changeMode(DefaultValue.KEY_DIRECTORY_MODE, dir_)

        files = ["{}/*ini".format(cfg_dir)]
        for file_ in files:
            FileUtil.changeMode(DefaultValue.KEY_FILE_MODE, file_)
        self.logger.debug("Successfully modified dss home permissions.")

    def fix_dss_disk_permission(self):
        '''
        Modifying DSS Disk Permissions
        '''

        vg_path = self.clusterInfo.dss_vg_info
        for file_ in list(filter(None, re.split(r',|:', vg_path)))[1::2]:
            self.logger.debug("Modifying dss disk permissions: %s" % file_)
            FileUtil.changeOwner(self.user, path=file_)
            FileUtil.changeMode(DefaultValue.DSS_DISK_MODE, path=file_)

    def fix_cm_disk_permission(self):
        cm_vote_disk = self.clusterInfo.cm_vote_disk
        self.logger.debug("Modifying cm disk permissions: %s" % cm_vote_disk)
        FileUtil.changeOwner(self.user, path=cm_vote_disk)
        FileUtil.changeMode(DefaultValue.DSS_DISK_MODE, path=cm_vote_disk)

        self.logger.log("Modifying cm disk permissions: %s" % cm_vote_disk)
        cm_share_disk = self.clusterInfo.cm_share_disk
        FileUtil.changeOwner(self.user, path=cm_share_disk)
        FileUtil.changeMode(DefaultValue.DSS_DISK_MODE, path=cm_share_disk)

    def fix_owner_and_permission(self):
        """
        function: fix owner and permission
        input: NA
        output: NA
        """
        self.fixop_package_path()
        self.fixop_tool_path()
        self.fixop_xml_and_mpp_file()
        if self.clusterInfo.enable_dss == 'on':
            idx = DssConfig.get_current_dss_id_by_dn(self.clusterInfo.dbNodes,
                                                     self.dbNodeInfo)
            if idx == -1:
                self.logger.debug('In dss-mode, the dn does not' \
                     ' exist on the current node.')
                return
            self.fix_dss_cap_permission()
            if EnvUtil.is_fuzzy_upgrade(self.user, self.logger, self.mpprcFile):
                return
            self.fix_dss_dir_permission()
            self.fix_dss_disk_permission()
            self.fix_cm_disk_permission()

    def fix_server_pkg_permission(self):
        """
        fix server package permission
        :return:
        """
        self.fix_owner_and_permission()
        self.backup_om_scripts()

    def dss_init(self):
        '''
        unreg the disk of the dss and about
        '''

        idx = DssConfig.get_current_dss_id_by_dn(self.clusterInfo.dbNodes,
                                                 self.dbNodeInfo)
        if idx == -1:
            self.logger.debug('In dss-mode, the dn does not' \
                    ' exist on the current node.')
            return

        if EnvUtil.is_fuzzy_upgrade(self.user, self.logger, self.mpprcFile):
            self.logger.debug('In upgrade, the disk lock will not to be unregistered.')
            return

        clib_app = os.path.realpath(
            os.path.join(self.clusterToolPath, 'script', 'gspylib', 'clib',
                         f'dss_app_{VersionInfo.getCommitid()}'))
        Dss.unreg_disk(self.clusterInfo.dss_home,
                       user=self.user,
                       clib_app=clib_app,
                       logger=self.logger)

    def clean_dss_env(self, mpprc_file):
        '''
        Clearing DSS Environment Variables
        '''

        for env in [
            'VGNAME', 'CM_VOTE_DISK', 'CM_SHARE_DISK', 'DSS_HOME',
            'RDMA_TYPE', 'RDMA_CONFIG', 'DSS_SSL'
        ]:
            FileUtil.deleteLine(mpprc_file, "^\\s*export\\s*{}=.*$".format(env))
            self.logger.debug(
                "Deleting crash {} in user environment variables.".format(env))

    def add_dss_env(self, mpprc_file):
        '''
        Setting DSS Environment Variables
        '''
        if self.clusterInfo.ss_interconnect_type == 'RDMA':
            FileUtil.writeFile(mpprc_file, [
                "export RDMA_TYPE={}".format(
                    self.clusterInfo.ss_interconnect_type)
            ])
            if self.clusterInfo.ss_rdma_work_config:
                FileUtil.writeFile(mpprc_file, [
                    "export RDMA_CONFIG={}".format(
                        self.clusterInfo.ss_rdma_work_config.replace(
                            ' ', '/'))
                ])
        if self.clusterInfo.dss_ssl_enable == 'on':
            FileUtil.writeFile(mpprc_file, ["export DSS_SSL=on"])
        FileUtil.writeFile(
            mpprc_file,
            ["export VGNAME={}".format(self.clusterInfo.dss_vgname)])
        FileUtil.writeFile(
            mpprc_file,
            ["export DSS_HOME={}".format(self.clusterInfo.dss_home)])

    def changeToolEnv(self):
        """
        function: change software tool env path
        :return:
        """
        userpath = pwd.getpwnam(self.user).pw_dir
        userProfile = os.path.join(userpath, ".bashrc")

        if self.clusterInfo.enable_dss == 'on' and self.mpprcFile and os.path.isfile(
                self.mpprcFile):
            userProfile = self.mpprcFile
            self.clean_dss_env(userProfile)
            self.add_dss_env(userProfile)
            return

        if not os.path.exists(userProfile):
            self.logger.logExit(ErrorCode.GAUSS_502[
                                    "GAUSS_50201"] % 'user profile'
                                + " Please create %s." % userProfile)
        self.clean_tool_env(userProfile)
        self.clean_dss_env(userProfile)
        # set GPHOME
        FileUtil.writeFile(userProfile,
                         ["export GPHOME=%s" % self.clusterToolPath])
        # set PATH
        FileUtil.writeFile(userProfile, [
            "export PATH=$GPHOME/script/gspylib/pssh/bin:"
            "$GPHOME/script:$PATH"])
        # set LD_LIBRARY_PATH
        FileUtil.writeFile(userProfile, [
            "export LD_LIBRARY_PATH="
            "$GPHOME/script/gspylib/clib:$LD_LIBRARY_PATH"])
        FileUtil.writeFile(userProfile, [
            "export LD_LIBRARY_PATH=$GPHOME/lib:$LD_LIBRARY_PATH"])
        # set PYTHONPATH
        FileUtil.writeFile(userProfile, ["export PYTHONPATH=$GPHOME/lib"])

        if self.clusterInfo.enable_dss == 'on':
            self.add_dss_env(userProfile)

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

        # clean LD_LIBRARY_PATH
        FileUtil.deleteLine(userProfile,
                          "^\\s*export\\s*LD_LIBRARY_PATH=\\$GPHOME\\/script"
                          "\\/gspylib\\/clib:\\$LD_LIBRARY_PATH$")
        FileUtil.deleteLine(userProfile,
                          "^\\s*export\\s*LD_LIBRARY_PATH=\\$GPHOME\\/lib:"
                          "\\$LD_LIBRARY_PATH$")
        self.logger.debug(
            "Deleting crash LD_LIBRARY_PATH in user environment variables.")

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

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


    def run(self):
        """
        function: run method
        input  : NA
        output : NA
        """
        try:
            self.get_current_user()
            self.parseCommandLine()
            self.checkParameter()
            self.initGlobals()
        except Exception as e:
            GaussLog.exitWithError(str(e))

        try:
            if self.action == ACTION_PREPARE_PATH:
                self.prepareGivenPath(self.preparePath, self.checkEmpty)
            elif self.action == ACTION_CHECK_OS_VERSION:
                self.checkOSVersion()
            elif self.action == ACTION_CREATE_OS_USER:
                self.createOSUser()
            elif self.action == ACTION_CHECK_OS_USER:
                global checkOSUser
                checkOSUser = True
                self.createOSUser()
            elif self.action == ACTION_CHECK_HOSTNAME_MAPPING:
                self.checkMappingForHostName()
            elif self.action == ACTION_CREATE_CLUSTER_PATHS:
                self.createClusterPaths()
            elif self.action == ACTION_SET_FINISH_FLAG:
                self.checkAbrt()
                self.checkRemoveIpc()
                self.setFinishFlag()
            elif self.action == ACTION_SET_TOOL_ENV:
                self.setToolEnv()
            elif self.action == ACTION_SET_USER_ENV:
                self.setDBUerProfile()
            elif self.action == ACTION_PREPARE_USER_CRON_SERVICE:
                self.prepareUserCronService()
            elif self.action == ACTION_PREPARE_USER_SSHD_SERVICE:
                self.prepareUserSshdService()
            elif self.action == ACTION_SET_LIBRARY:
                self.setLibrary()
            elif self.action == ACTION_SET_VIRTUALIP:
                FileUtil.modifyFileOwnerFromGPHOME(self.logger.logFile)
                self.setVirtualIp()
            elif self.action == ACTION_INIT_GAUSSLOG:
                self.initGaussLog()
            elif self.action == ACTION_CHECK_DISK_SPACE:
                self.checkDiskSpace()
            elif self.action == ACTION_SET_ARM_OPTIMIZATION:
                self.checkPlatformArm()
                if ARM_PLATE:
                    self.setArmOptimization()
                else:
                    self.logger.debug("The plate is not arm,"
                                      " skip set arm options.")
            elif self.action == ACTION_CHECK_ENVFILE:
                (checkstatus, checkoutput) = \
                    ProfileFile.check_env_file(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)
            elif self.action == ACTION_SET_WHITELIST:
                self.logger.debug("Start setting white list.")
                confFile = os.path.join(
                    os.path.dirname(os.path.realpath(__file__)),
                    "../../agent/om_agent.conf")
                if os.path.isfile(confFile):
                    self.getWhiteList(confFile)
                    if self.checkWhiteList():
                        self.clearIptables()
                        self.setWhiteList()
                else:
                    self.logger.debug("White list file not exist,"
                                      " skip set white list.")
            elif self.action == ACTION_CHECK_OS_SOFTWARE:
                self.checkOSSoftware()
            elif self.action == ACTION_FIX_SERVER_PACKAGE_OWNER:
                self.fix_server_pkg_permission()
            elif self.action == ACTION_DSS_NIT:
                self.dss_init()
            elif self.action == ACTION_CHANGE_TOOL_ENV:
                self.changeToolEnv()
            elif self.action == ACTION_SET_CGROUP:
                self.checkaio()
                self.setCgroup()
            elif self.action == ACTION_CHECK_CONFIG:
                self.check_config()
            elif self.action == ACTION_CHECK_CPU_INSTRUCTIONS:
                self.check_cpu_instructions()
            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 e:
        GaussLog.exitWithError(str(e))
