232 lines
7.3 KiB
Python
232 lines
7.3 KiB
Python
#!/usr/bin/env python3
|
|
#-*- coding:utf-8 -*-
|
|
##############################################################################
|
|
#Copyright (c): 2020-2025, Huawei Tech. Co., Ltd.
|
|
#FileName : config_cm_resource.py
|
|
#Version : openGauss
|
|
#Date : 2023-02-12
|
|
#Description : config_cm_resource.py is a utility to config CM resource file.
|
|
##############################################################################
|
|
|
|
import os
|
|
import sys
|
|
import getopt
|
|
|
|
sys.path.append(sys.path[0] + "/../")
|
|
from gspylib.common.GaussLog import GaussLog
|
|
from gspylib.common.ErrorCode import ErrorCode
|
|
from gspylib.common.LocalBaseOM import LocalBaseOM
|
|
from domain_utils.domain_common.cluster_constants import ClusterConstants
|
|
from domain_utils.cluster_file.cluster_log import ClusterLog
|
|
from gspylib.threads.parallelTool import parallelTool
|
|
from base_utils.os.net_util import NetUtil
|
|
|
|
|
|
# Global variables define
|
|
g_opts = None
|
|
|
|
# Action type
|
|
ACTION_INSTALL_CLUSTER = "install_cluster"
|
|
ACTION_EXPAND_NODE ="expansion_node"
|
|
ACTION_DROP_NODE = "drop_node"
|
|
|
|
|
|
class CmdOptions():
|
|
"""
|
|
Command line parameters
|
|
"""
|
|
|
|
def __init__(self):
|
|
"""
|
|
"""
|
|
self.action_type = ""
|
|
self.cluster_user = ""
|
|
self.cluster_conf = ""
|
|
self.log_file = ""
|
|
self.drop_nodes = []
|
|
|
|
|
|
def parse_command_line():
|
|
"""
|
|
Parse command line
|
|
"""
|
|
try:
|
|
opts, args = getopt.getopt(sys.argv[1:], "t:U:X:l:H:")
|
|
except Exception 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 == "-t":
|
|
g_opts.action_type = value
|
|
elif key == "-U":
|
|
g_opts.cluster_user = value
|
|
elif key == "-X":
|
|
g_opts.cluster_conf = value
|
|
elif key == "-l":
|
|
g_opts.log_file = value
|
|
elif key == "-H":
|
|
g_opts.drop_nodes = value.split(',')
|
|
|
|
def check_parameters():
|
|
"""
|
|
Check parameters
|
|
"""
|
|
if not g_opts.action_type:
|
|
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 't' + ".")
|
|
|
|
if not g_opts.drop_nodes and g_opts.action_type == ACTION_DROP_NODE:
|
|
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'H' + ".")
|
|
|
|
if not g_opts.cluster_user:
|
|
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 'U' + ".")
|
|
|
|
if g_opts.cluster_conf:
|
|
if not os.path.exists(g_opts.cluster_conf):
|
|
GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50201"] % g_opts.cluster_conf)
|
|
|
|
if not g_opts.log_file:
|
|
g_opts.log_file = ClusterLog.getOMLogPath(
|
|
ClusterConstants.LOCAL_LOG_FILE, g_opts.cluster_user, "")
|
|
|
|
|
|
class ConfigCMResource(LocalBaseOM):
|
|
"""
|
|
class: ConfigCMResource
|
|
"""
|
|
|
|
def __init__(self, action_type, cluster_user, cluster_conf, log_file, drop_nodes):
|
|
"""
|
|
Init configuration on local node
|
|
"""
|
|
LocalBaseOM.__init__(self, log_file, cluster_user, cluster_conf)
|
|
if self.clusterConfig == "":
|
|
self.readConfigInfo()
|
|
else:
|
|
self.readConfigInfoByXML()
|
|
|
|
# Check user information
|
|
self.getUserInfo()
|
|
if self.user != cluster_user.strip():
|
|
self.logger.debug("User parameter : %s." % self.user)
|
|
self.logger.logExit(ErrorCode.GAUSS_503["GAUSS_50315"]
|
|
% (self.user, self.clusterInfo.appPath))
|
|
self.initComponent()
|
|
|
|
self.cm_res_info = {}
|
|
self.base_ips = []
|
|
self.action_type = action_type
|
|
self.drop_nodes = drop_nodes
|
|
|
|
def get_cm_res_info(self):
|
|
"""
|
|
Get CM resource information for adding
|
|
"""
|
|
# get all node names
|
|
node_names = self.clusterInfo.getClusterNodeNames()
|
|
for node_name in node_names:
|
|
node_info = self.clusterInfo.getDbNodeByName(node_name)
|
|
for inst in node_info.datanodes:
|
|
for i, res_name in enumerate(inst.float_ips):
|
|
_tup = (self.clusterInfo.float_ips[res_name], inst.listenIps[i],
|
|
inst.instanceId, node_info.id)
|
|
if res_name not in self.cm_res_info:
|
|
self.cm_res_info[res_name] = [_tup]
|
|
else:
|
|
self.cm_res_info[res_name].append(_tup)
|
|
|
|
self.logger.log("Successfully get cm res info: \n%s" % str(self.cm_res_info))
|
|
|
|
def get_base_ips(self):
|
|
"""
|
|
Get base IP for reducing
|
|
"""
|
|
for node_name in self.drop_nodes:
|
|
node_info = self.clusterInfo.getDbNodeByName(node_name)
|
|
for inst in node_info.datanodes:
|
|
self.base_ips.extend(inst.listenIps)
|
|
|
|
def _config_an_instance(self, component):
|
|
"""
|
|
Config CM resource file for single component
|
|
"""
|
|
# check instance data directory
|
|
inst_type = component.instInfo.datadir.split('/')[-1].strip()
|
|
if inst_type != "cm_agent":
|
|
self.logger.log("Current instance is not cm_agent")
|
|
return
|
|
|
|
if not os.path.exists(component.instInfo.datadir):
|
|
raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % \
|
|
"data directory of the cm_agent instance")
|
|
|
|
component.config_cm_res_json(self.base_ips, self.cm_res_info)
|
|
|
|
def add_cm_res_info(self):
|
|
"""
|
|
Config CM resource file for "install/expansion"
|
|
"""
|
|
self.get_cm_res_info()
|
|
component_list = self.cmCons
|
|
try:
|
|
parallelTool.parallelExecute(self._config_an_instance, component_list)
|
|
except Exception as e:
|
|
raise Exception(str(e))
|
|
|
|
def reduce_cm_res_info(self):
|
|
"""
|
|
Config CM resource file for "dropnode"
|
|
"""
|
|
self.get_base_ips()
|
|
component_list = self.cmCons
|
|
try:
|
|
parallelTool.parallelExecute(self._config_an_instance, component_list)
|
|
except Exception as e:
|
|
raise Exception(str(e))
|
|
|
|
def run(self):
|
|
"""
|
|
Config CM resource file
|
|
"""
|
|
fun_dict = {ACTION_INSTALL_CLUSTER : self.add_cm_res_info,
|
|
ACTION_EXPAND_NODE : self.add_cm_res_info,
|
|
ACTION_DROP_NODE : self.reduce_cm_res_info}
|
|
|
|
if self.action_type in list(fun_dict.keys()):
|
|
fun_dict[self.action_type]()
|
|
else:
|
|
raise Exception(ErrorCode.GAUSS_500["GAUSS_50004"] % 't' + \
|
|
" Value: %s." % self.action_type)
|
|
|
|
self.logger.log("Successfully configured CM resource file on node[%s]" % \
|
|
NetUtil.GetHostIpOrName())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
"""
|
|
function: Main function
|
|
1.Parse command line
|
|
2.Check parameter
|
|
3.Read config from xml config file
|
|
4.Get the CM resource information to be configured
|
|
5.Config CM resource file
|
|
input : NA
|
|
output: NA
|
|
"""
|
|
try:
|
|
parse_command_line()
|
|
check_parameters()
|
|
configer = ConfigCMResource(g_opts.action_type, g_opts.cluster_user,
|
|
g_opts.cluster_conf, g_opts.log_file, g_opts.drop_nodes)
|
|
configer.run()
|
|
|
|
except Exception as e:
|
|
GaussLog.exitWithError(str(e))
|
|
|
|
sys.exit(0)
|