883 lines
36 KiB
Python
883 lines
36 KiB
Python
# -*- 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.
|
|
# ----------------------------------------------------------------------------
|
|
|
|
import os
|
|
import sys
|
|
import subprocess
|
|
import grp
|
|
import pwd
|
|
import getpass
|
|
|
|
from script.base_utils.os.user_util import UserUtil
|
|
|
|
sys.path.append(sys.path[0] + "/../")
|
|
from gspylib.threads.parallelTool import parallelTool
|
|
from gspylib.common.Common import DefaultValue, ClusterCommand
|
|
from gspylib.common.OMCommand import OMCommand
|
|
from gspylib.common.ErrorCode import ErrorCode
|
|
import impl.upgrade.UpgradeConst as Const
|
|
from base_utils.executor.cmd_executor import CmdExecutor
|
|
from domain_utils.cluster_file.cluster_config_file import ClusterConfigFile
|
|
from domain_utils.cluster_file.cluster_dir import ClusterDir
|
|
from base_utils.os.file_util import FileUtil
|
|
from domain_utils.cluster_file.profile_file import ProfileFile
|
|
from domain_utils.cluster_file.version_info import VersionInfo
|
|
from base_utils.os.net_util import NetUtil
|
|
from domain_utils.domain_common.cluster_constants import ClusterConstants
|
|
from os_platform.linux_distro import LinuxDistro
|
|
|
|
sys.path.append(sys.path[0] + "/../../../lib/")
|
|
DefaultValue.doConfigForParamiko()
|
|
import paramiko
|
|
|
|
#############################################################################
|
|
# Global variables
|
|
#############################################################################
|
|
gphome = None
|
|
# system config file
|
|
PROFILE_FILE = '/etc/profile'
|
|
# pssh directory name
|
|
PSSHDIR = 'pssh-2.3.1'
|
|
# action name
|
|
ACTION_CLEAN_TOOL_ENV = "clean_tool_env"
|
|
ACTION_CHECK_UNPREINSTALL = "check_unpreinstall"
|
|
ACTION_CLEAN_GAUSS_ENV = "clean_gauss_env"
|
|
ACTION_DELETE_GROUP = "delete_group"
|
|
ACTION_CLEAN_SYSLOG_CONFIG = 'clean_syslog_config'
|
|
ACTION_CLEAN_DEPENDENCY = "clean_dependency"
|
|
|
|
|
|
class PostUninstallImpl:
|
|
"""
|
|
init the command options
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
|
|
def __init__(self, GaussPost):
|
|
"""
|
|
function: constructor
|
|
"""
|
|
pass
|
|
|
|
def checkLogFilePath(self):
|
|
"""
|
|
function: Check log file path
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
clusterPath = []
|
|
|
|
try:
|
|
self.logger.log("Check log file path.", "addStep")
|
|
# get tool path
|
|
clusterPath.append(ClusterDir.getClusterToolPath(self.user))
|
|
|
|
# get tmp path
|
|
tmpDir = DefaultValue.getTmpDir(self.user, self.xmlFile)
|
|
clusterPath.append(tmpDir)
|
|
|
|
# get cluster path
|
|
hostName = NetUtil.GetHostIpOrName()
|
|
dirs = self.clusterInfo.getClusterDirectorys(hostName, False)
|
|
for checkdir in dirs.values():
|
|
clusterPath.extend(checkdir)
|
|
|
|
self.logger.debug("Cluster paths %s." % clusterPath)
|
|
# check directory
|
|
FileUtil.checkIsInDirectory(self.logFile, clusterPath)
|
|
self.logger.log("Successfully checked log file path.", "constant")
|
|
except Exception as e:
|
|
self.logger.logExit(str(e))
|
|
|
|
##########################################################################
|
|
# Uninstall functions
|
|
##########################################################################
|
|
def doCleanEnvironment(self):
|
|
"""
|
|
function: Clean Environment
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
self.logger.debug("Do clean Environment.", "addStep")
|
|
try:
|
|
# check uninstall
|
|
self.checkUnPreInstall()
|
|
# clean app/log/data/temp dirs
|
|
self.cleanDirectory()
|
|
# clean other user
|
|
self.cleanRemoteOsUser()
|
|
# clean other nodes environment software and variable
|
|
self.cleanOtherNodesEnvSoftware()
|
|
# clean other nodes log
|
|
self.cleanOtherNodesLog()
|
|
# clean local node environment software and variable
|
|
self.cleanLocalNodeEnvSoftware()
|
|
# clean local user
|
|
self.cleanLocalOsUser()
|
|
except Exception as e:
|
|
self.logger.logExit(str(e))
|
|
self.logger.debug("Do clean Environment succeeded.", "constant")
|
|
|
|
def checkUnPreInstall(self):
|
|
"""
|
|
function: check whether do uninstall before unpreinstall
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
self.logger.log("Checking unpreinstallation.")
|
|
if not self.localMode:
|
|
ProfileFile.checkAllNodesMpprcFile(
|
|
self.clusterInfo.getClusterNodeNames(), self.mpprcFile)
|
|
|
|
cmd = "%s -t %s -u %s -l '%s' -X '%s'" % (
|
|
OMCommand.getLocalScript("Local_UnPreInstall"),
|
|
ACTION_CHECK_UNPREINSTALL,
|
|
self.user,
|
|
self.localLog,
|
|
self.xmlFile)
|
|
self.logger.debug("Command for checking unpreinstall: %s" % cmd)
|
|
# check if do postuninstall in all nodes
|
|
CmdExecutor.execCommandWithMode(cmd,
|
|
self.sshTool, self.localMode,
|
|
self.mpprcFile)
|
|
self.logger.log("Successfully checked unpreinstallation.")
|
|
|
|
def cleanDirectory(self):
|
|
"""
|
|
function: clean install/instance/temp dirs
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
# clean instance path
|
|
hostName = NetUtil.GetHostIpOrName()
|
|
dbNodeInfo = self.clusterInfo.getDbNodeByName(hostName)
|
|
instanceDirs = []
|
|
# get DB instance
|
|
for dbInst in dbNodeInfo.datanodes:
|
|
instanceDirs.append(dbInst.datadir)
|
|
if (len(dbInst.ssdDir) != 0):
|
|
instanceDirs.append(dbInst.ssdDir)
|
|
# clean all instances
|
|
if (len(instanceDirs) > 0):
|
|
if (os.path.exists(instanceDirs[0]) and len(
|
|
os.listdir(instanceDirs[0])) == 0):
|
|
self.CleanInstanceDir()
|
|
else:
|
|
self.logger.debug(
|
|
"Instance directory [%s] is not empty. "
|
|
"Skip to delete instance's directory." %
|
|
instanceDirs[0])
|
|
else:
|
|
self.logger.debug(
|
|
"Instance's directory is not been found. "
|
|
"Skip to delete instance's directory.")
|
|
|
|
# clean install path
|
|
if (os.path.exists(self.clusterInfo.appPath)):
|
|
self.logger.log("Deleting the installation directory.")
|
|
cmd = "rm -rf '%s'" % self.clusterInfo.appPath
|
|
self.logger.debug(
|
|
"Command for deleting the installation path: %s" % cmd)
|
|
CmdExecutor.execCommandWithMode(cmd,
|
|
self.sshTool, self.localMode,
|
|
self.mpprcFile)
|
|
self.logger.log("Successfully deleted the installation directory.")
|
|
|
|
# clean tmp dir
|
|
self.logger.log("Deleting the temporary directory.")
|
|
tmpDir = DefaultValue.getTmpDir(self.user, self.xmlFile)
|
|
cmd = "rm -rf '%s'; rm -rf /tmp/gs_checkos; rm -rf /tmp/gs_virtualip" \
|
|
% tmpDir
|
|
self.logger.debug(
|
|
"Command for deleting the temporary directory: %s" % cmd)
|
|
CmdExecutor.execCommandWithMode(cmd,
|
|
self.sshTool, self.localMode,
|
|
self.mpprcFile)
|
|
self.logger.log("Successfully deleted the temporary directory.")
|
|
|
|
def CleanInstanceDir(self):
|
|
"""
|
|
function: Clean instance directory
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
self.logger.log("Deleting the instance's directory.")
|
|
cmd = "%s -U %s -l '%s' -X '%s'" % (
|
|
OMCommand.getLocalScript("Local_Clean_Instance"), self.user,
|
|
self.localLog, self.xmlFile)
|
|
self.logger.debug("Command for deleting the instance: %s" % cmd)
|
|
CmdExecutor.execCommandWithMode(cmd,
|
|
self.sshTool, self.localMode,
|
|
self.mpprcFile)
|
|
|
|
# clean upgrade temp backup path
|
|
cmd = "rm -rf '%s'" % ClusterDir.getBackupDir("upgrade", self.user)
|
|
self.logger.debug(
|
|
"Command for deleting the upgrade temp backup path: %s" % cmd)
|
|
CmdExecutor.execCommandWithMode(cmd,
|
|
self.sshTool, self.localMode,
|
|
self.mpprcFile)
|
|
|
|
self.logger.log("Successfully deleted the instance's directory.")
|
|
|
|
def cleanRemoteOsUser(self):
|
|
"""
|
|
function: Clean remote os user
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
# check if local mode
|
|
if (self.localMode):
|
|
return
|
|
|
|
if (not self.deleteUser):
|
|
# clean static config file
|
|
if os.stat(os.path.dirname(self.clusterInfo.appPath)).st_uid != 0:
|
|
cmd = "rm -rf '%s'" % self.clusterInfo.appPath
|
|
CmdExecutor.execCommandWithMode(cmd,
|
|
self.sshTool, self.localMode,
|
|
self.mpprcFile)
|
|
return
|
|
|
|
group = grp.getgrgid(pwd.getpwnam(self.user).pw_gid).gr_name
|
|
|
|
# get other nodes
|
|
hostName = NetUtil.GetHostIpOrName()
|
|
otherNodes = self.clusterInfo.getClusterNodeNames()
|
|
for otherNode in otherNodes:
|
|
if (otherNode == hostName):
|
|
otherNodes.remove(otherNode)
|
|
|
|
# clean remote user
|
|
self.logger.log("Deleting remote OS user.")
|
|
cmd = "%s -U %s -l %s" % (
|
|
OMCommand.getLocalScript("Local_Clean_OsUser"), self.user,
|
|
self.localLog)
|
|
self.logger.debug("Command for deleting remote OS user: %s" % cmd)
|
|
CmdExecutor.execCommandWithMode(cmd, self.sshTool,
|
|
self.localMode, self.mpprcFile,
|
|
otherNodes)
|
|
self.logger.log("Successfully deleted remote OS user.")
|
|
|
|
if (self.deleteGroup):
|
|
# clean remote group
|
|
self.logger.debug("Deleting remote OS group.")
|
|
cmd = "%s -t %s -u %s -l '%s' -X '%s'" % (
|
|
OMCommand.getLocalScript("Local_UnPreInstall"),
|
|
ACTION_DELETE_GROUP, group, self.localLog, self.xmlFile)
|
|
self.logger.debug("Command for deleting remote OS group: %s" % cmd)
|
|
status = self.sshTool.getSshStatusOutput(cmd, otherNodes,
|
|
self.mpprcFile)[0]
|
|
outputMap = self.sshTool.parseSshOutput(otherNodes)
|
|
for node in status.keys():
|
|
if (status[node] != DefaultValue.SUCCESS):
|
|
self.logger.log((outputMap[node]).strip("\n"))
|
|
self.logger.debug("Deleting remote group is completed.")
|
|
|
|
def cleanOtherNodesEnvSoftware(self):
|
|
"""
|
|
function: clean other nodes environment software and variable
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
# check if local mode
|
|
if self.localMode:
|
|
return
|
|
self.logger.log(
|
|
"Deleting software packages "
|
|
"and environmental variables of other nodes.")
|
|
try:
|
|
# get other nodes
|
|
hostName = NetUtil.GetHostIpOrName()
|
|
otherNodes = self.clusterInfo.getClusterNodeNames()
|
|
for otherNode in otherNodes:
|
|
if (otherNode == hostName):
|
|
otherNodes.remove(otherNode)
|
|
self.logger.debug(
|
|
"Deleting environmental variables of nodes: %s." % otherNodes)
|
|
|
|
# clean $GAUSS_ENV
|
|
if (not self.deleteUser):
|
|
cmd = "%s -t %s -u %s -l '%s' -X '%s'" % (
|
|
OMCommand.getLocalScript("Local_UnPreInstall"),
|
|
ACTION_CLEAN_GAUSS_ENV,
|
|
self.user,
|
|
self.localLog,
|
|
self.xmlFile)
|
|
self.logger.debug("Command for deleting $GAUSS_ENV: %s" % cmd)
|
|
CmdExecutor.execCommandWithMode(cmd,
|
|
self.sshTool, self.localMode,
|
|
self.mpprcFile, otherNodes)
|
|
cmd = "%s -t %s -u %s -l '%s' -X '%s'" % (
|
|
OMCommand.getLocalScript("Local_UnPreInstall"),
|
|
ACTION_CLEAN_TOOL_ENV,
|
|
self.user,
|
|
self.localLog,
|
|
self.xmlFile)
|
|
self.logger.debug(
|
|
"Command for deleting environmental variables: %s" % cmd)
|
|
CmdExecutor.execCommandWithMode(cmd,
|
|
self.sshTool,
|
|
self.localMode,
|
|
self.mpprcFile,
|
|
otherNodes.append(hostName))
|
|
except Exception as e:
|
|
self.logger.logExit(str(e))
|
|
self.logger.log(
|
|
"Successfully deleted software packages "
|
|
"and environmental variables of other nodes.")
|
|
|
|
def cleanOtherNodesLog(self):
|
|
"""
|
|
function: clean other nodes log
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
# check if local mode
|
|
if self.localMode:
|
|
return
|
|
self.logger.log("Deleting logs of other nodes.")
|
|
try:
|
|
# get other nodes
|
|
hostName = NetUtil.GetHostIpOrName()
|
|
otherNodes = self.clusterInfo.getClusterNodeNames()
|
|
for otherNode in otherNodes:
|
|
if (otherNode == hostName):
|
|
otherNodes.remove(otherNode)
|
|
|
|
# clean log
|
|
if os.stat(ClusterDir.getClusterToolPath(self.user)).st_uid != 0 or \
|
|
os.stat(self.clusterInfo.logPath).st_uid != 0:
|
|
cmd = "rm -rf '%s/%s'; rm -rf /tmp/gauss_*;" % (self.clusterInfo.logPath, self.user)
|
|
python_path = "%s/Python-2.7.9" % ClusterDir.getClusterToolPath(self.user)
|
|
if DefaultValue.non_root_owner(python_path):
|
|
cmd += "rm -rf '%s/Python-2.7.9'" % ClusterDir.getClusterToolPath(self.user)
|
|
self.logger.debug("Command for deleting logs of other nodes: %s" % cmd)
|
|
CmdExecutor.execCommandWithMode(cmd,
|
|
self.sshTool,
|
|
self.localMode,
|
|
self.mpprcFile,
|
|
otherNodes)
|
|
self.logger.debug(
|
|
"Successfully deleted logs of the nodes: %s." % otherNodes)
|
|
except Exception as e:
|
|
self.logger.logExit(
|
|
ErrorCode.GAUSS_502["GAUSS_50207"] % "other nodes log"
|
|
+ " Error: \n%s." % str(e))
|
|
self.logger.log("Successfully deleted logs of other nodes.")
|
|
|
|
def cleanLocalNodeEnvSoftware(self):
|
|
"""
|
|
function: clean local node environment software and variable
|
|
input : NA
|
|
output: NA
|
|
in this function, Gauss-MPPDB* & sctp_patch is came from R5 upgrade R7
|
|
"""
|
|
self.logger.log(
|
|
"Deleting software packages "
|
|
"and environmental variables of the local node.")
|
|
try:
|
|
self.clusterToolPath = ClusterDir.getClusterToolPath(self.user)
|
|
|
|
# clean local node environment software
|
|
path = "%s/%s" % (self.clusterToolPath, PSSHDIR)
|
|
FileUtil.removeDirectory(path)
|
|
path = "%s/upgrade.sh" % self.clusterToolPath
|
|
FileUtil.removeFile(path)
|
|
path = "%s/version.cfg" % self.clusterToolPath
|
|
FileUtil.removeFile(path)
|
|
path = "%s/GaussDB.py" % self.clusterToolPath
|
|
FileUtil.removeFile(path)
|
|
path = "%s/libcgroup" % self.clusterToolPath
|
|
FileUtil.removeDirectory(path)
|
|
path = "%s/unixodbc" % self.clusterToolPath
|
|
FileUtil.removeDirectory(path)
|
|
path = "%s/server.key.cipher" % self.clusterToolPath
|
|
FileUtil.removeFile(path)
|
|
path = "%s/server.key.rand" % self.clusterToolPath
|
|
FileUtil.removeFile(path)
|
|
path = "%s/%s*" % (self.clusterToolPath, VersionInfo.PRODUCT_NAME)
|
|
FileUtil.removeDirectory(path)
|
|
path = "%s/server.key.rand" % self.clusterToolPath
|
|
FileUtil.removeFile(path)
|
|
path = "%s/Gauss*" % (self.clusterToolPath)
|
|
FileUtil.removeDirectory(path)
|
|
path = "%s/sctp_patch" % (self.clusterToolPath)
|
|
FileUtil.removeDirectory(path)
|
|
path = "%s/%s" % (self.clusterToolPath, Const.UPGRADE_SQL_FILE)
|
|
FileUtil.removeFile(path)
|
|
path = "%s/%s" % (self.clusterToolPath, Const.UPGRADE_SQL_SHA)
|
|
FileUtil.removeFile(path)
|
|
self.logger.debug(
|
|
"Deleting environmental software of local nodes.")
|
|
|
|
# clean local node environment variable
|
|
cmd = "(if [ -s '%s' ]; then " % PROFILE_FILE
|
|
cmd += "sed -i -e '/^export PATH=\$PATH:\/root\/gauss_om\/%s\/" \
|
|
"script$/d' %s " % (self.user, PROFILE_FILE)
|
|
cmd += "-e '/^export PATH=\$PATH:\$GPHOME\/script\/gspylib\/pssh\/bin:" \
|
|
"\$GPHOME\/script$/d' %s " % PROFILE_FILE
|
|
cmd += "-e '/^export LD_LIBRARY_PATH=\$GPHOME\/script\/gspylib\/clib:" \
|
|
"\$LD_LIBRARY_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 deleting environment variable: %s" % cmd)
|
|
(status, output) = subprocess.getstatusoutput(cmd)
|
|
if (status != 0):
|
|
self.logger.logExit(ErrorCode.GAUSS_502["GAUSS_50207"] %
|
|
"environment variables of the local node"
|
|
+ " Error: \n%s" % output)
|
|
# check if user profile exist
|
|
user_bashrc = ProfileFile.get_user_bashrc(self.user)
|
|
if (self.mpprcFile is not None and self.mpprcFile != ""):
|
|
userProfile = self.mpprcFile
|
|
else:
|
|
userProfile = user_bashrc
|
|
if (not os.path.exists(userProfile)):
|
|
self.logger.debug(
|
|
"The %s does not exist. "
|
|
"Please skip to clean $GAUSS_ENV." % userProfile)
|
|
return
|
|
# clean user's environmental variable
|
|
DefaultValue.cleanUserEnvVariable(userProfile,
|
|
cleanGAUSS_WARNING_TYPE=True)
|
|
if os.path.exists(user_bashrc):
|
|
FileUtil.deleteLine(user_bashrc,
|
|
"^\\s*export\\s*%s=.*$" % DefaultValue.MPPRC_FILE_ENV)
|
|
|
|
# clean $GAUSS_ENV
|
|
if (not self.deleteUser):
|
|
envContent = "^\\s*export\\s*GAUSS_ENV=.*$"
|
|
FileUtil.deleteLine(userProfile, envContent)
|
|
self.logger.debug("Command for deleting $GAUSS_ENV: %s" % cmd,
|
|
"constant")
|
|
|
|
except Exception as e:
|
|
self.logger.logExit(str(e))
|
|
self.logger.log(
|
|
"Successfully deleted software packages "
|
|
"and environmental variables of the local nodes.")
|
|
|
|
def cleanLocalOsUser(self):
|
|
"""
|
|
function: Clean local os user
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
if (not self.deleteUser):
|
|
if (self.localMode):
|
|
if os.stat(os.path.dirname(self.clusterInfo.appPath)).st_uid != 0:
|
|
cmd = "rm -rf '%s'" % self.clusterInfo.appPath
|
|
CmdExecutor.execCommandWithMode(cmd,
|
|
self.sshTool, self.localMode,
|
|
self.mpprcFile)
|
|
return
|
|
|
|
group = grp.getgrgid(pwd.getpwnam(self.user).pw_gid).gr_name
|
|
|
|
# clean local user
|
|
self.logger.log("Deleting local OS user.")
|
|
cmd = "%s -U %s -l %s" % (
|
|
OMCommand.getLocalScript("Local_Clean_OsUser"), self.user,
|
|
self.localLog)
|
|
self.logger.debug("Command for deleting local OS user: %s" % cmd)
|
|
(status, output) = subprocess.getstatusoutput(cmd)
|
|
if (status != 0):
|
|
self.logger.logExit(output)
|
|
self.logger.log("Successfully deleted local OS user.")
|
|
|
|
if (self.deleteGroup):
|
|
# clean local user group
|
|
self.logger.debug("Deleting local OS group.")
|
|
cmd = "%s -t %s -u %s -l '%s' -X '%s'" % (
|
|
OMCommand.getLocalScript("Local_UnPreInstall"),
|
|
ACTION_DELETE_GROUP,
|
|
group,
|
|
self.localLog,
|
|
self.xmlFile)
|
|
self.logger.debug("Command for deleting local OS group: %s" % cmd)
|
|
(status, output) = subprocess.getstatusoutput(cmd)
|
|
if (status != 0):
|
|
self.logger.log(output.strip())
|
|
self.logger.debug("Deleting local group is completed.")
|
|
|
|
def cleanLocalLog(self):
|
|
"""
|
|
function: Clean default log
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
self.logger.log("Deleting local node's logs.", "addStep")
|
|
try:
|
|
# clean log
|
|
path = "%s/%s" % (self.clusterInfo.logPath, self.user)
|
|
FileUtil.removeDirectory(path)
|
|
except Exception as e:
|
|
self.logger.logExit(
|
|
ErrorCode.GAUSS_502["GAUSS_50207"]
|
|
% "logs" + " Error: \n%s." % str(e))
|
|
self.logger.log("Successfully deleted local node's logs.", "constant")
|
|
|
|
def cleanMpprcFile(self):
|
|
"""
|
|
function: clean mpprc file if we are using environment seperate
|
|
version.
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
self.logger.debug("Clean mpprc file.", "addStep")
|
|
# check if mpprcfile is null
|
|
if (self.mpprcFile != ""):
|
|
try:
|
|
UserUtil.check_user_exist(self.user)
|
|
baseCmd = 'su - %s -c "rm -rf %s"' % (self.user, self.mpprcFile)
|
|
except Exception as exp:
|
|
self.logger.debug("Check user [%s] not exist. Error: %s" % (self.user, str(exp)))
|
|
baseCmd = "if [ -f %s ]; then rm -rf %s; fi" % (self.mpprcFile, self.mpprcFile)
|
|
# check if local mode
|
|
if os.stat(self.mpprcFile).st_uid != 0:
|
|
if (self.localMode):
|
|
(status, output) = subprocess.getstatusoutput(baseCmd)
|
|
if (status != 0):
|
|
self.logger.logExit(
|
|
ErrorCode.GAUSS_502["GAUSS_50207"]
|
|
% "MPPRC file"
|
|
+ " Command: %s. Error: \n%s" % (baseCmd, output))
|
|
else:
|
|
dbNodeNames = self.clusterInfo.getClusterNodeNames()
|
|
for dbNodeName in dbNodeNames:
|
|
cmd = "pssh -s -H %s '%s'" % (dbNodeName, baseCmd)
|
|
(status, output) = subprocess.getstatusoutput(cmd)
|
|
if (status != 0):
|
|
message = output.strip()
|
|
err_message = ErrorCode.GAUSS_502["GAUSS_50207"] % "MPPRC file" + \
|
|
" Command: %s. Error: \n%s" % (cmd, output)
|
|
if "Permission denied" in message:
|
|
self.logger.debug(err_message)
|
|
else:
|
|
self.logger.logExit(err_message)
|
|
self.logger.debug("Successfully cleaned mpprc file.", "constant")
|
|
|
|
def cleanScript(self):
|
|
"""
|
|
clean script directory
|
|
"""
|
|
self.logger.debug("Clean script path")
|
|
cmd = "%s -t %s -u %s -Q %s" % (
|
|
OMCommand.getLocalScript("Local_UnPreInstall"),
|
|
ACTION_CLEAN_DEPENDENCY, self.user,
|
|
self.clusterToolPath)
|
|
if self.deleteUser:
|
|
cmd += " -P %s" % self.userHome
|
|
CmdExecutor.execCommandWithMode(cmd,
|
|
self.sshTool, self.localMode,
|
|
self.mpprcFile)
|
|
self.logger.debug("Clean script path successfully.")
|
|
|
|
def cleanSyslogConfig(self):
|
|
"""
|
|
function: clean syslog config
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
try:
|
|
# only suse11/suse12 can support it
|
|
distname = LinuxDistro.linux_distribution()[0]
|
|
if (distname.upper() != "SUSE"):
|
|
return
|
|
|
|
# clean syslog-ng/rsyslog config
|
|
cmd = "%s -t %s -u %s -l '%s' -X '%s'" % (
|
|
OMCommand.getLocalScript("Local_UnPreInstall"),
|
|
ACTION_CLEAN_SYSLOG_CONFIG,
|
|
self.user,
|
|
self.localLog,
|
|
self.xmlFile)
|
|
self.logger.debug(
|
|
"Command for clean syslog-ng/rsyslog config: %s" % cmd)
|
|
CmdExecutor.execCommandWithMode(
|
|
cmd,
|
|
self.sshTool,
|
|
self.localMode,
|
|
self.mpprcFile,
|
|
self.clusterInfo.getClusterNodeNames())
|
|
except Exception as e:
|
|
self.logger.logExit(str(e))
|
|
|
|
def sshExecWithPwd(self, host):
|
|
"""
|
|
function: execute command with root password
|
|
input : host
|
|
output: NA
|
|
"""
|
|
cmd = "if [ $(stat -c \"%s\" %s) == 0 ];then echo 'OKOKOK';" \
|
|
"else rm -rf %s/* && echo 'OKOKOK';fi" % ("%u", gphome, gphome)
|
|
ssh = paramiko.SSHClient()
|
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
ssh.connect(host, 22, "root", self.sshpwd)
|
|
stdin, stdout, stderr = ssh.exec_command(cmd)
|
|
output = stdout.read()
|
|
self.logger.debug("%s: %s" % (str(host), str(output)))
|
|
if output.find('OKOKOK') < 0:
|
|
raise Exception(
|
|
ErrorCode.GAUSS_514["GAUSS_51400"]
|
|
% cmd + "host: %s. Error:\n%s"
|
|
% (host, output))
|
|
|
|
def verifyCleanGphome(self, localMode=True):
|
|
"""
|
|
function: verify clean gphome and get root password
|
|
input : localMode
|
|
output: str
|
|
"""
|
|
sshpwd = ""
|
|
flag = input(
|
|
"Are you sure you want to clean gphome[%s] (yes/no)? " % gphome)
|
|
while (True):
|
|
if (
|
|
flag.upper() != "YES"
|
|
and flag.upper() != "NO"
|
|
and flag.upper() != "Y" and flag.upper() != "N"):
|
|
flag = input("Please type 'yes' or 'no': ")
|
|
continue
|
|
break
|
|
if (flag.upper() == "NO" or flag.upper() == "N"):
|
|
sys.exit(0)
|
|
if "HOST_IP" in os.environ.keys() and not localMode:
|
|
sshpwd = getpass.getpass("Please enter password for root:")
|
|
sshpwd_check = getpass.getpass("Please repeat password for root:")
|
|
if sshpwd_check != sshpwd:
|
|
sshpwd_check = ""
|
|
sshpwd = ""
|
|
raise Exception(ErrorCode.GAUSS_503["GAUSS_50306"] % "root")
|
|
sshpwd_check = ""
|
|
return sshpwd
|
|
|
|
def checkAuthentication(self, hostname):
|
|
"""
|
|
function: Ensure the proper password-less access to the remote host.
|
|
input : hostname
|
|
output: True/False, hostname
|
|
"""
|
|
cmd = 'ssh -n %s %s true' % (DefaultValue.SSH_OPTION, hostname)
|
|
(status, output) = subprocess.getstatusoutput(cmd)
|
|
if (status != 0):
|
|
self.logger.debug("The cmd is %s " % cmd)
|
|
self.logger.debug(
|
|
"Failed to check authentication. Hostname:%s. Error: \n%s" % (
|
|
hostname, output))
|
|
return (False, hostname)
|
|
return (True, hostname)
|
|
|
|
def getItemValueFromXml(self, itemName):
|
|
"""
|
|
function: Get item from xml tag CLUSTER.
|
|
input : hostname
|
|
output: True/False, hostname
|
|
"""
|
|
(retStatus, retValue) = ClusterConfigFile.readOneClusterConfigItem(
|
|
ClusterConfigFile.initParserXMLFile(self.xmlFile), itemName, "cluster")
|
|
if (retStatus != 0):
|
|
raise Exception(
|
|
ErrorCode.GAUSS_502["GAUSS_50204"]
|
|
% itemName + " Error: \n%s" % retValue)
|
|
return retValue
|
|
|
|
def cleanGphomeScript(self):
|
|
"""
|
|
function: clean gphome script
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
try:
|
|
if not self.clean_gphome:
|
|
return
|
|
global gphome
|
|
gphome = os.path.normpath(
|
|
self.getItemValueFromXml("gaussdbToolPath"))
|
|
cmd = "rm -rf %s/*" % gphome
|
|
if "HOST_IP" in os.environ.keys():
|
|
# Agent Mode
|
|
if self.localMode:
|
|
# clean gphome in local mode
|
|
self.verifyCleanGphome()
|
|
(status, output) = subprocess.getstatusoutput(cmd)
|
|
if status != 0:
|
|
raise Exception(
|
|
ErrorCode.GAUSS_514["GAUSS_51400"]
|
|
% cmd + " Error:\n%s" % output)
|
|
self.logger.logExit("Successfully clean gphome locally.")
|
|
else:
|
|
# clean gphome with specified node
|
|
self.sshpwd = self.verifyCleanGphome(self.localMode)
|
|
parallelTool.parallelExecute(self.sshExecWithPwd,
|
|
self.clean_host)
|
|
self.logger.logExit(
|
|
"Successfully clean gphome on node %s."
|
|
% self.clean_host)
|
|
|
|
else:
|
|
# SSH Mode
|
|
SSH_TRUST = True
|
|
self.nodeList = self.getItemValueFromXml("nodeNames").split(
|
|
",")
|
|
if len(self.nodeList) == 0:
|
|
raise Exception(
|
|
ErrorCode.GAUSS_502["GAUSS_50203"] % "nodeList")
|
|
results = parallelTool.parallelExecute(
|
|
self.checkAuthentication, self.nodeList)
|
|
for (key, value) in results:
|
|
if (not key):
|
|
self.logger.log("SSH trust has not been created. \
|
|
\nFor node : %s. Only clean local node." % value,
|
|
"constant")
|
|
SSH_TRUST = False
|
|
break
|
|
if SSH_TRUST and not self.localMode:
|
|
# SSH trust has been created
|
|
self.verifyCleanGphome()
|
|
parallelTool.parallelExecute(self.sshExecWithPwd,
|
|
self.nodeList)
|
|
if not SSH_TRUST or self.localMode:
|
|
# SSH trust has not been created
|
|
# which means clean gphome locally
|
|
self.verifyCleanGphome()
|
|
if os.stat(gphome).st_uid != 0:
|
|
(status, output) = subprocess.getstatusoutput(cmd)
|
|
if status != 0:
|
|
raise Exception(
|
|
ErrorCode.GAUSS_514["GAUSS_51400"]
|
|
% cmd + " Error:\n%s" % output)
|
|
self.logger.logExit("Successfully clean gphome.")
|
|
|
|
except Exception as e:
|
|
self.logger.logExit(str(e))
|
|
|
|
def createTrustForRoot(self):
|
|
"""
|
|
:return:
|
|
"""
|
|
if self.localMode or self.isSingle:
|
|
return
|
|
try:
|
|
# save the sshIps
|
|
Ips = []
|
|
# create trust for root
|
|
# get the user name
|
|
username = pwd.getpwuid(os.getuid()).pw_name
|
|
# get the user sshIps
|
|
sshIps = self.clusterInfo.getClusterSshIps()
|
|
# save the sshIps to Ips
|
|
for ips in sshIps:
|
|
Ips.extend(ips)
|
|
|
|
self.logger.log("Creating SSH trust for the root permission user.")
|
|
# Ask to create trust for root
|
|
flag = input("Are you sure you want to create trust for root (yes/no)?")
|
|
while True:
|
|
# If it is not yes or no, it has been imported
|
|
# if it is yes or no, it has been break
|
|
if flag.upper() not in ("YES", "NO", "Y", "N"):
|
|
flag = input("Please type 'yes' or 'no': ")
|
|
continue
|
|
break
|
|
|
|
# Receives the entered password
|
|
if flag.upper() in ("NO", "N"):
|
|
return
|
|
|
|
self.logger.log("Please enter password for root.")
|
|
retry_times = 0
|
|
while True:
|
|
try:
|
|
self.sshTool.createTrust(username, Ips, self.mpprcFile)
|
|
break
|
|
except Exception as err_msg:
|
|
if retry_times == 2:
|
|
raise Exception(str(err_msg))
|
|
if "Authentication failed" in str(err_msg):
|
|
self.logger.log("Password authentication failed, please try again.")
|
|
retry_times += 1
|
|
else:
|
|
raise Exception(str(err_msg))
|
|
FileUtil.changeMode(DefaultValue.HOSTS_FILE, "/etc/hosts", False,
|
|
"shell", retry_flag=True)
|
|
self.logger.log("Successfully created SSH trust for the root permission user.")
|
|
self.root_ssh_agent_flag = True
|
|
except Exception as e:
|
|
raise Exception(str(e))
|
|
|
|
def delet_root_mutual_trust(self):
|
|
"""
|
|
:return:
|
|
"""
|
|
if self.localMode or self.isSingle:
|
|
return
|
|
if not self.root_ssh_agent_flag:
|
|
return
|
|
self.logger.debug("Start Delete root mutual trust")
|
|
|
|
username = pwd.getpwuid(os.getuid()).pw_name
|
|
# get dir path
|
|
homeDir = os.path.expanduser("~" + username)
|
|
sshDir = "%s/.ssh/*" % homeDir
|
|
tmp_path = "%s/gaussdb_tmp" % homeDir
|
|
|
|
# get cmd
|
|
bashrc_file = os.path.join(pwd.getpwuid(os.getuid()).pw_dir, ".bashrc")
|
|
kill_ssh_agent_cmd = "ps ux | grep 'ssh-agent' | grep -v grep | awk '{print $2}' | " \
|
|
"xargs kill -9"
|
|
delete_line_cmd = " && sed -i '/^\\s*export\\s*SSH_AUTH_SOCK=.*$/d' %s" % bashrc_file
|
|
delete_line_cmd += " && sed -i '/^\\s*export\\s*SSH_AGENT_PID=.*$/d' %s" % bashrc_file
|
|
delete_shell_cmd = " && rm -rf %s && rm -rf %s" % (sshDir, tmp_path)
|
|
cmd = "%s" + delete_line_cmd + delete_shell_cmd
|
|
|
|
# get remote node and local node
|
|
host_list = self.clusterInfo.getClusterNodeNames()
|
|
local_host = NetUtil.GetHostIpOrName()
|
|
host_list.remove(local_host)
|
|
|
|
# delete remote root mutual trust
|
|
kill_remote_ssh_agent_cmd = DefaultValue.killInstProcessCmd("ssh-agent", True)
|
|
self.sshTool.getSshStatusOutput(cmd % kill_remote_ssh_agent_cmd, host_list)
|
|
# delete local root mutual trust
|
|
CmdExecutor.execCommandLocally(cmd % kill_ssh_agent_cmd)
|
|
self.logger.debug("Delete root mutual trust successfully.")
|
|
|
|
def run(self):
|
|
try:
|
|
self.logger.debug(
|
|
"gs_postuninstall execution takes %s steps in total"
|
|
% ClusterCommand.countTotalSteps("gs_postuninstall"))
|
|
self.createTrustForRoot()
|
|
self.cleanGphomeScript()
|
|
self.checkLogFilePath()
|
|
self.cleanSyslogConfig()
|
|
self.doCleanEnvironment()
|
|
self.logger.closeLog()
|
|
self.cleanLocalLog()
|
|
self.cleanMpprcFile()
|
|
self.cleanScript()
|
|
self.delet_root_mutual_trust()
|
|
self.logger.log("Successfully cleaned environment.")
|
|
except Exception as e:
|
|
self.logger.logExit(str(e))
|
|
sys.exit(0)
|