297 lines
11 KiB
Python
297 lines
11 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding:utf-8 -*-
|
|
#############################################################################
|
|
# Copyright (c) 2023 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 : xml_template is generate XML template file
|
|
#############################################################################
|
|
|
|
import os
|
|
import sys
|
|
import subprocess
|
|
import json
|
|
import xml.etree.ElementTree as ET
|
|
|
|
from gspylib.common.GaussLog import GaussLog
|
|
from base_utils.template.xml_status import XmlStatus
|
|
from base_utils.template.xml_constant import XmlConstant
|
|
|
|
|
|
def load_json_file():
|
|
if XmlConstant.IS_CHINESE:
|
|
resource = "resource_zh.json"
|
|
else:
|
|
resource = "resource_en.json"
|
|
with open(os.path.join(XmlConstant.get_current_dir(), resource), 'r') as f:
|
|
XmlConstant.RESOURCE_DATA = json.load(f)
|
|
|
|
|
|
def get_locale():
|
|
cmd = "echo $LANG"
|
|
(status, output) = subprocess.getstatusoutput(cmd)
|
|
if status == 0:
|
|
if output:
|
|
if "CN" in output:
|
|
XmlConstant.IS_CHINESE = True
|
|
else:
|
|
XmlConstant.IS_CHINESE = False
|
|
else:
|
|
GaussLog.exitWithError("Executing %s failed. output is empty." % cmd)
|
|
else:
|
|
GaussLog.exitWithError("Executing %s failed. Error: %s" % (cmd, output))
|
|
|
|
|
|
def check_input_chinese():
|
|
user_input = input(XmlConstant.RESOURCE_DATA.get('input_chinese')).strip()
|
|
if not user_input:
|
|
XmlConstant.IS_CHINESE = True
|
|
return True
|
|
if user_input == "1":
|
|
XmlConstant.IS_CHINESE = True
|
|
return True
|
|
elif user_input == "2":
|
|
XmlConstant.IS_CHINESE = False
|
|
return True
|
|
else:
|
|
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_character'))
|
|
return False
|
|
|
|
|
|
def input_user_info():
|
|
current_state = XmlStatus()
|
|
while True:
|
|
current_state = current_state.work()
|
|
if current_state is None:
|
|
break
|
|
|
|
|
|
def check_common(check):
|
|
for i in range(XmlConstant.TRIES):
|
|
if i == 3:
|
|
sys.exit(0)
|
|
if not check():
|
|
continue
|
|
else:
|
|
break
|
|
|
|
|
|
def with_chinese():
|
|
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('navigation'))
|
|
XmlConstant.select_option(XmlConstant.RESOURCE_DATA.get('chinese'), XmlConstant.RESOURCE_DATA.get('english'))
|
|
check_common(check_input_chinese)
|
|
|
|
def confirm_xml():
|
|
for i in range(XmlConstant.TRIES):
|
|
if i == 3:
|
|
sys.exit(0)
|
|
user_input = input(XmlConstant.RESOURCE_DATA.get('confirm_xml')).strip()
|
|
|
|
if user_input.lower() in ('y', 'yes'):
|
|
return
|
|
else:
|
|
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_confirm_xml'))
|
|
|
|
|
|
class GenerateTemplate:
|
|
|
|
def __init__(self):
|
|
"""
|
|
function: constructor
|
|
"""
|
|
self.tree = ET.ElementTree()
|
|
self.root = None
|
|
self.xml_file_path = ""
|
|
self.target_xml = ""
|
|
|
|
def load_xml(self):
|
|
try:
|
|
# xml default path is ./cluster_tmp.xml
|
|
tmp_xml_dir = "./cluster_tmp.xml"
|
|
xml_dir = os.path.normpath(os.path.join(XmlConstant.get_current_dir(), tmp_xml_dir))
|
|
self.tree = ET.parse(xml_dir)
|
|
self.root = self.tree.getroot()
|
|
self.xml_file_path = xml_dir
|
|
except Exception as e:
|
|
raise Exception("xml file parsing failed: ", e)
|
|
|
|
def delete_xml_node(self):
|
|
if 9 >= XmlConstant.PRI_STANDBY_COUNT > 0:
|
|
new_node_list = XmlConstant.HOST_NODE_INFO[XmlConstant.PRI_STANDBY_COUNT:]
|
|
for child in self.root[1].findall('DEVICE'):
|
|
if child.get('sn') in new_node_list:
|
|
self.root[1].remove(child)
|
|
|
|
def delete_xml_ddes(self):
|
|
if XmlConstant.IS_DDES:
|
|
return
|
|
# remove dss info: {'enable_dss', 'dss_home', 'dss_vg_info', 'votingDiskPath', 'shareDiskDir', 'ss_dss_vg_name'}
|
|
for child in self.root[0].findall('PARAM'):
|
|
if child.attrib['name'] in XmlConstant.DSS_PARA_INFO:
|
|
self.root[0].remove(child)
|
|
|
|
def delete_xml_cm(self):
|
|
if XmlConstant.IS_CM:
|
|
return
|
|
# remove cm info: ['cmDir', 'cmsNum', 'cmServerPortBase', 'cmServerPortStandby', 'cmServerListenIp1',
|
|
# 'cmServerHaIp1', 'cmServerlevel', 'cmServerRelation']
|
|
for i in range(0, len(self.root[1])):
|
|
for child in self.root[1][i].findall('PARAM'):
|
|
if child.attrib['name'] in XmlConstant.CM_PARA_INFO:
|
|
self.root[1][i].remove(child)
|
|
|
|
def update_cluster_label_nodename_info(self):
|
|
for child in self.root[0]:
|
|
if child.attrib['name'] == "nodeNames":
|
|
child.attrib['value'] = ",".join(XmlConstant.HOSTNAME_LISTS)
|
|
if child.attrib['name'] == "backIp1s":
|
|
child.attrib["value"] = ",".join(XmlConstant.IP_LISTS)
|
|
|
|
def update_database_install_dir(self):
|
|
for child in self.root[0]:
|
|
if child.get('name') == "gaussdbAppPath":
|
|
child.attrib['value'] = os.path.normpath(os.path.join(XmlConstant.OPENGAUSS_INSTALL_DIR, 'app'))
|
|
elif child.get('name') == "gaussdbLogPath":
|
|
child.attrib['value'] = os.path.normpath(os.path.join(XmlConstant.OPENGAUSS_INSTALL_DIR, 'log'))
|
|
elif child.get('name') == "tmpMppdbPath":
|
|
child.attrib['value'] = os.path.normpath(os.path.join(XmlConstant.OPENGAUSS_INSTALL_DIR, 'tmp'))
|
|
elif child.get('name') == "gaussdbToolPath":
|
|
child.attrib['value'] = os.path.normpath(os.path.join(XmlConstant.OPENGAUSS_INSTALL_DIR, 'tool'))
|
|
elif child.get('name') == "corePath":
|
|
child.attrib['value'] = os.path.normpath(os.path.join(XmlConstant.OPENGAUSS_INSTALL_DIR, 'corefile'))
|
|
|
|
def update_cluster_label_common_info(self):
|
|
self.update_cluster_label_nodename_info()
|
|
self.update_database_install_dir()
|
|
|
|
def update_database_port(self):
|
|
for i in range(len(self.root[1])):
|
|
for child in self.root[1][i]:
|
|
if child.attrib['name'] == 'dataPortBase':
|
|
child.attrib['value'] = XmlConstant.DATABASE_PORT
|
|
|
|
def update_node_ip_hostname_info(self):
|
|
datanode1 = os.path.normpath(os.path.join(XmlConstant.OPENGAUSS_INSTALL_DIR, "data/dn1"))
|
|
if not XmlConstant.IS_PRI_STANDBY:
|
|
datanode1_value = datanode1
|
|
else:
|
|
datanode1_list = []
|
|
datanode1_list.append(datanode1)
|
|
for hostname in XmlConstant.HOSTNAME_LISTS[1:]:
|
|
datanode1_list.append(hostname)
|
|
datanode1_list.append(datanode1)
|
|
datanode1_value = ",".join(datanode1_list)
|
|
|
|
for i in range(len(self.root[1])):
|
|
for ele in self.root[1][i]:
|
|
if ele.attrib['name'] == "name":
|
|
ele.attrib['value'] = XmlConstant.HOSTNAME_LISTS[i]
|
|
if ele.attrib['name'] == "backIp1":
|
|
ele.attrib['value'] = XmlConstant.IP_LISTS[i]
|
|
if ele.attrib['name'] == "sshIp1":
|
|
ele.attrib['value'] = XmlConstant.IP_LISTS[i]
|
|
if ele.attrib['name'] == "dataNode1":
|
|
ele.attrib['value'] = datanode1_value
|
|
|
|
def update_device_label_info(self):
|
|
# update database port
|
|
self.update_database_port()
|
|
# update node ip
|
|
self.update_node_ip_hostname_info()
|
|
|
|
def update_ddes_info(self):
|
|
if not XmlConstant.IS_DDES:
|
|
return
|
|
# update ddes info
|
|
for child in self.root[0].findall('PARAM'):
|
|
if child.attrib['name'] in XmlConstant.UPDATE_DSS_PARA_INFO:
|
|
child.attrib['value'] = XmlConstant.DDES_INFO.get(child.attrib['name'])
|
|
|
|
def update_cm_info(self):
|
|
if not XmlConstant.IS_CM:
|
|
return
|
|
# update cm: update cmServerPortBase cmServerListenIp1 cmServerHaIp1 cmServerRelation cmDir
|
|
for child in self.root[1]:
|
|
for ele in child:
|
|
if ele.attrib['name'] == "cmServerPortBase":
|
|
ele.attrib['value'] = XmlConstant.CM_SERVER_PORT
|
|
if ele.attrib['name'] == "cmServerPortStandby":
|
|
ele.attrib['value'] = XmlConstant.CM_SERVER_PORT
|
|
if ele.attrib['name'] == "cmServerListenIp1":
|
|
ele.attrib['value'] = ",".join(XmlConstant.IP_LISTS)
|
|
if ele.attrib['name'] == "cmServerHaIp1":
|
|
ele.attrib["value"] = ",".join(XmlConstant.IP_LISTS)
|
|
if ele.attrib['name'] == "cmServerRelation":
|
|
ele.attrib['value'] = ",".join(XmlConstant.HOSTNAME_LISTS)
|
|
if ele.attrib['name'] == "cmDir":
|
|
ele.attrib['value'] = os.path.normpath(
|
|
os.path.join(XmlConstant.OPENGAUSS_INSTALL_DIR, 'data', 'cmserver'))
|
|
|
|
def update_xml_all_info(self):
|
|
# update all info
|
|
# 1.update cluster label common info
|
|
self.update_cluster_label_common_info()
|
|
# 2.update device label common info
|
|
self.update_device_label_info()
|
|
# 3.update ddes info
|
|
self.update_ddes_info()
|
|
# 4.update cm info
|
|
self.update_cm_info()
|
|
|
|
def generate_new_xml_file(self):
|
|
self.target_xml = XmlConstant.TARGET_XML
|
|
if os.path.exists(self.target_xml):
|
|
os.remove(self.target_xml)
|
|
ET.ElementTree(self.root).write(self.target_xml)
|
|
|
|
def display_xml_info(self):
|
|
if not os.path.exists(self.target_xml):
|
|
raise Exception("new xml file not found!")
|
|
GaussLog.printMessage("%s %s" % (XmlConstant.RESOURCE_DATA.get('target_xml_dir'), self.target_xml))
|
|
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('target_xml_content'))
|
|
# use cat
|
|
cmd = "cat %s" % self.target_xml
|
|
(status, output) = subprocess.getstatusoutput(cmd)
|
|
if status == 0:
|
|
GaussLog.printMessage(output)
|
|
|
|
def run(self):
|
|
# get locale
|
|
get_locale()
|
|
# load json file
|
|
load_json_file()
|
|
# navigation for english or chinese
|
|
with_chinese()
|
|
# load json file
|
|
load_json_file()
|
|
# input user info
|
|
input_user_info()
|
|
# load xml
|
|
self.load_xml()
|
|
# delete xml excess node count
|
|
self.delete_xml_node()
|
|
# delete xml ddes info
|
|
self.delete_xml_ddes()
|
|
# delete xml cm info
|
|
self.delete_xml_cm()
|
|
# update xml all info
|
|
self.update_xml_all_info()
|
|
# generate a new xml file
|
|
self.generate_new_xml_file()
|
|
# display xml info
|
|
self.display_xml_info()
|
|
# confirm xml content
|
|
confirm_xml()
|