Files
openGauss-OM/script/impl/expansion/expansion_impl_with_cm_local.py

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)