예제 #1
0
class CleanOsUser(LocalBaseOM):
    '''
    This class is for cleaning os user, it will not cleaning group.
    '''
    def __init__(self):
        '''
        Constructor
        '''
        self.userProfile = ""
        self.user = ""
        self.logger = None

    ##########################################################################
    # Help context.
    ##########################################################################
    def usage(self):
        """
        function: usage
        input  : NA
        output : NA
        """
        print("CleanOsUser.py is a utility to clean OS user.")
        print(" ")
        print("Usage:")
        print("  python3 CleanOsUser.py --help")
        print("  python3 CleanOsUser.py -U user")
        print(" ")
        print("Common options:")
        print("  -U        the database program and cluster owner")
        print("  --help    show this help, then exit")
        print(" ")

    def __checkParameters(self):
        """
        function: Check parameter from command line
        input : NA
        output: NA
        """
        try:
            opts, args = getopt.getopt(sys.argv[1:], "U:l:", ["help"])
        except getopt.GetoptError as e:
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"] % str(e))

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

        logFile = ""
        for key, value in opts:
            if (key == "-U"):
                self.user = value
            elif (key == "-l"):
                logFile = value
            elif (key == "--help"):
                self.usage()
                sys.exit(0)
            else:
                GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"] %
                                       key)

            Parameter.checkParaVaild(key, value)

        if (self.user == ""):
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'U' +
                                   ".")
        try:
            DefaultValue.checkUser(self.user, False)
        except Exception as e:
            GaussLog.exitWithError(str(e))

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

        self.logger = GaussLog(logFile, "CleanOsUser")
        self.logger.ignoreErr = True

    ##########################################################################
    # This is the main clean OS user flow.
    ##########################################################################
    def cleanOsUser(self):
        """
        function: Clean OS user
        input : NA
        output: NA
        """
        self.__checkParameters()
        self.logger.log("Cleaning crash OS user.")
        try:
            # clean semaphore
            subprocess.getstatusoutput("ipcs -s|awk '/ %s /{print $2}'|"
                                       "xargs -n1 ipcrm -s" % self.user)

            # get install path
            cmd = "su - %s -c 'echo $GAUSSHOME' 2>/dev/null" % self.user
            (status, output) = subprocess.getstatusoutput(cmd)
            if (status != 0):
                self.logger.logExit(ErrorCode.GAUSS_518["GAUSS_51802"] %
                                    "$GAUSSHOME" + " Error:\n%s" % output)
            gaussHome = output.strip()
            if (gaussHome == ""):
                self.logger.debug("$GAUSSHOME is null. This means you may "
                                  "must clean crash install path manually.")
            self.logger.debug("The installation path is %s." % gaussHome)

            # delete user
            status, output = subprocess.getstatusoutput("userdel -f %s" %
                                                        self.user)
            if (status != 0):
                self.logger.logExit(ErrorCode.GAUSS_503["GAUSS_50314"] %
                                    self.user + " Error: \n%s" % output)

            # delete path
            status, output = subprocess.getstatusoutput("rm -rf '%s'" %
                                                        gaussHome)
            if (status != 0):
                self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50209"] %
                                    gaussHome + " Error: \n%s" % output)

        except Exception as e:
            self.logger.logExit(str(e))
        self.logger.log("Successfully cleaned OS user.")

    def removeAllowUsers(self):
        """
        function: Remove the specific user from 'AllowUsers'
         in /etc/ssh/sshd_config
        input : NA
        output: NA
        """
        sshd_config = "/etc/ssh/sshd_config"
        try:
            cmd = "cat %s | grep -E '\\<AllowUsers\\>'" % sshd_config
            (status, output) = subprocess.getstatusoutput(cmd)
            # Not found, or there is an error.
            if status != 0:
                if output is None or len(output.lstrip()) == 0:
                    self.logger.debug("No 'AllowUsers' configuration found"
                                      " in %s" % sshd_config)
                else:
                    # Error occurred, but there is no need to report.
                    self.logger.debug("Failed to get 'AllowUsers' from %s" %
                                      sshd_config)
                return

            allowUsersLineBefore = output.lstrip()
            userList = allowUsersLineBefore.split()
            userList.remove(self.user)
            allowUsersLineRemoved = ' '.join(userList)
            cmd = "sed -i 's/%s/%s/g' %s" % (
                allowUsersLineBefore, allowUsersLineRemoved, sshd_config)
            (status, output) = subprocess.getstatusoutput(cmd)
            # Not found, or there is an error.
            if status != 0:
                self.logger.debug(
                    "Failed to remove user '%s' from "
                    "'AllowUsers' in %s. Command: %s, Error: %s" %
                    (self.user, sshd_config, cmd, output))
        except Exception as e:
            self.logger.debug("Failed to remove user '%s' from 'AllowUsers'"
                              " in %s. Error: %s" %
                              (self.user, sshd_config, str(e)))
예제 #2
0
class CheckUninstall:
    '''
    classdocs
    '''
    def __init__(self):
        '''
        Constructor
        '''
        self.installPath = ""
        self.user = ""
        self.cleanUser = False
        self.cleanData = False
        self.logger = None

    ##########################################################################
    # Help context. U:R:oC:v:
    ##########################################################################
    def usage(self):
        """
        function: usage
        input  : NA
        output : NA
        """
        print("CheckUninstall.py is a utility to check Gauss MPP Database"
              " status .")
        print(" ")
        print("Usage:")
        print("  python3 CheckUninstall.py --help")
        print("  python3 CheckUninstall.py -R installpath -U user [-d] [-u]"
              " [-l log]")
        print(" ")
        print("Common options:")
        print("  -U        the database program and cluster owner")
        print("  -R        the database program path")
        print("  -d        clean data path")
        print("  -u        clean user")
        print("  -l        log directory")
        print("  --help    show this help, then exit")
        print(" ")

    ##########################################################################
    # check uninstall
    ##########################################################################
    def checkUninstall(self):
        """
        function:
            Check all kinds of environment. It includes:
            1. Input parameters.
            2. OS version.
            3. User Info
            4. If it has a old install.
        input : NA
        output: NA
        """
        self.__checkParameters()
        self.__checkOSVersion()
        self.__checkOsUser()
        self.__checkInstanllPath()
        self.logger.closeLog()

    def __checkParameters(self):
        """
        function: check input parameters
        input : NA
        output: NA
        """
        try:
            opts, args = getopt.getopt(sys.argv[1:], "U:R:l:du", ["help"])
        except getopt.GetoptError as e:
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"] % str(e))

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

        logFile = ""
        for key, value in opts:
            if (key == "-U"):
                self.user = value
            elif (key == "-R"):
                self.installPath = value
            elif (key == "-l"):
                logFile = value
            elif (key == "-d"):
                self.cleanData = True
            elif (key == "-u"):
                self.cleanUser = True
            elif (key == "--help"):
                self.usage()
                sys.exit(0)
            else:
                GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"] %
                                       key)

            Parameter.checkParaVaild(key, value)

        if (self.user == ""):
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'U' +
                                   ".")

        if (self.installPath == ""):
            raise Exception(ErrorCode.GAUSS_500["GAUSS_50001"] % 'R' + ".")

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

        self.logger = GaussLog(logFile, "CheckUninstall")
        self.logger.debug("The installation path of program: " +
                          self.installPath)
        self.logger.debug("The parameter of clean user is: %s." %
                          self.cleanUser)
        self.logger.debug("The parameter of clean data is: %s." %
                          self.cleanData)

    def __checkOSVersion(self):
        """
        function: Check operator system version, install binary file version.
        input : NA
        output: NA
        """
        self.logger.log("Checking OS version.")
        try:
            if (not DefaultValue.checkOsVersion()):
                raise Exception(ErrorCode.GAUSS_519["GAUSS_51900"] +
                                "The current system is: %s." %
                                platform.platform())
        except Exception as e:
            raise Exception(str(e))

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

    def __checkOsUser(self):
        """
        function: Check if user exists and get $GAUSSHOME
        input : NA
        output: NA
        """
        if not self.cleanUser:
            self.logger.log("Skipping user check. ")
            return

        self.logger.log("Checking OS user.")
        try:
            DefaultValue.checkUser(self.user, False)
        except Exception as e:
            raise Exception(str(e))

        # Get GAUSSHOME
        cmd = "echo $GAUSSHOME 2>/dev/null"
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            self.logger.debug("The cmd is %s " % cmd)
            raise Exception(ErrorCode.GAUSS_518["GAUSS_51802"] % "$GAUSSHOME" +
                            " Error:\n%s" % output)

        gaussHome = output.strip()
        if (gaussHome == ""):
            raise Exception(ErrorCode.GAUSS_518["GAUSS_51800"] % "$GAUSSHOME")

        if (gaussHome != self.installPath):
            self.logger.debug("$GAUSSHOME: %s." % gaussHome)
            self.logger.debug("Installation path parameter: %s." %
                              self.installPath)
            raise Exception(ErrorCode.GAUSS_518["GAUSS_51807"])
        self.logger.log("Successfully checked OS user.")

    def __checkInstanllPath(self):
        """
        function: Check if path exists and get owner
        input : NA
        output: NA
        """
        self.logger.log("Checking installation path.")
        if (not os.path.exists(self.installPath)):
            self.logger.log("Installation path does not exist: %s." %
                            self.installPath)
            if (not self.cleanData and not self.cleanUser):
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50219"] %
                                "installation path")
        else:
            # Get owner
            cmd = "stat -c '%%U:%%G' %s" % self.installPath
            (status, output) = subprocess.getstatusoutput(cmd)
            if (status != 0):
                self.logger.debug("The cmd is %s " % cmd)
                raise Exception(ErrorCode.GAUSS_503["GAUSS_50308"] +
                                " Error: \n%s" % str(output))

            owerInfo = output.strip()
            (user, group) = owerInfo.split(':')
            if (self.user != user.strip()):
                self.logger.debug("The owner information of installation"
                                  " path: %s." % owerInfo)
                self.logger.debug("User parameter : %s." % self.user)
                raise Exception(ErrorCode.GAUSS_503["GAUSS_50315"] %
                                (self.user, self.installPath))
        self.logger.log("Successfully checked installation path.")
예제 #3
0
class Uninstall(LocalBaseOM):
    """
    uninstall the cluster
    """

    def __init__(self):
        """
        Constructor
        """
        super(Uninstall, self).__init__()
        self.installPath = ""
        self.user = ""
        self.keepDir = False
        self.mpprcFile = ""
        self.logFile = ""
        self.logger = None
        self.installflag = False
        self.clusterInfo = None
        self.localNode = None
        self.keepData = True
        self.method = ""
        self.action = ""

    ##########################################################################
    # Help context. U:R:oC:v: 
    ##########################################################################
    def usage(self):
        """
        function: usage
        """
        print("Uninstall.py is a utility to uninstall Gauss MPP Database.")
        print(" ")
        print("Usage:")
        print("  python3 Uninstall.py --help")
        print("  python3 Uninstall.py -U user -R installpath [-c] [-l log]")
        print(" ")
        print("Common options:")
        print("  -U         the database program and cluster owner")
        print("  -R         the database program install path")
        print("  -l         the log path")
        print("  --help     show this help, then exit")
        print(" ")

    ##########################################################################
    # This is the main uninstall flow.  
    ##########################################################################
    def uninstall(self):
        """
        function: Remove install path content, which depend on $GAUSSHOME
        input : NA
        output: NA
        """
        try:
            self.logger.debug("OLAP's local uninstall.")
            self.__cleanMonitor()
            self.__cleanInstallProgram()
            self.__changeuserEnv()
            self.logger.closeLog()
        except Exception as e:
            raise Exception(str(e))

    def __changeuserEnv(self):
        """
        function: Change user GAUSS_ENV
        input : NA
        output: NA
        """
        # clean os user environment variable
        self.logger.log("Modifying user's environmental variable $GAUSS_ENV.")
        userProfile = self.mpprcFile
        DefaultValue.updateUserEnvVariable(userProfile, "GAUSS_ENV", "1")
        if "HOST_IP" in os.environ.keys():
            g_file.deleteLine(userProfile, "^\\s*export\\s*WHITELIST_ENV=.*$")
        self.logger.log("Successfully modified user's environmental"
                        " variable GAUSS_ENV.")

        self.logger.debug("Deleting symbolic link to $GAUSSHOME if exists.")
        gaussHome = DefaultValue.getInstallDir(self.user)
        if gaussHome == "":
            raise Exception(ErrorCode.GAUSS_518["GAUSS_51800"] % "$GAUSSHOME")
        if os.path.islink(gaussHome):
            self.installPath = os.path.realpath(gaussHome)
            os.remove(gaussHome)
        else:
            self.logger.debug("symbolic link does not exists.")
        self.logger.debug("Deleting bin file in installation path.")
        g_file.removeDirectory("%s/bin" % self.installPath)
        self.logger.debug("Successfully deleting bin file in"
                          " installation path.")

    def __cleanMonitor(self):
        """
        function: clean om_monitor process and delete cron
        input : NA
        output: NA
        """
        self.logger.log("Deleting monitor.")
        try:
            # get all content by crontab command
            (status, output) = g_OSlib.getAllCrontab()
            # overwrit crontabFile, make it empty.
            crontabFile = "%s/gauss_crontab_file_%d" \
                          % (DefaultValue.getTmpDirFromEnv(), os.getpid())
            g_file.createFile(crontabFile, True)
            content_CronTabFile = [output]
            g_file.writeFile(crontabFile, content_CronTabFile)
            g_file.deleteLine(crontabFile, "\/bin\/om_monitor")
            g_OSlib.execCrontab(crontabFile)
            g_file.removeFile(crontabFile)

            # clean om_monitor,cm_agent,cm_server process
            for progname in ["om_monitor", "cm_agent", "cm_server"]:
                g_OSlib.killallProcess(self.user, progname, '9')
        except Exception as e:
            if os.path.exists(crontabFile):
                g_file.removeFile(crontabFile)
            raise Exception(str(e))
        self.logger.log("Successfully deleted OMMonitor.")

    def checkParameters(self):
        """
        function: Check input parameters
        input : NA
        output: NA
        """
        try:
            opts, args = getopt.getopt(sys.argv[1:], "t:U:R:l:X:M:T",
                                       ["help", "delete-data"])
        except getopt.GetoptError as e:
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"]
                                   % str(e))

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

        for key, value in opts:
            if (key == "-U"):
                self.user = value
            elif (key == "-R"):
                self.installPath = value
            elif (key == "-l"):
                self.logFile = value
            elif (key == "--help"):
                self.usage()
                sys.exit(0)
            elif (key == "-T"):
                self.installflag = True
            elif key == "--delete-data":
                self.keepData = False
            elif key == "-M":
                self.method = value
            elif key == "-t":
                self.action = value
            else:
                GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"]
                                       % key)

            Parameter.checkParaVaild(key, value)

        if (self.user == ""):
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"]
                                   % 'U' + ".")

        if (self.installPath == ""):
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"]
                                   % 'R' + ".")

        self.mpprcFile = DefaultValue.getMpprcFile()
        if (self.logFile == ""):
            self.logFile = DefaultValue.getOMLogPath(
                DefaultValue.LOCAL_LOG_FILE, self.user, self.installPath)

    def __initLogger(self):
        """
        function: Init logger
        input : NA
        output: NA
        """
        self.logger = GaussLog(self.logFile, "UninstallApp")

    def __cleanInstallProgram(self):
        """
        function: Clean install program
        input : NA
        output: NA
        """
        if (not os.path.exists(self.installPath)):
            self.logger.log("The installation directory does not exist. ")
            return

        realLink = self.installPath
        if os.path.islink(self.installPath):
            realLink = os.readlink(self.installPath)

        # delete upgrade directory
        self.logger.debug("Starting delete other installation directory.")
        try:
            recordVersionFile = os.path.realpath(
                os.path.join(self.installPath, "record_app_directory"))
            if os.path.isfile(recordVersionFile):
                with open(recordVersionFile, 'r') as fp:
                    retLines = fp.readlines()
                if len(retLines) != 2:
                    raise Exception(ErrorCode.GAUSS_502["GAUSS_50222"]
                                    % recordVersionFile)
                oldPath = retLines[0].strip()
                newPath = retLines[1].strip()
                if os.path.normcase(oldPath) == os.path.normcase(realLink):
                    g_file.removeDirectory(newPath)
                else:
                    g_file.removeDirectory(oldPath)
                self.logger.debug("Successfully deleted other installation"
                                  " path need to delete.")
            else:
                self.logger.debug("No other installation path need"
                                  " to delete.")
        except Exception as e:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50209"]
                            % "other installation"
                            + " Can not delete other installation"
                              " directory: %s." % str(e))

        self.logger.log("Removing the installation directory.")
        try:
            fileList = os.listdir(self.installPath)
            for fileName in fileList:
                fileName = fileName.replace("/", "").replace("..", "")
                filePath = os.path.join(os.path.realpath(self.installPath),
                                        fileName)
                if os.path.isfile(filePath):
                    os.remove(filePath)
                elif os.path.isdir(filePath):
                    if (fileName == "bin"):
                        binFileList = os.listdir(filePath)
                        for binFile in binFileList:
                            fileInBinPath = os.path.join(filePath, binFile)
                            if os.path.isfile(fileInBinPath) and \
                                    binFile != "cluster_static_config":
                                os.remove(fileInBinPath)
                            elif os.path.islink(fileInBinPath):
                                os.remove(fileInBinPath)
                            elif os.path.isdir(fileInBinPath):
                                g_file.removeDirectory(fileInBinPath)
                    else:
                        g_file.removeDirectory(filePath)

                self.logger.debug("Remove path:%s." % filePath)

            self.logger.debug("Successfully deleted bin file"
                              " in installation path.")

        except Exception as e:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50209"]
                            % "installation"
                            + " Can not delete installation directory: %s."
                            % str(e))

        # regular match delete empty directory
        self.logger.debug("Starting delete empty installation directory.")
        try:
            removeflag = False
            namePrefix = os.path.basename(self.installPath)
            gaussPath = os.path.realpath(os.path.dirname(self.installPath))
            curInstallName = os.path.basename(realLink)
            fileList = os.listdir(gaussPath)
            for fileName in fileList:
                if fileName.strip() != curInstallName.strip():
                    filePath = os.path.join(os.path.realpath(gaussPath),
                                            fileName)
                    if os.path.isdir(filePath) \
                            and not os.listdir(filePath) and "_" in fileName:
                        fileNameElement = fileName.split("_", 1)
                        if namePrefix.strip() == fileNameElement[0].strip():
                            res = re.search(
                                '^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8}$',
                                fileNameElement[1].strip())
                            if res:
                                removeflag = True
                                g_file.removeDirectory(filePath)
            if removeflag:
                self.logger.debug("Successfully deleted empty"
                                  " installation path.")
            else:
                self.logger.debug("No empty installation path need"
                                  " to delete.")
        except Exception as e:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50209"]
                            % "other installation"
                            + " Can not delete empty installation"
                              " directory: %s." % str(e))

        self.logger.log("Successfully deleted installation directory.")

    def init(self):
        """
        function: constuctor
        """
        self.__initLogger()
예제 #4
0
class Postuninstall(LocalBaseOM):
    """
    execute unPreInstall
    """
    def __init__(self):
        self.action = ""
        self.userInfo = ""
        self.user = ""
        self.group = ""
        self.clusterConfig = ""
        self.preparePath = ""
        self.checkEmpty = False
        self.envParams = []
        self.userProfile = ""
        self.logFile = ""
        self.clusterToolPath = ""
        self.tmpFile = ""
        self.component = []
        self.clusterComponent = []
        self.logger = None
        self.userHome = ""

    def initGlobals(self):
        """
        init global variables
        input : NA
        output: NA
        """
        global g_nodeInfo
        self.logger = GaussLog(self.logFile, self.action)

        if self.clusterConfig != "":
            if os.path.isfile(self.clusterConfig):
                self.clusterToolPath = DefaultValue.getPreClusterToolPath(
                    self.user, self.clusterConfig)
                self.readConfigInfoByXML()
                hostName = DefaultValue.GetHostIpOrName()
                g_nodeInfo = self.clusterInfo.getDbNodeByName(hostName)
                if (g_nodeInfo is None):
                    self.logger.logExit(
                        ErrorCode.GAUSS_516["GAUSS_51620"] % "local" +
                        " There is no host named %s!" % hostName)
            else:
                self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50210"] %
                                    ("config file [%s]" % self.clusterConfig))

        elif self.action != ACTION_CLEAN_DEPENDENCY:
            try:
                self.clusterToolPath = DefaultValue.getClusterToolPath(
                    self.user)
            except Exception as e:
                self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50219"] %
                                    "the cluster tool path" +
                                    " Error: \n%s" % str(e))

        if not self.clusterToolPath:
            self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50219"] %
                                "cluster tool path")

        # make sure if we are using env seperate version,
        # and get the right profile
        # we can not check mppenvfile exists here
        mppenvFile = DefaultValue.getEnv(DefaultValue.MPPRC_FILE_ENV)
        if (mppenvFile != "" and mppenvFile is not None):
            self.userProfile = mppenvFile
        else:
            self.userProfile = "/home/%s/.bashrc" % self.user

    def usage(self):
        """
    Usage:
      python3 UnPreInstallUtility.py -t action -u user [-X xmlfile] [-l log]
    Common options:
      -t                                the type of action
      -u                                the os user of cluster
      -X                                the xml file path
      -l                                the path of log file
      --help                            show this help, then exit
        """
        print(self.usage.__doc__)

    def parseCommandLine(self):
        """
        function: Check parameter from command line
        input : NA
        output: NA
        """
        try:
            opts, args = getopt.getopt(sys.argv[1:], "t:u:X:l:f:Q:P:",
                                       ["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]))

        for (key, value) in opts:
            if (key == "--help"):
                self.usage()
                sys.exit(0)
            elif (key == "-t"):
                self.action = value
            elif (key == "-u"):
                self.user = value
            elif (key == "-X"):
                self.clusterConfig = value
            elif (key == "-l"):
                self.logFile = os.path.realpath(value)
            elif (key == "-f"):
                self.tmpFile = value
            elif key == "-Q":
                self.clusterToolPath = value
            elif key == "-P":
                self.userHome = value
            else:
                GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"] %
                                       key)
            Parameter.checkParaVaild(key, value)

    def checkParameter(self):
        """
        function: Check parameter from command line
        input : NA
        output: NA
        """

        if self.action == "":
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % "t" +
                                   ".")

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

        if self.user == "" and self.action != ACTION_CLEAN_DEPENDENCY:
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % "u" +
                                   ".")

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

    def cleanWarningConfig(self):
        """
        function: clean syslog-ng/rsyslog config
        input : NA
        output: NA
        """
        self.logger.debug("Cleaning syslog-ng configuration.")
        # judge the installed syslog type on the local host is rsyslog
        # or syslog-ng
        syslogType = self.getSyslogType()
        if (syslogType == SYSLOG_NG):
            self.cleanWarningConfigForSyslogng()
        elif (syslogType == RSYSLOG):
            self.cleanWarningConfigForRsyslog()
        self.logger.debug("Successfully cleaned system log.")

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

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

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

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

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

    def cleanEnvSoftware(self):
        """
        function: clean environment software and variable
        Gauss-MPPDB* & sctp_patch is came from R5 upgrade R7
        input : NA
        output: NA
        """
        self.logger.debug("Cleaning the environmental software and variable.")
        # clean environment software
        path = "%s/%s" % (self.clusterToolPath, PSSHDIR)
        g_file.removeDirectory(path)
        path = "%s/lib" % self.clusterToolPath
        g_file.removeDirectory(path)
        path = "%s/script" % self.clusterToolPath
        g_file.removeDirectory(path)
        path = "%s/sudo" % self.clusterToolPath
        g_file.removeDirectory(path)
        path = "%s/upgrade.sh" % self.clusterToolPath
        g_file.removeFile(path)
        path = "%s/version.cfg" % self.clusterToolPath
        g_file.removeFile(path)
        path = "%s/GaussDB.py" % self.clusterToolPath
        g_file.removeFile(path)
        path = "%s/libcgroup" % self.clusterToolPath
        g_file.removeDirectory(path)
        path = "%s/server.key.cipher" % self.clusterToolPath
        g_file.removeFile(path)
        path = "%s/server.key.rand" % self.clusterToolPath
        g_file.removeFile(path)
        path = "%s/%s*" % (self.clusterToolPath, VersionInfo.PRODUCT_NAME)
        g_file.removeDirectory(path)
        path = "%s/Gauss*" % (self.clusterToolPath)
        g_file.removeDirectory(path)
        path = "%s/sctp_patch" % (self.clusterToolPath)
        g_file.removeDirectory(path)
        path = "%s/unixodbc" % self.clusterToolPath
        g_file.removeDirectory(path)
        path = "%s/%s" % (self.clusterToolPath, Const.UPGRADE_SQL_FILE)
        g_file.removeFile(path)
        path = "%s/%s" % (self.clusterToolPath, Const.UPGRADE_SQL_SHA)
        g_file.removeFile(path)
        self.logger.debug(
            "Successfully cleaned the environmental software and variable.")

        self.logger.debug("Cleaning environmental software.")
        # clean environment variable
        cmd = "(if [ -s '%s' ]; then " % PROFILE_FILE
        cmd += "sed -i -e '/^export GPHOME=%s$/d' %s " % (
            self.clusterToolPath.replace('/', '\/'), PROFILE_FILE)
        cmd += \
            "-e '/^export PATH=\$GPHOME\/pssh-2.3.1\/bin:" \
            "\$GPHOME\/script:\$PATH$/d' %s " % PROFILE_FILE
        cmd += \
            "-e '/^export PATH=\$GPHOME\/script\/gspylib\/pssh\/bin:" \
            "\$GPHOME\/script:\$PATH$/d' %s " % PROFILE_FILE
        cmd += \
            "-e '/^export LD_LIBRARY_PATH=\$GPHOME\/lib:" \
            "\$LD_LIBRARY_PATH$/d' %s " % PROFILE_FILE
        cmd += \
            "-e '/^export PYTHONPATH=\$GPHOME\/lib$/d' %s; fi) " % PROFILE_FILE
        self.logger.debug("Command for cleaning environment variable: %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 cleaned environmental software and variable.")

    def checkUnPreInstall(self):
        """
        function: check whether do uninstall before unpreinstall
        input : NA
        output: NA
        """
        self.logger.debug("Checking UnPreInstall.")
        # check if user exist
        try:
            DefaultValue.getUserId(self.user)
        except Exception as e:
            self.logger.logExit(str(e))

        # check if user profile exist
        if (not os.path.exists(self.userProfile)):
            self.logger.debug("The %s does not exist." % self.userProfile +
                              " Please skip to check UnPreInstall.")
            return

            # check $GAUSSHOME
        cmd = "su - %s -c 'source %s && echo $GAUSS_ENV' 2>/dev/null" % (
            self.user, self.userProfile)
        self.logger.debug("Command for getting $GAUSSHOME: %s" % cmd)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd +
                                " Error:\n%s" % output)
        gaussEnv = output.strip()
        if (gaussEnv == "2"):
            self.logger.logExit(ErrorCode.GAUSS_525["GAUSS_52501"] %
                                "gs_uninstall")

            # check $GAUSS_ENV
        cmd = "su - %s -c 'source %s && echo $GAUSS_ENV' 2>/dev/null" % (
            self.user, self.userProfile)
        self.logger.debug("Command for getting $GAUSS_ENV: %s" % cmd)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            self.logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd +
                                " Error:\n%s" % output)
        gaussEnv = output.strip()

        if (str(gaussEnv) != "1"):
            self.logger.logExit(ErrorCode.GAUSS_525["GAUSS_52501"] %
                                "gs_preinstall")

        self.logger.debug("Successfully checked UnPreInstall.")

    def cleanGaussEnv(self):
        """
        function: clean $GAUSS_ENV
        input : NA
        output: NA
        """
        self.logger.debug("Cleaning $GAUSS_ENV.")

        # check if user profile exist
        if (self.userProfile is not None and self.userProfile != ""):
            userProfile = self.userProfile
        else:
            userProfile = "/home/%s/.bashrc" % self.user

        if (not os.path.exists(userProfile)):
            self.logger.debug("The %s does not exist." % userProfile +
                              " Please skip to clean $GAUSS_ENV.")
            return
        # clean user's environmental variable
        DefaultValue.cleanUserEnvVariable(userProfile,
                                          cleanGAUSS_WARNING_TYPE=True)

        # clean $GAUSS_ENV
        envContent = "^\\s*export\\s*GAUSS_ENV=.*$"
        g_file.deleteLine(userProfile, envContent)

        self.logger.debug("Cleaned $GAUSS_ENV.")

    def cleanNetworkfile(self, backIpNIC, virtualIp):
        """
        function: clean configured IP in Network file
        input : NA
        output: NA
        """
        self.logger.debug("Cleaning network file.")
        try:
            # read information from networkfile
            networkfile = "/etc/sysconfig/network/ifcfg-" + backIpNIC
            networkinfo = []
            # check if the file is a link
            g_OSlib.checkLink(networkfile)
            with open(networkfile, "r") as fp:
                networkinfo = fp.readlines()
            LABEL = self.getLABEL(virtualIp, networkfile)
            if (LABEL is not None):
                # init linenum for delete
                del_1 = 0
                del_2 = 0
                linenum = 1
                for line in networkinfo:
                    if (line.split("=")[1].strip() == virtualIp):
                        # find if the netmask exist, if exist, delete this line
                        cmd_g = "grep -n 'NETMASK_%s=' %s" % (LABEL,
                                                              networkfile)
                        (status, output) = subprocess.getstatusoutput(cmd_g)
                        if (status == 0):
                            linenum_net = int(output.split(":")[0])
                        if (linenum + 1 == linenum_net):
                            del_1 = linenum_net
                        # find if the LABEL number exist,
                        # if exist, delete this line
                        cmd_g = "grep -n 'LABEL_%s=' %s " % (LABEL,
                                                             networkfile)
                        (status, output) = subprocess.getstatusoutput(cmd_g)
                        if (status == 0):
                            linenum_net = int(output.split(":")[0])
                        if (linenum + 2 == linenum_net):
                            del_2 = linenum_net
                        # delete issues which exist
                        if (del_1 != 0 and del_2 != 0):
                            cmd = "sed -i '%dd;%dd;%dd' %s" % (
                                linenum, del_1, del_2, networkfile)
                        elif (del_1 != 0 and del_2 == 0):
                            cmd = "sed -i '%dd;%dd' %s" % (linenum, del_1,
                                                           networkfile)
                        elif (del_1 == 0 and del_2 != 0):
                            cmd = "sed -i '%dd;%dd' %s" % (linenum, del_2,
                                                           networkfile)
                        else:
                            cmd = "sed -i '%dd' %s" % (linenum, networkfile)
                        (status, output) = subprocess.getstatusoutput(cmd)
                        if (status != 0):
                            raise Exception(
                                ErrorCode.GAUSS_514["GAUSS_51400"] % cmd +
                                "Error:\n%s" % output)
                    linenum += 1
                self.logger.log(
                    "Successfully clean virtual Ip from network file")
            else:
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50204"] %
                                ("the LABEL number of %s " % virtualIp))
            self.logger.debug("Successfully cleaned network file.")
        except Exception as e:
            self.logger.log("Error: Write networkfile failed." + str(e))

    def IsSuSE12SP0(self):
        """
        function:Check is OS SuSE12.0
        input   :NA
        output  :bool
        """
        if (os.path.isfile("/etc/SuSE-release")):
            cmd = "grep -i 'PATCHLEVEL' /etc/SuSE-release  " \
                  "| awk -F '=' '{print $2}'"
            (status, output) = subprocess.getstatusoutput(cmd)
            if (status == 0 and output != ""):
                if (output.strip().isdigit() and int(output.strip()) == 0):
                    return True
            else:
                raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd +
                                " Error: \n%s " % output)
        return False

    def getLABEL(self, virtualIp, networkfile):
        """
        function: get LABEL number of virtual ip from network file
        input : fp, virtualIp
        output: int
        """
        # check if the file is a link
        g_OSlib.checkLink(networkfile)
        with open(networkfile, "r") as fp:
            for line in fp:
                if line.split("=")[1].strip() == virtualIp:
                    if line.split("IPADDR_")[1].split("=%s" % virtualIp)[0]:
                        return line.split("IPADDR_")[1].split("=%s" %
                                                              virtualIp)[0]
                    else:
                        return None
        return None

    def cleanGroup(self):
        """
        function: clean group
        input : NA
        output: NA
        """
        self.logger.debug("Cleaning user group.")
        hostName = DefaultValue.GetHostIpOrName()
        groupname = self.user

        try:
            groupid = grp.getgrnam(groupname).gr_gid
        except Exception:
            self.logger.debug("group %s has been deleted." % groupname)
            sys.exit(0)

        cmd = "cat /etc/passwd | awk -F [:] '{print $1  \" \"$4}'" \
              "|grep ' %s$'" % groupid
        (status, output) = subprocess.getstatusoutput(cmd)
        if status == 0:
            self.logger.logExit(
                "Warning: There are other users in the group %s on %s,"
                " skip to delete group." % (groupname, hostName))
        elif status == 1:
            cmd = "groupdel %s" % groupname
            (status, output) = subprocess.getstatusoutput(cmd)
            if status != 0:
                self.logger.logExit("Warning: Failed to delete group "
                                    "%s by cmd:%s. Error: \n%s" %
                                    (groupname, cmd, output))
        else:
            self.logger.logExit("Warning: Failed to delete group "
                                "%s by cmd:%s. Error: \n%s" %
                                (groupname, cmd, output))
        self.logger.debug("Successfully cleaned user group.")

    def cleanScript(self):
        """
        function: clean script
        """
        # clean lib
        libPath = os.path.join(self.clusterToolPath, LIBPATH)
        if os.path.exists(libPath):
            g_file.removeDirectory(libPath)

        # clean om script
        scriptPath = os.path.join(self.clusterToolPath, SCRIPTPATH)
        if os.path.exists(scriptPath):
            g_file.removeDirectory(scriptPath)

        # clean root script path
        root_script_path = os.path.join(DefaultValue.ROOT_SCRIPTS_PATH,
                                        self.user)
        if os.path.exists(root_script_path):
            g_file.removeDirectory(root_script_path)
        # if /root/gauss_om has no files, delete it.
        if not os.listdir(DefaultValue.ROOT_SCRIPTS_PATH):
            g_file.removeDirectory(DefaultValue.ROOT_SCRIPTS_PATH)

        # clean others
        if os.path.exists(self.clusterToolPath):
            g_file.cleanDirectoryContent(self.clusterToolPath)

        if self.userHome != "":
            if os.path.exists(self.userHome):
                g_file.removeDirectory(self.userHome)

    def cleanEnv(self):
        """
        function: clean envriment variable
        """
        self.logger.debug("Begin clean envrionment variable")
        if not self.userProfile:
            self.logger.logExit("Clean Env failed: can not get user profile.")
        for comp in self.clusterComponent:
            comp.cleanEnv(self.userProfile)

        # clean user's environment variable
        self.logger.debug("Clean user environment variable.")
        DefaultValue.cleanUserEnvVariable(self.userProfile,
                                          cleanGAUSS_WARNING_TYPE=True)
        # clean GAUSS_ENV
        self.logger.debug("Clean GAUSS_ENV.")
        g_file.deleteLine(self.userProfile, "^\\s*export\\s*GAUSS_ENV=.*$")
        self.logger.debug("Clean envrionment variable successfully.")

    def cleanPath(self):
        """
        function: clean path
        input: NA
        output: NA
        """
        self.logger.debug("Begin clean path")
        if os.path.exists(self.clusterInfo.appPath):
            self.logger.debug("Deleting the install directory.")
            cleanPath = os.path.join(self.clusterInfo.appPath, "./*")
            g_file.removeDirectory(cleanPath)
            self.logger.debug("Successfully deleted the install directory.")
        for i in self.component:
            i.cleanPath()
        gsdbHomePath = "/home/%s/gsdb_home" % self.user
        if os.path.exists(gsdbHomePath):
            self.logger.debug("Deleting the gsdb home path.")
            g_file.removeDirectory(gsdbHomePath)
            self.logger.debug("Successfully deleted the gsdb home path.")
        self.logger.debug("Clean Path successfully.")

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

        try:
            if (self.action == ACTION_CLEAN_SYSLOG_CONFIG):
                self.cleanWarningConfig()
            elif (self.action == ACTION_CLEAN_TOOL_ENV):
                self.cleanEnvSoftware()
            elif (self.action == ACTION_CHECK_UNPREINSTALL):
                self.checkUnPreInstall()
            elif (self.action == ACTION_CLEAN_GAUSS_ENV):
                self.cleanGaussEnv()
            elif (self.action == ACTION_DELETE_GROUP):
                self.cleanGroup()
            elif (self.action == ACTION_CLEAN_DEPENDENCY):
                self.cleanScript()
            elif (self.action == ACTION_CLEAN_ENV):
                self.cleanEnv()
            elif (self.action == ACTION_CLEAN_INSTANCE_PATHS):
                self.cleanPath()
            else:
                self.logger.logExit(ErrorCode.GAUSS_500["GAUSS_50000"] %
                                    self.action)
        except Exception as e:
            self.logger.logExit(str(e))
class ParallelBaseOM(object):
    """
    Base class of parallel command
    """
    ACTION_INSTALL = "install"
    ACTION_CONFIG = "config"
    ACTION_START = "start"
    ACTION_REDISTRIBUTE = "redistribute"
    ACTION_HEALTHCHECK = "healthcheck"

    HEALTH_CHECK_BEFORE = "before"
    HEALTH_CHECK_AFTER = "after"
    """
    Base class for parallel command
    """
    def __init__(self):
        '''
        Constructor
        '''
        self.logger = None
        self.clusterInfo = None
        self.oldClusterInfo = None
        self.sshTool = None
        self.action = ""

        # Cluster config file.
        self.xmlFile = ""
        self.oldXmlFile = ""

        self.logType = DefaultValue.LOCAL_LOG_FILE
        self.logFile = ""
        self.localLog = ""
        self.user = ""
        self.group = ""
        self.mpprcFile = ""
        # Temporary catalog for install
        self.operateStepDir = TempfileManagement.getTempDir(
            "%s_step" % self.__class__.__name__.lower())
        # Temporary files for install step
        self.operateStepFile = "%s/%s_step.dat" % (
            self.operateStepDir, self.__class__.__name__.lower())
        self.initStep = ""
        self.dws_mode = False
        self.rollbackCommands = []
        self.etcdCons = []
        self.cmCons = []
        self.gtmCons = []
        self.cnCons = []
        self.dnCons = []
        # localMode is same as isSingle in all OM script, expect for
        # gs_preinstall.
        # in gs_preinstall, localMode means local mode for master-standby
        # cluster.
        # in gs_preinstall, localMode also means local mode for single
        # cluster(will not create os user).
        # in gs_preinstall, isSingle means single cluster, it will create
        # os user.
        # not isSingle and not localMode : master-standby cluster global
        # mode(will create os user).
        # not isSingle and localMode : master-standby cluster local
        # mode(will not create os user).
        # isSingle and not localMode : single cluster(will create os user).
        # isSingle and localMode : single cluster(will not create os user).
        self.localMode = False
        self.isSingle = False
        # Indicates whether there is a logical cluster.
        # If elastic_group exists, the current cluster is a logical cluster.
        # Otherwise, it is a large physical cluster.
        self.isElasticGroup = False
        self.isAddElasticGroup = False
        self.lcGroup_name = ""
        # Lock the cluster mode, there are two modes: exclusive lock and
        # wait lock mode,
        # the default exclusive lock
        self.lockMode = "exclusiveLock"

        # SinglePrimaryMultiStandby support binary upgrade, inplace upgrade
        self.isSinglePrimaryMultiStandby = False

        # Adapt to 200 and 300
        self.productVersion = None

    def initComponent(self):
        """
        function: Init component
        input : NA
        output: NA
        """
        for nodeInfo in self.clusterInfo.dbNodes:
            self.initKernelComponent(nodeInfo)

    def initComponentAttributes(self, component):
        """
        function: Init  component attributes on current node
        input : Object component
        output: NA
        """
        component.logger = self.logger
        component.binPath = "%s/bin" % self.clusterInfo.appPath
        component.dwsMode = self.dws_mode

    def initKernelComponent(self, nodeInfo):
        """
        function: Init kernel component
        input : Object nodeInfo
        output: NA
        """
        for inst in nodeInfo.datanodes:
            component = DN_OLAP()
            # init component cluster type
            component.clusterType = self.clusterInfo.clusterType
            component.instInfo = inst
            self.initComponentAttributes(component)
            self.dnCons.append(component)

    def initLogger(self, module=""):
        """
        function: Init logger
        input : module
        output: NA
        """
        # log level
        LOG_DEBUG = 1
        self.logger = GaussLog(self.logFile, module, LOG_DEBUG)

        dirName = os.path.dirname(self.logFile)
        self.localLog = os.path.join(dirName, DefaultValue.LOCAL_LOG_FILE)

    def initClusterInfo(self, refreshCN=True):
        """
        function: Init cluster info
        input : NA
        output: NA
        """
        try:
            self.clusterInfo = dbClusterInfo()
            if (refreshCN):
                static_config_file = "%s/bin/cluster_static_config" % \
                                     DefaultValue.getInstallDir(self.user)
                self.clusterInfo.initFromXml(self.xmlFile, static_config_file)
            else:
                self.clusterInfo.initFromXml(self.xmlFile)
        except Exception as e:
            raise Exception(str(e))
        self.logger.debug("Instance information of cluster:\n%s." %
                          str(self.clusterInfo))

    def initClusterInfoFromStaticFile(self, user, flag=True):
        """
        function: Function to init clusterInfo from static file
        input : user
        output: NA
        """
        try:
            self.clusterInfo = dbClusterInfo()
            self.clusterInfo.initFromStaticConfig(user)
        except Exception as e:
            raise Exception(str(e))
        if flag:
            self.logger.debug("Instance information of cluster:\n%s." %
                              str(self.clusterInfo))

    def initSshTool(self, nodeNames, timeout=0):
        """
        function: Init ssh tool
        input : nodeNames, timeout
        output: NA
        """
        self.sshTool = SshTool(nodeNames, self.logger.logFile, timeout)

    def check_cluster_version_consistency(self, clusterNodes, newNodes=None):
        """
        """
        self.logger.log("Check cluster version consistency.")
        if newNodes is None:
            newNodes = []
        dic_version_info = {}
        # check version.cfg on every node.
        gp_home = DefaultValue.getEnv("GPHOME")
        gauss_home = DefaultValue.getEnv("GAUSSHOME")
        if not (os.path.exists(gp_home) and os.path.exists(gauss_home)):
            GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50201"] %
                                   ("%s", "or %s") % (gp_home, gauss_home))
        for ip in clusterNodes:
            if ip in newNodes:
                cmd = "pssh -s -H %s 'cat %s/version.cfg'" % \
                      (ip, DefaultValue.getEnv("GPHOME"))
            else:
                cmd = "pssh -s -H %s 'cat %s/bin/upgrade_version'" % \
                      (ip, DefaultValue.getEnv("GAUSSHOME"))
            status, output = subprocess.getstatusoutput(cmd)
            if (status != 0):
                raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd +
                                " Error:\n%s" % str(output))
            if len(output.strip().split()) < 3:
                raise Exception(ErrorCode.GAUSS_516["GAUSS_51623"])
            dic_version_info[ip] = ",".join(output.strip().split()[1:])

        self.logger.debug("The cluster version on every node.")
        for check_ip, version_info in dic_version_info.items():
            self.logger.debug("%s : %s" % (check_ip, version_info))
        if len(set(dic_version_info.values())) != 1:
            L_inconsistent = list(set(dic_version_info.values()))
            self.logger.debug("The package version on some nodes are "
                              "inconsistent\n%s" % str(L_inconsistent))
            raise Exception("The package version on some nodes are "
                            "inconsistent,%s" % str(L_inconsistent))
        self.logger.log("Successfully checked cluster version.")

    def checkBaseFile(self, checkXml=True):
        """
        function: Check xml file and log file
        input : checkXml
        output: NA
        """
        if (checkXml):
            if (self.xmlFile == ""):
                raise Exception(ErrorCode.GAUSS_500["GAUSS_50001"] % 'X' + ".")

            if (not os.path.exists(self.xmlFile)):
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] %
                                ("configuration file [%s]" % self.xmlFile))

            if (not os.path.isabs(self.xmlFile)):
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50213"] %
                                ("configuration file [%s]" % self.xmlFile))
        else:
            self.xmlFile = ""

        if (self.logFile == ""):
            self.logFile = DefaultValue.getOMLogPath(self.logType, self.user,
                                                     "", self.xmlFile)

        if (not os.path.isabs(self.logFile)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50213"] % "log")

    def initSignalHandler(self):
        """
        function: Function to init signal handler
        input : NA
        output: NA
        """
        signal.signal(signal.SIGINT, signal.SIG_IGN)
        signal.signal(signal.SIGQUIT, signal.SIG_IGN)
        signal.signal(signal.SIGTERM, signal.SIG_IGN)
        signal.signal(signal.SIGALRM, signal.SIG_IGN)
        signal.signal(signal.SIGHUP, signal.SIG_IGN)
        signal.signal(signal.SIGUSR1, signal.SIG_IGN)
        signal.signal(signal.SIGUSR2, signal.SIG_IGN)

    def print_signal_stack(self, frame):
        """
        function: Function to print signal stack
        input : frame
        output: NA
        """
        if (self.logger is None):
            return
        try:
            import inspect
            stacks = inspect.getouterframes(frame)
            for curr in range(len(stacks)):
                stack = stacks[curr]
                self.logger.debug("Stack level: %d. File: %s. Function: "
                                  "%s. LineNo: %d." %
                                  (curr, stack[1], stack[3], stack[2]))
                self.logger.debug("Code: %s." %
                                  (stack[4][0].strip().strip("\n")))
        except Exception as e:
            self.logger.debug("Failed to print signal stack. Error: \n%s" %
                              str(e))

    def raise_handler(self, signal_num, frame):
        """
        function: Function to raise handler
        input : signal_num, frame
        output: NA
        """
        if (self.logger is not None):
            self.logger.debug("Received signal[%d]." % (signal_num))
            self.print_signal_stack(frame)
        raise Exception(ErrorCode.GAUSS_516["GAUSS_51614"] % (signal_num))

    def setupTimeoutHandler(self):
        """
        function: Function to set up time out handler
        input : NA
        output: NA
        """
        signal.signal(signal.SIGALRM, self.timeout_handler)

    def setTimer(self, timeout):
        """
        function: Function to set timer
        input : timeout
        output: NA
        """
        self.logger.debug("Set timer. The timeout: %d." % timeout)
        signal.signal(signal.SIGALRM, self.timeout_handler)
        signal.alarm(timeout)

    def resetTimer(self):
        """
        function: Reset timer
        input : NA
        output: NA
        """
        signal.signal(signal.SIGALRM, signal.SIG_IGN)
        self.logger.debug("Reset timer. Left time: %d." % signal.alarm(0))

    def timeout_handler(self, signal_num, frame):
        """
        function: Received the timeout signal
        input : signal_num, frame
        output: NA
        """
        if (self.logger is not None):
            self.logger.debug("Received the timeout signal: [%d]." %
                              (signal_num))
            self.print_signal_stack(frame)
        raise Timeout("Time out.")

    def waitProcessStop(self, processKeywords, hostname):
        """
        function: Wait the process stop
        input : process name 
        output: NA
        """
        count = 0
        while (True):
            psCmd = "ps ux|grep -v grep |awk '{print \$11}'|grep '%s' " % \
                    processKeywords.strip()
            (status,
             output) = self.sshTool.getSshStatusOutput(psCmd, [hostname])
            # Determine whether the process can be found.
            if (status[hostname] != DefaultValue.SUCCESS):
                self.logger.debug("The %s process stopped." % processKeywords)
                break

            count += 1
            if (count % 20 == 0):
                self.logger.debug("The %s process exists." % processKeywords)
            time.sleep(3)

    def managerOperateStepDir(self, action='create', nodes=None):
        """
        function: manager operate step directory 
        input : NA
        output: currentStep
        """
        if nodes is None:
            nodes = []
        try:
            # Creating the backup directory
            if (action == "create"):
                cmd = "(if [ ! -d '%s' ];then mkdir -p '%s' -m %s;fi)" % (
                    self.operateStepDir, self.operateStepDir,
                    DefaultValue.KEY_DIRECTORY_MODE)
            else:
                cmd = "(if [ -d '%s' ];then rm -rf '%s';fi)" % (
                    self.operateStepDir, self.operateStepDir)
            DefaultValue.execCommandWithMode(cmd,
                                             "%s temporary directory" % action,
                                             self.sshTool, self.localMode
                                             or self.isSingle, "", nodes)
        except Exception as e:
            raise Exception(str(e))

    def readOperateStep(self):
        """
        function: read operate step signal 
        input : NA
        output: currentStep
        """
        currentStep = self.initStep

        if not os.path.exists(self.operateStepFile):
            self.logger.debug("The %s does not exits." % self.operateStepFile)
            return currentStep

        if not os.path.isfile(self.operateStepFile):
            self.logger.debug("The %s must be a file." % self.operateStepFile)
            return currentStep

        with open(self.operateStepFile, "r") as fp:
            line = fp.readline().strip()
            if line is not None and line != "":
                currentStep = line

        return currentStep

    def writeOperateStep(self, stepName, nodes=None):
        """
        function: write operate step signal 
        input : step
        output: NA
        """
        if nodes is None:
            nodes = []
        try:
            # write the step into INSTALL_STEP
            # open the INSTALL_STEP
            with open(self.operateStepFile, "w") as g_DB:
                # write the INSTALL_STEP
                g_DB.write(stepName)
                g_DB.write(os.linesep)
                g_DB.flush()
            # change the INSTALL_STEP permissions
            g_file.changeMode(DefaultValue.KEY_FILE_MODE, self.operateStepFile)

            # distribute file to all nodes
            cmd = "mkdir -p -m %s '%s'" % (DefaultValue.KEY_DIRECTORY_MODE,
                                           self.operateStepDir)
            DefaultValue.execCommandWithMode(
                cmd, "create backup directory "
                "on all nodes", self.sshTool, self.localMode or self.isSingle,
                "", nodes)

            if not self.localMode and not self.isSingle:
                self.sshTool.scpFiles(self.operateStepFile,
                                      self.operateStepDir, nodes)
        except Exception as e:
            # failed to write the step into INSTALL_STEP
            raise Exception(str(e))

    def distributeFiles(self):
        """
        function: distribute package to every host
        input : NA
        output: NA
        """
        self.logger.debug("Distributing files.")
        try:
            # get the all nodes
            hosts = self.clusterInfo.getClusterNodeNames()
            if DefaultValue.GetHostIpOrName() not in hosts:
                raise Exception(ErrorCode.GAUSS_516["GAUSS_51619"] %
                                DefaultValue.GetHostIpOrName())
            hosts.remove(DefaultValue.GetHostIpOrName())
            # Send xml file to every host
            DefaultValue.distributeXmlConfFile(self.sshTool, self.xmlFile,
                                               hosts, self.mpprcFile)
            # Successfully distributed files
            self.logger.debug("Successfully distributed files.")
        except Exception as e:
            # failed to distribute package to every host
            raise Exception(str(e))

    def checkPreInstall(self, user, flag, nodes=None):
        """
        function: check if have done preinstall on given nodes
        input : user, nodes
        output: NA
        """
        if nodes is None:
            nodes = []
        try:
            cmd = "%s -U %s -t %s" % (
                OMCommand.getLocalScript("Local_Check_PreInstall"), user, flag)
            DefaultValue.execCommandWithMode(cmd, "check preinstall",
                                             self.sshTool, self.localMode
                                             or self.isSingle, "", nodes)
        except Exception as e:
            raise Exception(str(e))

    def checkNodeInstall(self,
                         nodes=None,
                         checkParams=None,
                         strictUserCheck=True):
        """
        function: Check node install
        input : nodes, checkParams, strictUserCheck
        output: NA
        """
        if nodes is None:
            nodes = []
        if checkParams is None:
            checkParams = []
        validParam = ["shared_buffers", "max_connections"]
        cooGucParam = ""
        for param in checkParams:
            entry = param.split("=")
            if (len(entry) != 2):
                raise Exception(ErrorCode.GAUSS_500["GAUSS_50009"])
            if (entry[0].strip() in validParam):
                cooGucParam += " -C \\\"%s\\\"" % param
        self.logger.log("Checking installation environment on all nodes.")
        cmd = "%s -U %s:%s -R %s %s -l %s -X '%s'" % (
            OMCommand.getLocalScript("Local_Check_Install"), self.user,
            self.group, self.clusterInfo.appPath, cooGucParam, self.localLog,
            self.xmlFile)
        if (not strictUserCheck):
            cmd += " -O"
        self.logger.debug("Checking the install command: %s." % cmd)
        DefaultValue.execCommandWithMode(cmd, "check installation environment",
                                         self.sshTool, self.localMode
                                         or self.isSingle, "", nodes)

    def cleanNodeConfig(self, nodes=None, datadirs=None):
        """
        function: Clean instance
        input : nodes, datadirs
        output: NA
        """
        self.logger.log("Deleting instances from all nodes.")
        if nodes is None:
            nodes = []
        if datadirs is None:
            datadirs = []
        cmdParam = ""
        for datadir in datadirs:
            cmdParam += " -D %s " % datadir
        cmd = "%s -U %s %s -l %s" % (OMCommand.getLocalScript(
            "Local_Clean_Instance"), self.user, cmdParam, self.localLog)
        DefaultValue.execCommandWithMode(cmd, "clean instance", self.sshTool,
                                         self.localMode or self.isSingle, "",
                                         nodes)
        self.logger.log("Successfully deleted instances from all nodes.")

    @staticmethod
    def getPrepareKeysCmd(key_file,
                          user,
                          confFile,
                          destPath,
                          logfile,
                          userProfile="",
                          localMode=False):
        """
        function: get  etcd communication keys command
        input: key_file, user, confFile, destPath, localMode:do not scp keys
        output: NA
        """
        if (not os.path.exists(key_file)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % key_file)
        if (not userProfile):
            userProfile = DefaultValue.getMpprcFile()
        # create the directory on all nodes
        cmd = "source %s; %s -U %s -X %s --src-file=%s --dest-path=%s -l %s" \
              % (userProfile, OMCommand.getLocalScript("Local_PrepareKeys"),
               user, confFile, key_file, destPath, logfile)
        # if local mode, only prepare keys, do not scp keys to cluster nodes
        if (localMode):
            cmd += " -L"
        return cmd

    def getClusterRings(self, clusterInfo):
        """
        function: get clusterRings from cluster info
        input: DbclusterInfo() instance
        output: list
        """
        hostPerNodeList = self.getDNHostnamesPerNode(clusterInfo)
        # Loop the hostname list on each node where the master and slave
        # of the DB instance.
        for i in range(len(hostPerNodeList)):
            # Loop the list after the i-th list
            for perNodelist in hostPerNodeList[i + 1:len(hostPerNodeList)]:
                # Define a tag
                flag = 0
                # Loop the elements of each perNodelist
                for hostNameElement in perNodelist:
                    # If elements on the i-th node, each element of the
                    # list are joined in hostPerNodeList[i
                    if hostNameElement in hostPerNodeList[i]:
                        flag = 1
                        for element in perNodelist:
                            if element not in hostPerNodeList[i]:
                                hostPerNodeList[i].append(element)
                if (flag == 1):
                    hostPerNodeList.remove(perNodelist)

        return hostPerNodeList

    def getDNHostnamesPerNode(self, clusterInfo):
        """
        function: get DB hostnames per node
        input: DbclusterInfo() instance
        output: list
        """
        hostPerNodeList = []
        for dbNode in clusterInfo.dbNodes:
            nodeDnlist = []
            # loop per node
            for dnInst in dbNode.datanodes:
                if (dnInst.instanceType == DefaultValue.MASTER_INSTANCE):
                    if dnInst.hostname not in nodeDnlist:
                        nodeDnlist.append(dnInst.hostname)
                    # get other standby and dummy hostname
                    instances = clusterInfo.getPeerInstance(dnInst)
                    for inst in instances:
                        if inst.hostname not in nodeDnlist:
                            nodeDnlist.append(inst.hostname)
            if nodeDnlist != []:
                hostPerNodeList.append(nodeDnlist)
        return hostPerNodeList

    # for olap function
    def checkIsElasticGroupExist(self, dbNodes):
        """
        function: Check if elastic_group exists.
        input : NA
        output: NA
        """
        self.logger.debug("Checking if elastic group exists.")

        self.isElasticGroup = False
        coorNode = []
        # traverse old nodes
        for dbNode in dbNodes:
            if (len(dbNode.coordinators) >= 1):
                coorNode.append(dbNode.coordinators[0])
                break

        # check elastic group
        CHECK_GROUP_SQL = "SELECT count(*) FROM pg_catalog.pgxc_group " \
                          "WHERE group_name='elastic_group' " \
                          "and group_kind='e'; "
        (checkstatus, checkoutput) = ClusterCommand.remoteSQLCommand(
            CHECK_GROUP_SQL, self.user, coorNode[0].hostname, coorNode[0].port)
        if (checkstatus != 0 or not checkoutput.isdigit()):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50219"] % "node group" +
                            " Error:\n%s" % str(checkoutput))
        elif (checkoutput.strip() == '1'):
            self.isElasticGroup = True
        elif (checkoutput.strip() == '0'):
            self.isElasticGroup = False
        else:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50219"] %
                            "the number of node group")

        self.logger.debug("Successfully checked if elastic group exists.")

    def checkHostnameIsLoop(self, nodenameList):
        """
        function: check if hostname is looped
        input : NA
        output: NA
        """
        isRing = True
        # 1.get ring information in the cluster
        clusterRings = self.getClusterRings(self.clusterInfo)
        nodeRing = ""
        nodenameRings = []
        # 2.Check if the node is in the ring
        for num in iter(clusterRings):
            ringNodeList = []
            for nodename in nodenameList:
                if (nodename in num):
                    ringNodeList.append(nodename)
            if (len(ringNodeList) != 0 and len(ringNodeList) == len(num)):
                nodenameRings.append(ringNodeList)
            if (len(ringNodeList) != 0 and len(ringNodeList) != len(num)):
                isRing = False
                break
            else:
                continue
        if not isRing:
            raise Exception(ErrorCode.GAUSS_500["GAUSS_50004"] % "h" +
                            " The hostname (%s) specified by the -h parameter "
                            "must be looped." % nodeRing)
        return (clusterRings, nodenameRings)

    def getDNinstanceByNodeName(self, hostname, isMaster=True):
        """
        function: Get the DB instance of the node based on the node name.
        input : hostname
                isMaster: get master DB instance
        output: NA
        """
        masterdnInsts = []
        standbydnInsts = []
        # notice
        for dbNode in self.clusterInfo.dbNodes:
            if (dbNode.name == hostname):
                for dbInst in dbNode.datanodes:
                    # get master DB instance
                    if (dbInst.instanceType == DefaultValue.MASTER_INSTANCE):
                        masterdnInsts.append(dbInst)
                    # get standby or dummy DB instance
                    else:
                        standbydnInsts.append(dbInst)

        if (isMaster):
            return masterdnInsts
        else:
            return standbydnInsts

    def getSQLResultList(self, sql, user, hostname, port, database="postgres"):
        """
        """
        (status,
         output) = ClusterCommand.remoteSQLCommand(sql, user, hostname, port,
                                                   False, database)
        if status != 0 or ClusterCommand.findErrorInSql(output):
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % sql +
                            " Error:\n%s" % str(output))
        # split the output string with '\n'
        resultList = output.split("\n")
        return resultList

    def getCooInst(self):
        """
        function: get CN instance
        input : NA
        output: CN instance
        """
        coorInst = []
        # get CN on nodes
        for dbNode in self.clusterInfo.dbNodes:
            if (len(dbNode.coordinators) >= 1):
                coorInst.append(dbNode.coordinators[0])
        # check if contain CN on nodes
        if (len(coorInst) == 0):
            raise Exception(ErrorCode.GAUSS_526["GAUSS_52602"])
        else:
            return coorInst

    def getGroupName(self, fieldName, fieldVaule):
        """
        function: Get nodegroup name by field name and field vaule.
        input : field name and field vaule
        output: node group name
        """
        # 1.get CN instance info from cluster
        cooInst = self.getCooInst()

        # 2.obtain the node group
        OBTAIN_SQL = "select group_name from pgxc_group where %s = %s; " % \
                     (fieldName, fieldVaule)
        # execute the sql command
        (status, output) = ClusterCommand.remoteSQLCommand(OBTAIN_SQL,
                                                           self.user,
                                                           cooInst[0].hostname,
                                                           cooInst[0].port,
                                                           ignoreError=False)
        if (status != 0):
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % OBTAIN_SQL +
                            " Error:\n%s" % str(output))

        return output.strip()

    def killKernalSnapshotThread(self, dnInst):
        """
        function: kill snapshot thread in Kernel,
                avoid dead lock with redistribution)
        input : NA
        output: NA
        """
        self.logger.debug("Stopping snapshot thread in database node Kernel.")
        killSnapshotSQL = "select * from kill_snapshot();"

        (status, output) = ClusterCommand.remoteSQLCommand(
            killSnapshotSQL, self.user, dnInst.hostname, dnInst.port, False,
            DefaultValue.DEFAULT_DB_NAME)
        if (status != 0):
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] %
                            killSnapshotSQL + " Error:\n%s" % str(output))
        self.logger.debug("Successfully stopped snapshot "
                          "thread in database node Kernel.")

    def createServerCa(self, hostList=None):
        """
        function: create grpc ca file
        input : NA
        output: NA
        """
        self.logger.debug("Generating CA files.")
        if hostList is None:
            hostList = []
        appPath = DefaultValue.getInstallDir(self.user)
        caPath = os.path.join(appPath, "share/sslcert/om")
        self.logger.debug("The ca file dir is: %s." % caPath)
        if (len(hostList) == 0):
            for dbNode in self.clusterInfo.dbNodes:
                hostList.append(dbNode.name)
        # Create CA dir and prepare files for using.
        self.logger.debug("Create CA file directory.")
        try:
            DefaultValue.createCADir(self.sshTool, caPath, hostList)
            self.logger.debug("Add hostname to config file.")
            DefaultValue.createServerCA(DefaultValue.SERVER_CA, caPath,
                                        self.logger)
            # Clean useless files, and change permission of ca file to 600.
            DefaultValue.cleanServerCaDir(caPath)
            self.logger.debug("Scp CA files to all nodes.")
        except Exception as e:
            certFile = caPath + "/demoCA/cacert.pem"
            if os.path.exists(certFile):
                g_file.removeFile(certFile)
            DefaultValue.cleanServerCaDir(caPath)
            raise Exception(str(e))
        if not self.isSingle:
            # localhost no need scp files
            for certFile in DefaultValue.SERVER_CERT_LIST:
                scpFile = os.path.join(caPath, "%s" % certFile)
                self.sshTool.scpFiles(scpFile, caPath, hostList)
        self.logger.debug("Successfully generated server CA files.")

    def createGrpcCa(self, hostList=None):
        """
        function: create grpc ca file
        input : NA
        output: NA
        """
        self.logger.debug("Generating grpc CA files.")
        if hostList is None:
            hostList = []
        appPath = DefaultValue.getInstallDir(self.user)
        caPath = os.path.join(appPath, "share/sslcert/grpc")
        self.logger.debug("The ca file dir is: %s." % caPath)
        if (len(hostList) == 0):
            for dbNode in self.clusterInfo.dbNodes:
                hostList.append(dbNode.name)
        # Create CA dir and prepare files for using.
        self.logger.debug("Create CA file directory.")
        try:
            DefaultValue.createCADir(self.sshTool, caPath, hostList)
            self.logger.debug("Add hostname to config file.")
            configPath = os.path.join(appPath,
                                      "share/sslcert/grpc/openssl.cnf")
            self.logger.debug("The ca file dir is: %s." % caPath)
            # Add hostname to openssl.cnf file.
            DefaultValue.changeOpenSslConf(configPath, hostList)
            self.logger.debug("Generate CA files.")
            DefaultValue.createCA(DefaultValue.GRPC_CA, caPath)
            # Clean useless files, and change permission of ca file to 600.
            DefaultValue.cleanCaDir(caPath)
            self.logger.debug("Scp CA files to all nodes.")
        except Exception as e:
            certFile = caPath + "/demoCA/cacertnew.pem"
            if os.path.exists(certFile):
                g_file.removeFile(certFile)
            DefaultValue.cleanCaDir(caPath)
            raise Exception(str(e))
        for certFile in DefaultValue.GRPC_CERT_LIST:
            scpFile = os.path.join(caPath, "%s" % certFile)
            self.sshTool.scpFiles(scpFile, caPath, hostList)
        self.logger.debug("Successfully generated grpc CA files.")

    def genCipherAndRandFile(self, hostList=None, initPwd=None):
        self.logger.debug("Encrypting cipher and rand files.")
        if hostList is None:
            hostList = []
        appPath = DefaultValue.getInstallDir(self.user)
        binPath = os.path.join(appPath, "bin")
        retry = 0
        while True:
            if not initPwd:
                sshpwd = getpass.getpass("Please enter password for database:")
                sshpwd_check = getpass.getpass("Please repeat for database:")
            else:
                sshpwd = sshpwd_check = initPwd
            if sshpwd_check != sshpwd:
                sshpwd = ""
                sshpwd_check = ""
                self.logger.error(ErrorCode.GAUSS_503["GAUSS_50306"] %
                                  "database" +
                                  "The two passwords are different, "
                                  "please enter password again.")
            else:
                cmd = "%s/gs_guc encrypt -M server -K %s -D %s " % (
                    binPath, sshpwd, binPath)
                (status, output) = subprocess.getstatusoutput(cmd)
                sshpwd = ""
                sshpwd_check = ""
                initPwd = ""
                if status != 0:
                    self.logger.error(ErrorCode.GAUSS_503["GAUSS_50322"] %
                                      "database" + "Error:\n %s" % output)
                else:
                    break
            if retry >= 2:
                raise Exception(ErrorCode.GAUSS_503["GAUSS_50322"] %
                                "database")
            retry += 1
        g_file.changeMode(DefaultValue.KEY_FILE_MODE,
                          "'%s'/server.key.cipher" % binPath)
        g_file.changeMode(DefaultValue.KEY_FILE_MODE,
                          "'%s'/server.key.rand" % binPath)
        if len(hostList) == 0:
            for dbNode in self.clusterInfo.dbNodes:
                hostList.append(dbNode.name)
        if not self.isSingle:
            # localhost no need scp files
            for certFile in DefaultValue.BIN_CERT_LIST:
                scpFile = os.path.join(binPath, "%s" % certFile)
                self.sshTool.scpFiles(scpFile, binPath, hostList)
        self.logger.debug("Successfully encrypted cipher and rand files.")
예제 #6
0
class LocalBaseOM(object):
    """
    Base class for local command
    """
    def __init__(self,
                 logFile=None,
                 user=None,
                 clusterConf=None,
                 dwsMode=False,
                 initParas=None,
                 gtmInitParas=None):
        '''
        Constructor
        '''
        if (logFile is not None):
            self.logger = GaussLog(logFile, self.__class__.__name__)
        else:
            self.logger = None
        self.clusterInfo = None
        self.dbNodeInfo = None
        self.clusterConfig = clusterConf
        self.user = user
        self.group = ""
        self.dws_mode = dwsMode
        if initParas is None:
            initParas = []
        self.initParas = initParas
        if gtmInitParas is None:
            gtmInitParas = []
        self.gtmInitParas = gtmInitParas
        self.etcdCons = []
        self.cmCons = []
        self.gtmCons = []
        self.cnCons = []
        self.dnCons = []
        self.gtsCons = []

    def initComponent(self):
        """
        function: Init component
        input : NA
        output: NA
        """
        self.initKernelComponent()

    def initComponentAttributes(self, component):
        """
        function: Init  component attributes on current node
        input : Object component
        output: NA
        """
        component.logger = self.logger
        component.binPath = "%s/bin" % self.clusterInfo.appPath
        component.dwsMode = self.dws_mode

    def initKernelComponent(self):
        """
        function: Init kernel component on current node
        input : Object nodeInfo
        output: NA
        """
        for inst in self.dbNodeInfo.datanodes:
            component = DN_OLAP()
            # init component cluster type
            component.clusterType = self.clusterInfo.clusterType
            component.instInfo = inst
            component.instInfo.peerInstanceInfos = \
                self.clusterInfo.getPeerInstance(component.instInfo)
            self.initComponentAttributes(component)
            component.initParas = self.initParas
            self.dnCons.append(component)

    def readConfigInfo(self):
        """
        function: Read config from static config file
        input : NA
        output: NA
        """
        try:
            self.clusterInfo = dbClusterInfo()
            hostName = DefaultValue.GetHostIpOrName()
            dynamicFileExist = False
            if self.__class__.__name__ == "Start":
                dynamicFileExist = \
                    self.clusterInfo.dynamicConfigExists(self.user)
            if dynamicFileExist:
                self.clusterInfo.readDynamicConfig(self.user)
                self.dbNodeInfo = self.clusterInfo.getDbNodeByName(hostName)
            else:
                self.clusterInfo.initFromStaticConfig(self.user)
                self.dbNodeInfo = self.clusterInfo.getDbNodeByName(hostName)
            if self.dbNodeInfo is None:
                self.logger.logExit(ErrorCode.GAUSS_516["GAUSS_51619"] %
                                    hostName)
        except Exception as e:
            self.logger.logExit(str(e))

        self.logger.debug("Instance information on local node:\n%s" %
                          str(self.dbNodeInfo))

    def readConfigInfoByXML(self):
        """
        function: Read config from xml config file
        input : NA
        output: NA
        """
        try:
            if (self.clusterConfig is None):
                self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50201"] %
                                    "XML configuration file")
            static_config_file = "%s/bin/cluster_static_config" % \
                                 DefaultValue.getInstallDir(self.user)
            self.clusterInfo = dbClusterInfo()
            self.clusterInfo.initFromXml(self.clusterConfig,
                                         static_config_file)
            hostName = DefaultValue.GetHostIpOrName()
            self.dbNodeInfo = self.clusterInfo.getDbNodeByName(hostName)
            if (self.dbNodeInfo is None):
                self.logger.logExit(ErrorCode.GAUSS_516["GAUSS_51619"] %
                                    hostName)
        except Exception as e:
            self.logger.logExit(str(e))
        self.logger.debug("Instance information on local node:\n%s" %
                          str(self.dbNodeInfo))

    def getUserInfo(self):
        """
        Get user and group
        """
        if os.path.islink(self.clusterInfo.appPath):
            appPath = os.path.realpath(self.clusterInfo.appPath)
        elif os.path.exists(self.clusterInfo.appPath):
            appPath = self.clusterInfo.appPath
        else:
            commitid = VersionInfo.getCommitid()
            appPath = self.clusterInfo.appPath + "_" + commitid
        self.logger.debug("Get the install path %s user info." % appPath)
        (self.user, self.group) = g_OSlib.getPathOwner(appPath)
        if (self.user == "" or self.group == ""):
            self.logger.logExit(ErrorCode.GAUSS_503["GAUSS_50308"])