From 8f4e721dab4540c27848efc479c006b08242de10 Mon Sep 17 00:00:00 2001 From: xue_meng_en <1836611252@qq.com> Date: Wed, 9 Nov 2022 20:33:05 +0800 Subject: [PATCH 1/4] =?UTF-8?q?xml=E6=96=87=E4=BB=B6=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tool/cm_tool/Common.py | 20 ++++++++++++++ tool/cm_tool/cm_install | 56 ++++++++++++++++++++++----------------- tool/cm_tool/cm_uninstall | 21 ++++++++++++--- 3 files changed, 69 insertions(+), 28 deletions(-) diff --git a/tool/cm_tool/Common.py b/tool/cm_tool/Common.py index 7f6377a..1763e4a 100644 --- a/tool/cm_tool/Common.py +++ b/tool/cm_tool/Common.py @@ -18,6 +18,7 @@ # Description : Common.py includes some public function ############################################################################# +import os import subprocess from CMLog import CMLog from ErrorCode import ErrorCode @@ -40,3 +41,22 @@ def executeCmdOnHost(host, cmd, isLocal = False): cmd = 'ssh -o ConnectTimeout=5 %s \"%s\"' % (host, cmd) status, output = subprocess.getstatusoutput(cmd) return status, output + +def checkXMLFile(xmlFile): + """ + function: check XML file + 1.check whether XML file exists + 2.check whether XML file is file + 3.permission + input : NA + output: NA + """ + if xmlFile.startswith('~/'): + homePath = os.path.expanduser('~') + xmlFile = homePath + xmlFile[1:] + if not os.path.exists(xmlFile): + CMLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50201"] % "xmlFile") + if not os.path.isfile(xmlFile): + CMLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50210"] % "xmlFile") + if not os.access(xmlFile, os.R_OK): + CMLog.exitWithError(ErrorCode.GAUSS_501["GAUSS_50100"] % (xmlFile, "current user")) diff --git a/tool/cm_tool/cm_install b/tool/cm_tool/cm_install index af540a7..4c73c15 100644 --- a/tool/cm_tool/cm_install +++ b/tool/cm_tool/cm_install @@ -19,6 +19,7 @@ # Description : cm_install is a utility to deploy CM tool to openGauss database cluster. ############################################################################# +import cmd import getopt import os import sys @@ -60,26 +61,7 @@ class Install: self.tmpPath = getEnvParam(self.envFile, "PGHOST") def checkXMLFile(self): - """ - function: check XML file - 1.check -X parameter - 2.check XML file exists - 3.check XML file an absolute path - 4.permission - input : NA - output: NA - """ - if self.xmlFile.startswith('~/'): - homePath = os.path.expanduser('~') - self.xmlFile = homePath + self.xmlFile[1:] - if not os.path.isfile(self.xmlFile): - CMLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50210"] % "xmlFile") - if not os.path.exists(self.xmlFile): - CMLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50201"] % "xmlFile") - if not os.path.isabs(self.xmlFile): - CMLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50213"] % "xmlFile") - if not os.access(self.xmlFile, os.R_OK): - CMLog.exitWithError(ErrorCode.GAUSS_501["GAUSS_50100"] % (self.xmlFile, "current user")) + checkXMLFile(self.xmlFile) def checkExeUser(self): if os.getuid() == 0: @@ -128,7 +110,7 @@ General options: CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'X or xml' + ".") if self.cmpkg == "": - CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'p or cmpkg' + ".") + CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'cmpkg' + ".") if self.envFile == "": self.envFile = "~/.bashrc" @@ -180,6 +162,8 @@ General options: def getInfoListOfAllNodes(self): """ get hostname and cmDir list of all nodes + check other CM infos in xml + TODO: check the consistence of xml and installed cluster. """ self.localhostName = getLocalhostName() @@ -189,13 +173,35 @@ General options: raise Exception(ErrorCode.GAUSS_512["GAUSS_51200"] % elementName) deviceArray = rootNode.findall('DEVICELIST')[0] deviceNodes = deviceArray.findall('DEVICE') + cmDict = {"cmsNum": "", "cmServerPortBase": "", "cmServerPortStandby": "", + "cmServerlevel": "", "cmServerListenIp1": "", "cmServerRelation": ""} for dev in deviceNodes: paramList = dev.findall('PARAM') for param in paramList: - if param.attrib['name'] == 'name': - self.hostNames.append(param.attrib['value']) - if param.attrib['name'] == 'cmDir': - self.cmDirs.append(param.attrib['value']) + paraName = param.attrib['name'] + paraValue = param.attrib['value'] + if paraName == 'name': + self.hostnames.append(paraValue) + elif paraName == 'cmDir': + self.cmDirs.append(paraValue) + elif paraName in cmDict.keys(): + cmDict[paraName] = paraValue + # check params in xml + for item in cmDict: + if item == 'cmServerPortStandby': + continue + if cmDict[item] == "": + CMLog.exitWithError(ErrorCode.GAUSS_512["GAUSS_51200"] % item) + if cmDict['cmsNum'] != '1': + CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50024"] % 'cmsNum') + if cmDict['cmServerlevel'] != '1': + CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50024"] % 'cmServerlevel') + if not cmDict['cmServerPortBase'].isdigit(): + CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50024"] % 'cmServerPortBase') + if cmDict['cmServerPortStandby'] != "" and not cmDict['cmServerPortStandby'].isdigit(): + CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50024"] % 'cmServerPortStandby') + if len(self.hostNames) != len(self.cmDirs): + CMLog.exitWithError("\"cmDir\" of all nodes must be provided.") def _checkTrust(self, host): """ diff --git a/tool/cm_tool/cm_uninstall b/tool/cm_tool/cm_uninstall index b175d89..1ff8ad3 100644 --- a/tool/cm_tool/cm_uninstall +++ b/tool/cm_tool/cm_uninstall @@ -26,7 +26,7 @@ import subprocess from CMLog import CMLog from ErrorCode import ErrorCode from InstallImpl import InstallImpl -from Common import executeCmdOnHost, getEnvParam, getLocalhostName +from Common import * class UnIntall: def __init__(self) -> None: @@ -40,7 +40,7 @@ class UnIntall: def usage(self): """ -cm_uninstall is a utility to deploy CM tool to openGauss database cluster. +cm_uninstall is a utility to uninstall CM tool to openGauss database cluster. Usage: cm_uninstall -? | --help @@ -88,6 +88,17 @@ General options: if self.envFile == "": self.envFile = "~/.bashrc" + def _checkXMLContainCMInfo(self): + cmd = "grep -E 'cmDir|cmsNum|cmServerPortBase|cmServerPortStandby|cmServerlevel|" \ + "cmServerListenIp1|cmServerRelation' " + self.xmlFile + status, output = subprocess.getstatusoutput(cmd) + if status == 0: + CMLog.exitWithError("%s should not contain CM infos.\nDetail:\n%s" % (self.xmlFile, output)) + + def checkXMLFile(self): + checkXMLFile(self.xmlFile) + self._checkXMLContainCMInfo() + def getHostnames(self): """ Get hostnames of all nodes from static file. @@ -134,7 +145,10 @@ General options: crontab {cronContentTmpFile} """.format(cronContentTmpFile=cronContentTmpFile) for host in self.hostnames: - status, output = executeCmdOnHost(host, cmd) + isLocal = False + if host == self.localhostName: + isLocal = True + status, output = executeCmdOnHost(host, cmd, isLocal) if status != 0: errorDetail = "\nCommand: %s\nStatus: %s\nOutput: %s" % (cmd, status, output) self.logger.logExit(("Failed to cancle monitor crontab on host %s." % host) + errorDetail) @@ -232,6 +246,7 @@ General options: self.checkExeUser() self.parseCommandLine() self.checkParam() + self.checkXMLFile() self.initLogger() self.logger.log("Start to uninstall CM.") self.getHostnames() From 5e80e13dcbca09767412a346955a2dd331ccbd0b Mon Sep 17 00:00:00 2001 From: xue_meng_en <1836611252@qq.com> Date: Tue, 1 Nov 2022 11:24:33 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8D=B8=E8=BD=BDCM?= =?UTF-8?q?=E6=9C=AA=E6=B8=85=E7=90=86=E5=AE=8C=E5=85=A8CM=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=96=87=E4=BB=B6=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tool/cm_tool/cm_uninstall | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tool/cm_tool/cm_uninstall b/tool/cm_tool/cm_uninstall index 1ff8ad3..b5e110c 100644 --- a/tool/cm_tool/cm_uninstall +++ b/tool/cm_tool/cm_uninstall @@ -204,15 +204,16 @@ General options: if not self.bDeleteData: return self.logger.log("Deleting CM data path.") + self.logger.closeLog() for host, path in zip(self.hostnames, self.cmDataPaths): isLocal = False if host == self.localhostName: isLocal = True - cmd = "source %s; rm -rf %s" % (self.envFile, path) + cmd = "source %s; rm -rf %s $GAUSSLOG/cm" % (self.envFile, path) status, output = executeCmdOnHost(host, cmd, isLocal) if status != 0: errorDetail = "\nCommand: %s\nStatus: %s\nOutput: %s" % (cmd, status, output) - self.logger.exitWithError(("Failed to delete CM data path on host %s." % host) + errorDetail) + CMLog.exitWithError(("Failed to delete CM data path on host %s." % host) + errorDetail) def deleteBinary(self): """ @@ -225,11 +226,12 @@ General options: isLocal = False if host == self.localhostName: isLocal = True - cmd = "source %s; cd $GAUSSHOME/bin; rm -f om_monitor cm_agent cm_server cm_ctl; cd -" % self.envFile + cmd = "source %s; cd $GAUSSHOME/bin; rm -f om_monitor* cm_agent* cm_server* " \ + "cm_ctl* *manual*start*; cd -" % self.envFile status, output = executeCmdOnHost(host, cmd, isLocal) if status != 0: errorDetail = "\nCommand: %s\nStatus: %s\nOutput: %s" % (cmd, status, output) - self.logger.exitWithError(("Failed to delete CM binaries on host %s." % host) + errorDetail) + self.logger.logExit(("Failed to delete CM binaries on host %s." % host) + errorDetail) def initLogger(self): gaussLog = getEnvParam(self.envFile, "GAUSSLOG") @@ -254,11 +256,13 @@ General options: self.cancleMonitorCrontab() self.stopCMProcess() self.refreshStaticAndDynamicFile() - self.deleteData() self.deleteBinary() - self.logger.log("Uninstall CM tool success.") - + self.deleteData() + if self.bDeleteData: + self.logger.printMessage("Uninstall CM tool success.") + else: + self.logger.logExit("Uninstall CM tool success.") if __name__ == "__main__": unInstall = UnIntall() - unInstall.run() \ No newline at end of file + unInstall.run() From 2b88920078cd912d8e437154a9a23e36a12c5365 Mon Sep 17 00:00:00 2001 From: xue_meng_en <1836611252@qq.com> Date: Tue, 1 Nov 2022 19:48:29 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E6=96=87=E4=BB=B6=E4=B8=BA=E7=9B=B8=E5=AF=B9?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E5=AF=BC=E8=87=B4monitor=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tool/cm_tool/cm_install | 20 +++++++++++++------- tool/cm_tool/cm_uninstall | 21 ++++++++++++--------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/tool/cm_tool/cm_install b/tool/cm_tool/cm_install index 4c73c15..399bd9f 100644 --- a/tool/cm_tool/cm_install +++ b/tool/cm_tool/cm_install @@ -60,9 +60,6 @@ class Install: self.toolPath = getEnvParam(self.envFile, "GPHOME") self.tmpPath = getEnvParam(self.envFile, "PGHOST") - def checkXMLFile(self): - checkXMLFile(self.xmlFile) - def checkExeUser(self): if os.getuid() == 0: CMLog.exitWithError(ErrorCode.GAUSS_501["GAUSS_50105"]) @@ -107,13 +104,23 @@ General options: def checkParam(self): if self.xmlFile == "": - CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'X or xml' + ".") + CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'X' + ".") + checkXMLFile(self.xmlFile) if self.cmpkg == "": - CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'cmpkg' + ".") + CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % '-cmpkg' + ".") + if not os.path.exists(self.cmpkg): + CMLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50201"] % self.cmpkg) if self.envFile == "": - self.envFile = "~/.bashrc" + self.envFile = os.path.join(os.environ['HOME'], ".bashrc") + if not os.path.exists(self.envFile): + CMLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50201"] % ("envFile " + self.envFile)) + if not os.path.isfile(self.envFile): + CMLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50210"] % ("envFile " + self.envFile)) + self.envFile = getEnvParam(self.envFile, "MPPDB_ENV_SEPARATE_PATH") + if self.envFile == "" or not os.path.exists(self.envFile) or not os.path.isfile(self.envFile): + CMLog.exitWithError(ErrorCode.GAUSS_518["GAUSS_51802"] % 'MPPDB_ENV_SEPARATE_PATH' + ".") def checkOm(self): """ @@ -239,7 +246,6 @@ General options: self.checkParam() self.checkOm() self.checkCM() - self.checkXMLFile() self.getEnvParams() self.initLogger() self.getLocalhostName() diff --git a/tool/cm_tool/cm_uninstall b/tool/cm_tool/cm_uninstall index b5e110c..218bda6 100644 --- a/tool/cm_tool/cm_uninstall +++ b/tool/cm_tool/cm_uninstall @@ -82,23 +82,26 @@ General options: def checkParam(self): if self.xmlFile == "": - CMLog.exitWithError( - ErrorCode.GAUSS_500["GAUSS_50001"] % 'X' + ".") + CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'X' + ".") + checkXMLFile(self.xmlFile) if self.envFile == "": - self.envFile = "~/.bashrc" + self.envFile = os.path.join(os.environ['HOME'], ".bashrc") + if not os.path.exists(self.envFile): + CMLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50201"] % ("envFile " + self.envFile)) + if not os.path.isfile(self.envFile): + CMLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50210"] % ("envFile " + self.envFile)) + self.envFile = getEnvParam(self.envFile, "MPPDB_ENV_SEPARATE_PATH") + if self.envFile == "" or not os.path.exists(self.envFile) or not os.path.isfile(self.envFile): + CMLog.exitWithError(ErrorCode.GAUSS_518["GAUSS_51802"] % 'MPPDB_ENV_SEPARATE_PATH' + ".") - def _checkXMLContainCMInfo(self): + def checkXMLContainCMInfo(self): cmd = "grep -E 'cmDir|cmsNum|cmServerPortBase|cmServerPortStandby|cmServerlevel|" \ "cmServerListenIp1|cmServerRelation' " + self.xmlFile status, output = subprocess.getstatusoutput(cmd) if status == 0: CMLog.exitWithError("%s should not contain CM infos.\nDetail:\n%s" % (self.xmlFile, output)) - def checkXMLFile(self): - checkXMLFile(self.xmlFile) - self._checkXMLContainCMInfo() - def getHostnames(self): """ Get hostnames of all nodes from static file. @@ -248,7 +251,7 @@ General options: self.checkExeUser() self.parseCommandLine() self.checkParam() - self.checkXMLFile() + self.checkXMLContainCMInfo() self.initLogger() self.logger.log("Start to uninstall CM.") self.getHostnames() From f48f950513f5df2cc036dc39b13f1ec3095180dd Mon Sep 17 00:00:00 2001 From: xue_meng_en <1836611252@qq.com> Date: Sat, 5 Nov 2022 10:40:15 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E5=8D=B8=E8=BD=BDCM=E5=89=8D=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E4=BA=92=E4=BF=A1=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tool/cm_tool/Common.py | 16 ++++++++++++++++ tool/cm_tool/cm_install | 18 +++--------------- tool/cm_tool/cm_uninstall | 6 +++++- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/tool/cm_tool/Common.py b/tool/cm_tool/Common.py index 1763e4a..a4aa83f 100644 --- a/tool/cm_tool/Common.py +++ b/tool/cm_tool/Common.py @@ -60,3 +60,19 @@ def checkXMLFile(xmlFile): CMLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50210"] % "xmlFile") if not os.access(xmlFile, os.R_OK): CMLog.exitWithError(ErrorCode.GAUSS_501["GAUSS_50100"] % (xmlFile, "current user")) + +def checkHostsTrust(hosts, localhost = ""): + """ + check trust between current host and the given hosts + """ + hostsWithoutTrust = [] + for host in hosts: + if host == localhost: + continue + checkTrustCmd = "ssh -o ConnectTimeout=3 -o ConnectionAttempts=5 -o PasswordAuthentication=no " \ + "-o StrictHostKeyChecking=no %s 'pwd > /dev/null'" % host + status, output = subprocess.getstatusoutput(checkTrustCmd) + if status != 0: + hostsWithoutTrust.append(host) + if hostsWithoutTrust != []: + CMLog.exitWithError(ErrorCode.GAUSS_511["GAUSS_51100"] % ','.join(hostsWithoutTrust)) diff --git a/tool/cm_tool/cm_install b/tool/cm_tool/cm_install index 399bd9f..a2a117f 100644 --- a/tool/cm_tool/cm_install +++ b/tool/cm_tool/cm_install @@ -46,7 +46,7 @@ class Install: self.toolPath = "" self.tmpPath = "" self.cmDirs = [] - self.hostNames = [] + self.hostnames = [] self.localhostName = "" self.cmpkg = "" @@ -207,23 +207,11 @@ General options: CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50024"] % 'cmServerPortBase') if cmDict['cmServerPortStandby'] != "" and not cmDict['cmServerPortStandby'].isdigit(): CMLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50024"] % 'cmServerPortStandby') - if len(self.hostNames) != len(self.cmDirs): + if len(self.hostnames) != len(self.cmDirs): CMLog.exitWithError("\"cmDir\" of all nodes must be provided.") - def _checkTrust(self, host): - """ - check trust between current host and the given host - """ - checkTrustCmd = "source %s; pssh -s -H %s 'pwd'" % (self.envFile, host) - status, output = subprocess.getstatusoutput(checkTrustCmd) - return status - def checkHostTrust(self): - for host in self.hostNames: - if host == self.localhostName: - continue - if self._checkTrust(host) != 0: - CMLog.exitWithError(ErrorCode.GAUSS_511["GAUSS_51100"] % host) + checkHostsTrust(self.hostnames, self.localhostName) def initLogger(self): logPath = os.path.join(self.gaussLog, "cm", "cm_tool") diff --git a/tool/cm_tool/cm_uninstall b/tool/cm_tool/cm_uninstall index 218bda6..a1f007a 100644 --- a/tool/cm_tool/cm_uninstall +++ b/tool/cm_tool/cm_uninstall @@ -247,14 +247,18 @@ General options: if os.getuid() == 0: CMLog.exitWithError(ErrorCode.GAUSS_501["GAUSS_50105"]) + def checkHostTrust(self): + checkHostsTrust(self.hostnames, self.localhostName) + def run(self): self.checkExeUser() self.parseCommandLine() self.checkParam() self.checkXMLContainCMInfo() self.initLogger() - self.logger.log("Start to uninstall CM.") self.getHostnames() + self.checkHostTrust() + self.logger.log("Start to uninstall CM.") self.getCMDataPaths() self.cancleMonitorCrontab() self.stopCMProcess()