Files
openGauss-OM/script/gs_postuninstall
coolany eae422baf3 适配CM组件
Signed-off-by: coolany <kyosang@163.com>

support cgroup

追加合入
2022-03-05 18:51:52 +08:00

390 lines
15 KiB
Python

#!/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 : gs_postuninstall is a utility to clean up the environment
# after uninstalling a Gauss200 server.
#############################################################################
import os, sys
import subprocess
import grp
import pwd
package_path = os.path.dirname(os.path.realpath(__file__))
ld_path = package_path + "/gspylib/clib"
if 'LD_LIBRARY_PATH' not in os.environ:
os.environ['LD_LIBRARY_PATH'] = ld_path
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
if not os.environ.get('LD_LIBRARY_PATH').startswith(ld_path):
os.environ['LD_LIBRARY_PATH'] = \
ld_path + ":" + os.environ['LD_LIBRARY_PATH']
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
from gspylib.common.GaussLog import GaussLog
from gspylib.common.Common import DefaultValue
from gspylib.common.ErrorCode import ErrorCode
from gspylib.common.ParallelBaseOM import ParallelBaseOM
from gspylib.common.ParameterParsecheck import Parameter
from impl.postuninstall.OLAP.PostUninstallImplOLAP import \
PostUninstallImplOLAP
from domain_utils.cluster_file.cluster_config_file import ClusterConfigFile
from domain_utils.cluster_file.cluster_dir import ClusterDir
from domain_utils.cluster_file.cluster_log import ClusterLog
from base_utils.os.env_util import EnvUtil
from base_utils.os.net_util import NetUtil
from domain_utils.domain_common.cluster_constants import ClusterConstants
from os_platform.linux_distro import LinuxDistro
from domain_utils.cluster_os.cluster_user import ClusterUser
class Postuninstall(ParallelBaseOM):
"""
init the command options
input : NA
output: NA
"""
def __init__(self):
"""
function: init parameters
input : NA
output: NA
"""
ParallelBaseOM.__init__(self)
self.deleteUser = False
self.deleteGroup = False
self.clean_gphome = False
self.clean_host = []
self.sshpwd = ""
self.nodeList = []
self.clusterToolPath = ""
self.userHome = ""
self.rootPasswd = ""
self.ips = []
self.root_ssh_agent_flag = False
def usage(self):
"""
gs_postuninstall is a utility to clean up the environment
after uninstalling the cluster.
Usage:
gs_postuninstall -? |--help
gs_postuninstall -V |--version
gs_postuninstall -U USER -X XMLFILE [-L] [--delete-user] [--delete-group]
[-l LOGFILE]
General options:
-U Cluster user.
-X Path of the XML configuration file.
-L Only clean up local nodes.
--delete-user Delete the OS user.
--delete-group Delete the group of the OS user.
-l Path of log file.
-?, --help Show help information for this utility,
and exit the command line mode.
-V, --version Show version information.
"""
print(self.usage.__doc__)
def parseCommandLine(self):
"""
function: Parse command line and save to global variable
input : NA
output: NA
"""
ParaObj = Parameter()
ParaDict = ParaObj.ParameterCommandLine("postuninstall")
# check if has '--help' parameter
if (ParaDict.__contains__("helpFlag")):
self.usage()
sys.exit(0)
# check the parameters of postuninstall command
if (ParaDict.__contains__("user")):
self.user = ParaDict.get("user")
if (ParaDict.__contains__("confFile")):
self.xmlFile = ParaDict.get("confFile")
if (ParaDict.__contains__("logFile")):
self.logFile = ParaDict.get("logFile")
if (ParaDict.__contains__("delete-user")):
self.deleteUser = ParaDict.get("delete-user")
if (ParaDict.__contains__("delete-group")):
self.deleteGroup = ParaDict.get("delete-group")
if (ParaDict.__contains__("clean-gphome")):
self.clean_gphome = ParaDict.get("clean-gphome")
if (ParaDict.__contains__("nodename")):
if not "HOST_IP" in os.environ.keys():
GaussLog.exitWithError(
ErrorCode.GAUSS_518["GAUSS_51801"] % "HOST_IP doesn't" +
" so -h parameter is not needed.")
self.clean_host = ParaDict.get("nodename")
if len(self.clean_host) == 0:
raise Exception(ErrorCode.GAUSS_500["GAUSS_50004"] % 'h')
if (ParaDict.__contains__("localMode")):
self.localMode = ParaDict.get("localMode")
if "HOST_IP" in os.environ.keys():
if not ParaDict.__contains__("localMode"):
if not (ParaDict.__contains__("clean-gphome")
and ParaDict.__contains__("nodename")):
GaussLog.exitWithError(
ErrorCode.GAUSS_518["GAUSS_51801"] % "HOST_IP" +
" so you must specify the -L parameter or (-h and "
"--clean-gphome) parameters.")
if ParaDict.__contains__("clean-gphome"):
if ParaDict.__contains__("localMode") and\
ParaDict.__contains__("nodename"):
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50005"]
% ("-L", "-h"))
if (self.deleteGroup == True and self.deleteUser != True):
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"]
% "-delete-user" + ".")
def checkParameter(self):
"""
function: check parameter
input : NA
output: NA
"""
# check user
self.checkUser()
# check config file
ClusterConfigFile.checkConfigFile(self.xmlFile)
# check log file
self.logFile = ClusterLog.checkLogFile(self.logFile, self.user, self.xmlFile,
ClusterConstants.UNPREINSTALL_LOG_FILE)
# check mpprc file if needed, should be done
# before check preinstall step
self.checkMpprcFile()
# check preInstall
self.checkPreInstall()
# check group for redhat
self.checkGroup()
def checkUser(self):
"""
function: check the user
input : NA
output: NA
"""
# check if no user
if (self.user == ""):
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % "U"
+ ".")
# check if is root user
if (self.user == "root"):
GaussLog.exitWithError(ErrorCode.GAUSS_503["GAUSS_50301"])
try:
ClusterUser.checkUser(self.user, False)
except Exception as e:
GaussLog.exitWithError(str(e))
if (pwd.getpwnam(self.user).pw_uid == 0):
GaussLog.exitWithError(ErrorCode.GAUSS_503["GAUSS_50302"])
def checkMpprcFile(self):
"""
function: check MpprcFile
input : NA
output: NA
"""
# get path of MpprcFile
self.mpprcFile = EnvUtil.getEnv(DefaultValue.MPPRC_FILE_ENV)
try:
# get tool path
self.clusterToolPath = ClusterDir.getPreClusterToolPath(self.xmlFile)
except Exception as e:
GaussLog.exitWithError(str(e))
# if MpprcFile is null
if (self.mpprcFile == None):
self.mpprcFile = ""
# if MpprcFile is not null
if (self.mpprcFile != ""):
# if no MpprcFile
if (not os.path.exists(self.mpprcFile)):
GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50201"]
% "MPPRC file" + " %s."
% self.mpprcFile)
# if is not absolute path
if (not os.path.isabs(self.mpprcFile)):
GaussLog.exitWithError(ErrorCode.GAUSS_512["GAUSS_51206"]
% self.mpprcFile)
def checkPreInstall(self):
"""
function: check preInstall
input : NA
output: NA
"""
# check if agent-mode
if "HOST_IP" in os.environ.keys():
# get om_agent path
agent_path_cmd = "ps aux | grep 'om_agent.py' | grep %s | grep " \
"-v grep | head -n 1 | awk '{print $NF}'" % \
self.user
(status, output) = subprocess.getstatusoutput(agent_path_cmd)
if (status != 0):
raise Exception(ErrorCode.GAUSS_535["GAUSS_53507"]
% agent_path_cmd)
agent_path = os.path.dirname(output.strip())
agent_conf_file = os.path.join(agent_path, 'om_agent.conf')
if not os.path.exists(agent_conf_file):
raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"]
% agent_conf_file)
# get agent sep_env_file
with open(agent_conf_file) as fp:
recordLines = fp.readlines()
sep_env_file = ""
for tmp in recordLines:
if 'sep_env_file' in tmp:
sep_env_file = tmp.split("=")[-1].strip()
if not os.path.exists(sep_env_file):
raise Exception(
ErrorCode.GAUSS_502["GAUSS_50201"] % sep_env_file)
cmd = "su - %s -c 'source %s && echo $GAUSS_ENV' 2>/dev/null"\
% (self.user, sep_env_file)
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
GaussLog.exitWithError(ErrorCode.GAUSS_518["GAUSS_51802"]
% "$GAUSS_ENV" + "Error: \n%s." % output
+ "The cmd is %s" % cmd)
gaussEnv = output.strip()
else:
# check if has mpprcFile
if (self.mpprcFile != ""):
userprofile = self.mpprcFile
else:
userprofile = "/home/%s/.bashrc" % self.user
cmd = "su - %s -c 'source %s && echo $GAUSS_ENV' 2>/dev/null"\
% (self.user, userprofile)
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
GaussLog.exitWithError(ErrorCode.GAUSS_518["GAUSS_51802"]
% "$GAUSS_ENV" + "Error: \n%s." % output
+ "The cmd is %s" % cmd)
gaussEnv = output.strip()
# if gaussEnv is 2, user do not do uninstall before
if (str(gaussEnv) == "2"):
GaussLog.exitWithError(ErrorCode.GAUSS_525["GAUSS_52501"]
% "gs_uninstall")
# if gaussEnv is not 1, user do not do preinstall before
elif (str(gaussEnv) != "1" and not self.clean_gphome):
GaussLog.exitWithError(
ErrorCode.GAUSS_525["GAUSS_52501"] % "gs_preinstall" +
"If you do preinstall with seperate file mode, please input "
"sep-env-file before postuninstall. ")
elif (str(gaussEnv) == "1" or str(gaussEnv) == "2")\
and self.clean_gphome:
GaussLog.exitWithError(ErrorCode.GAUSS_525["GAUSS_52501"]
% "'gs_uninstall' or 'gs_postuninstall"
" no clean gphome'")
def checkGroup(self):
"""
function: check user group
input : NA
output: NA
"""
try:
# get user group
group = grp.getgrgid(pwd.getpwnam(self.user).pw_gid).gr_name
distname, version, idnum = LinuxDistro.linux_distribution()
# check if OS version is redhat or Euler
if (distname in ("redhat", "euleros", "centos", "openEuler")):
if (self.deleteGroup != True and self.deleteUser == True
and self.user == group):
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] %
"-delete-group" + ". You must "
"delete the "
"group when you "
"delete the "
"user which has "
"the same name "
"with the group "
"in redhat.")
except Exception as e:
GaussLog.exitWithError(ErrorCode.GAUSS_503["GAUSS_50308"]
+ "Failed to obtain the group for %s" %
self.user + "Error:\n%s" % str(e))
def initGlobals(self):
"""
function: init Logg file
input : NA
output: NA
"""
self.initLogger("gs_postuninstall")
self.logger.ignoreErr = True
try:
self.logger.log("Parsing the configuration file.", "addStep")
# get cluster info from xml file
# Initialize the self.clusterInfo variable
self.initClusterInfo()
# Initialize the self.sshTool variable
self.initSshTool(self.clusterInfo.getClusterNodeNames(),
DefaultValue.TIMEOUT_PSSH_POSTPREINSTALL)
self.logger.debug("The cluster's information:\n%s."
% str(self.clusterInfo))
self.logger.log("Successfully parsed the configuration file.",
"constant")
except Exception as e:
self.logger.logExit(str(e))
dirName = os.path.dirname(self.logFile)
self.localLog = os.path.join(dirName, ClusterConstants.LOCAL_LOG_FILE)
self.userHome = DefaultValue.getUserHome(self.user)
if __name__ == '__main__':
"""
main function
input : NA
output: NA
"""
if (os.getuid() != 0):
GaussLog.exitWithError(ErrorCode.GAUSS_501["GAUSS_50104"])
try:
postuninstall = Postuninstall()
postuninstall.parseCommandLine()
postuninstall.checkParameter()
postuninstall.initGlobals()
if len(postuninstall.clusterInfo.getClusterNodeNames()) == 1 and \
postuninstall.clusterInfo.getClusterNodeNames()[
0] == NetUtil.GetHostIpOrName():
postuninstall.localMode = True
impl = PostUninstallImplOLAP(postuninstall)
# Perform the whole extand process
impl.run()
except Exception as e:
GaussLog.exitWithError(str(e))