157 lines
7.2 KiB
Python
157 lines
7.2 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.
|
|
# ----------------------------------------------------------------------------
|
|
# Description : expansion_impl_with_cm_local.py
|
|
#############################################################################
|
|
|
|
import os
|
|
import subprocess
|
|
|
|
from gspylib.common.Common import DefaultValue
|
|
from impl.expansion.expansion_impl_with_cm import ExpansionImplWithCm, change_user_executor
|
|
|
|
|
|
class ExpansionImplWithCmLocal(ExpansionImplWithCm):
|
|
"""
|
|
This is expand subclass for add node with CM component
|
|
"""
|
|
def __init__(self, expansion):
|
|
super(ExpansionImplWithCmLocal, self).__init__(expansion)
|
|
|
|
def _get_local_node_cluster_commit_id(self):
|
|
"""
|
|
Get local node version
|
|
"""
|
|
self.logger.log("Start get commit ID on local host.")
|
|
# gp_home = self.context.clusterInfoDict["toolPath"]
|
|
# version_file = os.path.realpath(os.path.join(gp_home, "version.cfg"))
|
|
gsql_cmd = "source {0} ; gsql -V".format(self.envFile)
|
|
status, output = subprocess.getstatusoutput(gsql_cmd)
|
|
if status != 0 or not output.strip():
|
|
self.logger.error("Gsql command error: {0}".format(output))
|
|
raise Exception("Current node gsql command failed. {0}".format(output))
|
|
self.logger.debug("Get current node gsql command successfully. "
|
|
"output is : {0}".format(output))
|
|
# gsql version display like (gsql (openGauss x.x.0 build xxxxxxx)
|
|
# compiled at 2029-02-26 02:07:00 commit 0 last mr xxxx)
|
|
commit_id = output.strip().split(")")[0].split()[-1]
|
|
self.logger.log("Current commit ID is : {0}".format(commit_id))
|
|
return commit_id
|
|
|
|
def _get_remote_node_commit_id(self):
|
|
"""
|
|
Get local node version
|
|
"""
|
|
self.logger.log("Start get commit ID on remote host.")
|
|
# gp_home = self.context.clusterInfoDict["toolPath"]
|
|
# version_file = os.path.realpath(os.path.join(gp_home, "version.cfg"))
|
|
gsql_cmd = "source {0} ; gsql -V".format(self.envFile)
|
|
result_map, output_collect = \
|
|
self.ssh_tool.getSshStatusOutput(gsql_cmd,
|
|
hostList=self.get_node_names(self.new_nodes))
|
|
|
|
self.logger.debug("Check remote nodes commit ID , "
|
|
"result_map is : {0}".format(result_map))
|
|
self.logger.debug("Check remote nodes commit ID , "
|
|
"output_collect is : {0}".format(output_collect))
|
|
if DefaultValue.FAILURE in result_map.values():
|
|
self.logger.error("Get commit ID on remote node failed. output: "
|
|
"{0}".format(result_map))
|
|
raise Exception("Get commit ID on remote node failed. output: {0}".format(result_map))
|
|
result_dict = self._parse_ssh_tool_output_collect(output_collect)
|
|
if len(list(set(result_dict.values()))) != 1:
|
|
self.logger.debug("The database version on the remote node is inconsistent. "
|
|
"result {0}".format(result_dict))
|
|
raise Exception("The database version on the remote node is inconsistent.")
|
|
self.logger.debug("result dict is : {0}".format(result_dict))
|
|
return list(result_dict.values())[0]
|
|
|
|
def check_remote_host_cluster_version(self):
|
|
"""
|
|
Check remote node cluster version.
|
|
"""
|
|
current_commit_id = self._get_local_node_cluster_commit_id()
|
|
remote_commit_id = self._get_remote_node_commit_id()
|
|
if current_commit_id != remote_commit_id:
|
|
self.logger.error("The commit ID [{0}] of the new node is "
|
|
"inconsistent with the local ID "
|
|
"[{1}].".format(remote_commit_id, current_commit_id))
|
|
raise Exception("The commit ID [{0}] of the new node is "
|
|
"inconsistent with the local ID "
|
|
"[{1}].".format(remote_commit_id, current_commit_id))
|
|
|
|
def check_remote_host_cm_component(self):
|
|
"""
|
|
Check remote node is contain CM component.
|
|
"""
|
|
self.logger.log("Start check CM component on remote node.")
|
|
for new_node in self.new_nodes:
|
|
cm_agent_conf = os.path.realpath(os.path.join(new_node.cmagents[0].datadir,
|
|
"cm_agent.conf"))
|
|
cmd = "ls {0} | wc -l".format(cm_agent_conf)
|
|
_, output_collect = self.ssh_tool.getSshStatusOutput(cmd, hostList=[new_node.name])
|
|
result_dict = self._parse_ssh_tool_output_collect(output_collect)
|
|
if new_node.name not in result_dict:
|
|
self.logger.error("Check remote node [{0}] cm_agent.conf failed. "
|
|
"output: {1}".format(new_node.name, result_dict))
|
|
raise Exception("Check remote node [{0}] cm_agent.conf failed. "
|
|
"output: {1}".format(new_node.name, result_dict))
|
|
if result_dict.get(new_node.name) != '1':
|
|
self.logger.error("Check remote node [{0}] result failed. "
|
|
"output: {1}".format(new_node.name, result_dict))
|
|
raise Exception("Check remote node [{0}] result failed. "
|
|
"output: {1}".format(new_node.name, result_dict))
|
|
self.logger.log("Check cm_agent.conf on node [{0}] "
|
|
"successfully.".format(new_node.name))
|
|
self.logger.log("Check remote node CM compent successfully.")
|
|
|
|
def expansion_check(self):
|
|
"""
|
|
Check cluster for expansion local mode
|
|
"""
|
|
self.checkUserAndGroupExists()
|
|
self.checkXmlFileAccessToUser()
|
|
self.checkClusterStatus()
|
|
self.validNodeInStandbyList()
|
|
self.check_remote_host_cluster_version()
|
|
self.check_remote_host_cm_component()
|
|
|
|
def do_config(self, p_value):
|
|
"""
|
|
Config instance on new nodes
|
|
"""
|
|
self._change_user_without_root()
|
|
self._config_instance()
|
|
if DefaultValue.is_create_grpc(self.logger,
|
|
self.static_cluster_info.appPath):
|
|
self.logger.log("Generate GRPC cert file.")
|
|
self.generateGRPCCert()
|
|
p_value.value = 1
|
|
|
|
def run(self):
|
|
"""
|
|
This is class enter.
|
|
"""
|
|
self.sendSoftToHosts(send_pkg=False)
|
|
self.send_xml()
|
|
self.expansion_check()
|
|
self._set_expansion_success()
|
|
change_user_executor(self.do_config)
|
|
self._set_pgxc_node_name()
|
|
change_user_executor(self.do_start)
|
|
self.check_new_node_state(True)
|