304 lines
12 KiB
Python
304 lines
12 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_install is a utility to deploy a Gauss200 server.
|
|
#############################################################################
|
|
|
|
import os
|
|
import sys
|
|
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)
|
|
|
|
sys.path.append(sys.path[0])
|
|
from gspylib.common.GaussLog import GaussLog
|
|
from gspylib.common.Common import DefaultValue, ClusterCommand
|
|
from gspylib.common.ParallelBaseOM import ParallelBaseOM
|
|
from gspylib.common.ErrorCode import ErrorCode
|
|
from gspylib.common.ParameterParsecheck import Parameter
|
|
from impl.install.OLAP.InstallImplOLAP import InstallImplOLAP
|
|
from domain_utils.cluster_file.cluster_config_file import ClusterConfigFile
|
|
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 base_utils.os.user_util import UserUtil
|
|
from domain_utils.domain_common.cluster_constants import ClusterConstants
|
|
# exit code
|
|
EXEC_SUCCESS = 0
|
|
ROLLBACK_FAILED = 3
|
|
|
|
|
|
class Install(ParallelBaseOM):
|
|
"""
|
|
The class is used to do perform installation
|
|
"""
|
|
|
|
def __init__(self):
|
|
"""
|
|
function: initialize the parameters
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
ParallelBaseOM.__init__(self)
|
|
self.time_out = None
|
|
self.alarm_component = ""
|
|
self.dbInitParam = []
|
|
self.dataGucParam = []
|
|
self.cm_server_guc_param = []
|
|
self.action = "gs_install"
|
|
self.initStep = "Init Install"
|
|
|
|
def usage(self):
|
|
"""
|
|
gs_install is a utility to deploy a cluster server.
|
|
|
|
Usage:
|
|
gs_install -? | --help
|
|
gs_install -V | --version
|
|
gs_install -X XMLFILE [--gsinit-parameter="PARAMETER" [...]]
|
|
[--dn-guc="PARAMETER" [...]] [--alarm-component=ALARMCOMPONENT]
|
|
[--time-out=SECS] [-l LOGFILE]
|
|
|
|
General options:
|
|
-X Path of the XML configuration file.
|
|
-l Path of log file.
|
|
-?, --help Show help information for this utility, and exit the command line mode.
|
|
-V, --version Show version information.
|
|
|
|
--gsinit-parameter="PARAMETER" Parameters to initialize DN and CN.
|
|
For more information, see \"gs_initdb --help\".
|
|
--dn-guc="PARAMETER" Parameters to set the configuration of DN.
|
|
For more information, see \"gs_guc --help\".
|
|
--alarm-component=ALARMCOMPONENT Path of the alarm component.
|
|
--time-out=SECS Maximum waiting time when start cluster.
|
|
"""
|
|
print(self.usage.__doc__)
|
|
|
|
def initGlobals(self):
|
|
"""
|
|
function: Init logger
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
try:
|
|
self.initLogger(self.action)
|
|
self.logger.debug(
|
|
"gs_install execution takes %s steps in total" % ClusterCommand.countTotalSteps(
|
|
self.action, "", self.readOperateStep()))
|
|
self.logger.log("Parsing the configuration file.", "addStep")
|
|
# parsing the configuration file, Parameter [refreshCN] does not refresh the CN number
|
|
self.initClusterInfo(refreshCN=False)
|
|
self.initComponent()
|
|
# Initialize self.sshTool
|
|
self.initSshTool(self.clusterInfo.getClusterNodeNames(),
|
|
DefaultValue.TIMEOUT_PSSH_INSTALL)
|
|
if (len(self.clusterInfo.getClusterNodeNames()) == 1 and
|
|
self.clusterInfo.getClusterNodeNames()[0]
|
|
== NetUtil.GetHostIpOrName()):
|
|
self.isSingle = True
|
|
self.localMode = True
|
|
except Exception as e:
|
|
# failed to parse cluster config file
|
|
raise Exception(str(e))
|
|
# Successfully parsed the configuration file
|
|
self.logger.debug("Successfully parsed the configuration file.",
|
|
"constant")
|
|
|
|
def checkParaList(self, specialStr):
|
|
"""
|
|
function:
|
|
input:
|
|
output:
|
|
"""
|
|
VALUE_CHECK_LIST = ["|", ";", "&", "$", "<", ">", "`", "\\", "{", "}",
|
|
"(", ")", "[", "]", "~", "*", "?", "!", "\n"]
|
|
VALUE_CHECK_GUC_PARA_LIST = ["client_encoding", "--encoding"]
|
|
VALUE_CHECK_ENCODING_LIST = ["LATIN5", "ISO_8859_7", "KOI8U",
|
|
"LATIN7", "EUC_TW", "WIN1251", "LATIN8",
|
|
"KOI8R", "UTF8",
|
|
"ISO_8859_5", "ISO_8859_8", "LATIN9",
|
|
"LATIN6", "EUC_JP", "EUC_KR", "WIN1255",
|
|
"EUC_CN",
|
|
"LATIN3", "LATIN1", "ISO_8859_6", "GBK"]
|
|
gs_checkStr = specialStr[0]
|
|
if (gs_checkStr.strip() == ""):
|
|
return
|
|
for rac in VALUE_CHECK_LIST:
|
|
flag = gs_checkStr.find(rac)
|
|
if flag >= 0:
|
|
raise Exception(ErrorCode.GAUSS_502["GAUSS_50219"]
|
|
% specialStr + " There are illegal "
|
|
"characters in the parameter.")
|
|
if (len(gs_checkStr.split("=")) != 2):
|
|
return
|
|
if (gs_checkStr.split("=")[1].strip().startswith("\'") is True and
|
|
gs_checkStr.split("=")[1].strip().endswith("\'") is False) or \
|
|
(gs_checkStr.split("=")[1].strip().startswith("\'") is False
|
|
and gs_checkStr.split("=")[1].strip().endswith(
|
|
"\'") is True):
|
|
raise Exception(
|
|
ErrorCode.GAUSS_502["GAUSS_50219"]
|
|
% specialStr + " Lack of Paired Single "
|
|
"Quotation Marks.value %s" % gs_checkStr)
|
|
if (gs_checkStr.split("=")[1].strip().startswith("\"") is True and
|
|
gs_checkStr.split("=")[1].strip().endswith("\"") is False) \
|
|
or (
|
|
gs_checkStr.split("=")[1].strip().startswith("\"") is False
|
|
and gs_checkStr.split("=")[1].strip().endswith("\"") is True):
|
|
raise Exception(
|
|
ErrorCode.GAUSS_502["GAUSS_50219"] % specialStr
|
|
+ " Lack of double quotation marks.value %s" % gs_checkStr)
|
|
if gs_checkStr.split("=")[0].strip() in VALUE_CHECK_GUC_PARA_LIST and \
|
|
(gs_checkStr.split("=")[1].strip().strip("\'").strip(
|
|
"\"").strip() not in VALUE_CHECK_ENCODING_LIST):
|
|
raise Exception(
|
|
ErrorCode.GAUSS_500["GAUSS_50011"] % (
|
|
gs_checkStr.split("=")[0],
|
|
gs_checkStr.split("=")[1].strip("\'").strip("\"").strip())
|
|
+ "Please cheak parameter '--dn-guc' or '--gsinit-parameter'.")
|
|
|
|
def parseCommandLine(self):
|
|
"""
|
|
function: Parse command line and save to global variable
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
# init the ParaObj
|
|
ParaObj = Parameter()
|
|
ParaDict = ParaObj.ParameterCommandLine("install")
|
|
# parameter -h or -?
|
|
if (ParaDict.__contains__("helpFlag")):
|
|
self.usage()
|
|
sys.exit(EXEC_SUCCESS)
|
|
|
|
# parameter -X
|
|
if (ParaDict.__contains__("confFile")):
|
|
self.xmlFile = ParaDict.get("confFile")
|
|
# parameter -l
|
|
if (ParaDict.__contains__("logFile")):
|
|
self.logFile = ParaDict.get("logFile")
|
|
# parameter --gsinit-parameter
|
|
if (ParaDict.__contains__("dbInitParams")):
|
|
self.dbInitParam = ParaDict.get("dbInitParams")
|
|
self.checkParaList(self.dbInitParam)
|
|
# parameter --cmserver-guc
|
|
if "cmServerGucParams" in ParaDict:
|
|
self.cm_server_guc_param = ParaDict.get("cmServerGucParams")
|
|
self.checkParaList(self.cm_server_guc_param)
|
|
# parameter --dn-guc
|
|
if (ParaDict.__contains__("dataGucParams")):
|
|
self.dataGucParam = ParaDict.get("dataGucParams")
|
|
self.checkParaList(self.dataGucParam)
|
|
# parameter --alarm-component
|
|
if (ParaDict.__contains__("alarm_component")):
|
|
self.alarm_component = ParaDict.get("alarm_component")
|
|
# parameter --time-out
|
|
if (ParaDict.__contains__("time_out")):
|
|
self.time_out = ParaDict.get("time_out")
|
|
|
|
def checkUser(self):
|
|
"""
|
|
"""
|
|
# get user info
|
|
self.user = UserUtil.getUserInfo()['name']
|
|
# get the group info
|
|
self.group = UserUtil.getUserInfo()['g_name']
|
|
# check the user and group
|
|
if (self.user == "" or self.group == ""):
|
|
raise Exception(ErrorCode.GAUSS_503["GAUSS_50308"])
|
|
if (self.user == "root" or self.group == "root"):
|
|
raise Exception(ErrorCode.GAUSS_501["GAUSS_50105"])
|
|
|
|
|
|
def checkDNPara(self):
|
|
"""
|
|
"""
|
|
dnUnsupportedParameters = DefaultValue.findUnsupportedParameters(
|
|
self.dataGucParam)
|
|
if (len(dnUnsupportedParameters) != 0):
|
|
GaussLog.printMessage("The following parameters set for database node will"
|
|
" not take effect:\n%s"
|
|
% str(dnUnsupportedParameters))
|
|
for param in dnUnsupportedParameters:
|
|
self.dataGucParam.remove(param)
|
|
|
|
def checkAlarm(self):
|
|
"""
|
|
"""
|
|
if (self.alarm_component == ""):
|
|
self.alarm_component = DefaultValue.ALARM_COMPONENT_PATH
|
|
if (not os.path.isabs(self.alarm_component)):
|
|
raise Exception(
|
|
ErrorCode.GAUSS_502["GAUSS_50213"] % "alarm component")
|
|
|
|
|
|
def checkParameter(self):
|
|
"""
|
|
function: Check parameter from command line
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
# check required parameters
|
|
self.checkUser()
|
|
# check mpprc file path
|
|
self.mpprcFile = EnvUtil.getMpprcFile()
|
|
# check config file
|
|
ClusterConfigFile.checkConfigFile(self.xmlFile)
|
|
# check unsupported -D parameter
|
|
self.checkDNPara()
|
|
# check alarm component
|
|
self.checkAlarm()
|
|
# check logFile
|
|
self.logFile = ClusterLog.checkLogFile(self.logFile, self.user, self.xmlFile,
|
|
ClusterConstants.DEPLOY_LOG_FILE)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
"""
|
|
main function
|
|
"""
|
|
# check if user is root
|
|
if (os.getuid() == 0):
|
|
GaussLog.exitWithError(ErrorCode.GAUSS_501["GAUSS_50105"])
|
|
try:
|
|
REPEAT = False
|
|
# Objectize class
|
|
install = Install()
|
|
# Initialize self and Parse command line and save to global variable
|
|
install.parseCommandLine()
|
|
# check the parameters is not OK
|
|
install.checkParameter()
|
|
# Initialize globals parameters
|
|
install.initGlobals()
|
|
# set action flag file
|
|
DefaultValue.setActionFlagFile("gs_install")
|
|
|
|
impl = InstallImplOLAP(install)
|
|
# Perform the whole install process
|
|
impl.run()
|
|
except Exception as e:
|
|
GaussLog.exitWithError(str(e))
|
|
finally:
|
|
DefaultValue.setActionFlagFile("gs_install", False)
|