#!/usr/bin/env python3 # -*- coding:utf-8 -*- ############################################################################# # Copyright (c) 2020 Huawei Technologies Co.,Ltd. # # openGauss is licensed under Mulan PSL v2. # You can use this software according to the terms # and conditions of the Mulan PSL v2. # You may obtain a copy of Mulan PSL v2 at: # # http://license.coscl.org.cn/MulanPSL2 # # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, # WITHOUT WARRANTIES OF ANY KIND, # EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, # MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. # See the Mulan PSL v2 for more details. # ---------------------------------------------------------------------------- # Description : CleanInstance.py is a utility to clean Gauss MPP # Database instance. ############################################################################# import getopt import os import sys sys.path.append(sys.path[0] + "/../") from gspylib.common.GaussLog import GaussLog from gspylib.common.Common import ClusterInstanceConfig from gspylib.common.ParameterParsecheck import Parameter from gspylib.common.ErrorCode import ErrorCode from gspylib.common.LocalBaseOM import LocalBaseOM from gspylib.threads.parallelTool import parallelTool from domain_utils.cluster_file.cluster_log import ClusterLog from domain_utils.domain_common.cluster_constants import ClusterConstants from domain_utils.cluster_os.cluster_user import ClusterUser ######################################################################## TYPE_DATADIR = "data-dir" TYPE_LOCKFILE = "lock-file" ######################################################################## # Global variables define ######################################################################## g_opts = None ######################################################################## class CmdOptions(): """ class: cmdOptions """ def __init__(self): """ function: Constructor input : NA output: NA """ self.clusterInfo = None self.dbNodeInfo = None self.logger = None self.cleanType = [] self.Instancedirs = [] self.tblspcdirs = [] self.user = "" self.group = "" self.clusterConfig = "" self.failedDir = "" self.nodedirCount = 0 self.inputDir = False self.logFile = "" ############################################################################## # Help context. ############################################################################## def usage(): """ CleanInstance.py is a utility to clean Gauss MPP Database instance. Usage: python3 CleanInstance.py --help python3 CleanInstance.py -U user [-t cleanType...] [-D datadir...] [-l logfile] [-X clusterConfig] Common options: --help show this help, then exit -U the user of Gauss MPP Database -t the content to be cleaned, can be data directory, lock-file. -D the directory of instance to be clean. -l the log file path -X the path of XML configuration file """ print(usage.__doc__) def parseCommandLine(): """ function: check input parameters input : NA output: NA """ try: opts, args = getopt.getopt(sys.argv[1:], "U:D:l:t:X:", ["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])) global g_opts g_opts = CmdOptions() for key, value in opts: if (key == "-U"): g_opts.user = value elif (key == "-D"): g_opts.inputDir = True g_opts.Instancedirs.append(os.path.normpath(value)) elif (key == "-t"): g_opts.cleanType.append(value) elif (key == "-l"): g_opts.logFile = value elif (key == "-X"): g_opts.clusterConfig = value elif (key == "--help"): usage() sys.exit(0) else: GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"] % key) Parameter.checkParaVaild(key, value) def checkParameter(): """ class: check parameter """ # check if user exist and is the right user if (g_opts.user == ""): GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'U' + ".") try: ClusterUser.checkUser(g_opts.user, False) except Exception as e: GaussLog.exitWithError(str(e)) if (os.getuid() == 0 and g_opts.clusterConfig is None): GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'X' + ".") if (len(g_opts.cleanType) == 0): g_opts.cleanType = [TYPE_DATADIR, TYPE_LOCKFILE] if (g_opts.logFile == ""): g_opts.logFile = ClusterLog.getOMLogPath( ClusterConstants.LOCAL_LOG_FILE, g_opts.user, "", "") class CleanInstance(LocalBaseOM): """ class: cleanInstance """ def __init__(self, logFile, user, clusterConf, dwsMode=False): """ function: Constructor input : logFile, user, clusterConf, dwsMode output: NA """ LocalBaseOM.__init__(self, logFile, user, clusterConf, dwsMode) if (self.clusterConfig == ""): # Read config from static config file self.readConfigInfo() elif self.clusterConfig.endswith("json"): self.readConfigInfoByJson() else: self.readConfigInfoByXML() # get user info self.getUserInfo() if (user != "" and self.user != user.strip()): self.logger.debug("User parameter : %s." % user) raise Exception(ErrorCode.GAUSS_503["GAUSS_50315"] % (self.user, self.clusterInfo.appPath)) # init every component self.initComponent() ########################################################################## # This is the main clean instance flow. ########################################################################## def cleanInstance(self): """ function: Clean node instances. 1.get the data dirs, tablespaces, soketfiles 2.use theard delete the dirs or files input : NA output: NA """ self.logger.log("Cleaning instance.") compent_list = [[cm_inst] for cm_inst in self.cmCons if not ((g_opts.inputDir) and (cm_inst.instInfo.datadir not in g_opts.Instancedirs) and (cm_inst.instInfo.ssdDir not in g_opts.Instancedirs))] for compent in self.dnCons: if ((g_opts.inputDir) and (compent.instInfo.datadir not in g_opts.Instancedirs) and (compent.instInfo.ssdDir not in g_opts.Instancedirs)): continue peerInsts = self.clusterInfo.getPeerInstance(compent.instInfo) nodename = ClusterInstanceConfig. \ setReplConninfoForSinglePrimaryMultiStandbyCluster( compent.instInfo, peerInsts, self.clusterInfo)[1] com_list = list() com_list.append(compent) com_list.append(nodename) compent_list.append(com_list) if compent_list: try: self.logger.debug("Deleting instances.") parallelTool.parallelExecute(self.uninstallCompent, compent_list) except Exception as e: raise Exception(str(e)) self.logger.log("Successfully cleaned instances.") self.logger.log("Successfully cleaned instance information.") def uninstallCompent(self, compentEle=None): """ function: uninstall compent input: NA output: NA """ if compentEle is None: compentEle = [] if len(compentEle) == 1: compentEle[0].uninstall() if len(compentEle) == 2: compentEle[0].uninstall(compentEle[1]) if __name__ == '__main__': ########################################################################## # clean instance ########################################################################## """ function: Do clean instance 1.get the clusterinfo and daNodeInfo 2.check the user and group 3.clean the instance input : NA output: NA """ try: # parse and check input parameters parseCommandLine() checkParameter() # Initialize globals parameters cleanInst = CleanInstance(g_opts.logFile, g_opts.user, g_opts.clusterConfig) cleanInst.cleanInstance() except Exception as e: GaussLog.exitWithError(str(e)) sys.exit(0)