Files
openGauss-OM/script/base_utils/template/xml_template.py
liuheng 64bd844c51 # This is a combination of 2 commits.
修复扩容检视意见
2024-02-07 10:57:43 +08:00

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()