Files
openGauss-OM/script/base_utils/template/xml_status.py
axiaxixixixi 922f3ae4f1 om适配ipv6
2024-07-29 15:28:01 +08:00

509 lines
18 KiB
Python

import os
import sys
import socket
import subprocess
from gspylib.common.GaussLog import GaussLog
from gspylib.common.Common import DefaultValue
from base_utils.os.net_util import NetUtil
from base_utils.template.xml_constant import XmlConstant
def check_illegal_character(user_put):
for rac in DefaultValue.PATH_CHECK_LIST:
flag = user_put.find(rac)
if flag >= 0:
GaussLog.printMessage("%s %s" % (user_put, XmlConstant.RESOURCE_DATA.get('invalid_character')))
return False
return True
def check_port(port, action='', database_port=''):
if not str(port).isdigit():
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_num'))
return False
if int(port) > 65535 or int(port) < 1024:
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_port'))
return False
if action == 'cm':
if port == database_port:
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('cm_port_repeat'))
return False
if int(port) in range(int(database_port), int(database_port) + 11):
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('cm_port_beyond'))
return False
return True
def check_database_dir(database_dir):
# check illegal character
if not check_illegal_character(database_dir):
return False
# check isabs path
if not os.path.isabs(database_dir):
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_abs_dir'))
return False
database_dir = os.path.normpath(database_dir)
# check path exists
if os.path.exists(database_dir):
if not os.path.isdir(database_dir):
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_dir'))
return False
# check permission
if not os.access(database_dir, os.R_OK | os.W_OK):
GaussLog.printMessage("%s %s" % (XmlConstant.RESOURCE_DATA.get('not_permission'), database_dir))
return False
else:
cmd = "mkdir -p %s && rm -rf %s" % (database_dir, database_dir)
(status, output) = subprocess.getstatusoutput(cmd)
if status != 0:
GaussLog.printMessage("%s %s" % (database_dir, XmlConstant.RESOURCE_DATA.get('mkdir_dir_failed')))
return False
return True
def check_ip_hostname_valid(ip, hostname):
if not NetUtil.isIpValid(ip):
GaussLog.printMessage("%s %s" % (ip, XmlConstant.RESOURCE_DATA.get('invalid_ip')))
return False
if not check_illegal_character(ip):
return False
if not check_illegal_character(hostname):
return False
return True
def check_ip_node_count():
if len(XmlConstant.PRI_STANDBY_IP.keys()) != XmlConstant.PRI_STANDBY_COUNT:
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('ip_hostname_not_match'))
return False
return True
def get_ip_hostname(user_input):
pri_standby_ip = {}
ip_lists = []
hostname_lists = []
ip_hostname = user_input.split(";")
# ip_hostname remove empty elements
ip_hostname = [tmp for tmp in ip_hostname if tmp]
if (len(ip_hostname) != XmlConstant.PRI_STANDBY_COUNT):
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('ip_hostname_not_match'))
return False
for tmp in ip_hostname:
if len(tmp.strip().split()) != 2:
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('ip_hostname_not_match'))
return False
ip = str(tmp.strip().split()[0])
hostname = str(tmp.strip().split()[1])
if not check_ip_hostname_valid(ip, hostname):
return False
pri_standby_ip[ip] = hostname
ip_lists.append(ip)
hostname_lists.append(hostname)
XmlConstant.PRI_STANDBY_IP = pri_standby_ip
XmlConstant.IP_LISTS = ip_lists
XmlConstant.HOSTNAME_LISTS = hostname_lists
if not check_ip_node_count():
return False
return True
class TemplateStatus:
def work(self):
pass
def check_xml_isabs(xml_dir):
if os.path.isabs(xml_dir):
target_xml = xml_dir
else:
target_xml = os.path.join(XmlConstant.get_current_dir(), xml_dir)
return os.path.normpath(target_xml)
def check_xml_file_permission(target_xml):
if os.path.exists(target_xml):
if not os.path.isfile(target_xml):
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_xml_dir'))
return False
# check permission
if not os.access(target_xml, os.R_OK | os.W_OK):
GaussLog.printMessage("%s %s" % (XmlConstant.RESOURCE_DATA.get('not_permission'), target_xml))
return False
else:
cmd = "touch %s && rm -rf %s" % (target_xml, target_xml)
(status, output) = subprocess.getstatusoutput(cmd)
if status != 0:
GaussLog.printMessage("%s %s" % (target_xml, XmlConstant.RESOURCE_DATA.get('mkdir_file_failed')))
return False
return True
def check_xml_dir_repeat(target_xml):
cur_dir = XmlConstant.get_current_dir()
files = []
for tmp in XmlConstant.KEEP_FILES:
file = os.path.normpath(os.path.join(cur_dir, tmp))
files.append(file)
if target_xml in files:
GaussLog.printMessage("%s %s" % (XmlConstant.RESOURCE_DATA.get('invalid_xml_path'), target_xml))
return False
return True
def check_input_xml_info(xml_dir):
# check illegal
if not check_illegal_character(xml_dir):
return False
# get xml file's abs dir
XmlConstant.TARGET_XML = check_xml_isabs(xml_dir)
if not check_xml_file_permission(XmlConstant.TARGET_XML):
return False
if not check_xml_dir_repeat(XmlConstant.TARGET_XML):
return False
return True
class XmlStatus(TemplateStatus):
def work(self):
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
# 用户输入back回退到上个流程
user_input = input(XmlConstant.RESOURCE_DATA.get('input_xml_path')).strip()
if user_input.lower() in ('back', 'b'):
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('not_back'))
return XmlStatus()
if not user_input:
tmp_dir = os.path.join(XmlConstant.get_current_dir(), 'cluster.xml')
if os.path.exists(tmp_dir):
os.remove(tmp_dir)
XmlConstant.TARGET_XML = tmp_dir
if not check_input_xml_info(tmp_dir):
continue
return DatabaseInstallStatus()
if not check_input_xml_info(user_input):
continue
return DatabaseInstallStatus()
class DatabaseInstallStatus(TemplateStatus):
def work(self):
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
user_input = input(XmlConstant.RESOURCE_DATA.get('input_database_path')).strip()
if user_input.lower() in ('back', 'b'):
return XmlStatus()
if not user_input:
XmlConstant.OPENGAUSS_INSTALL_DIR = XmlConstant.DATABASE_INSTALL_DIR
if not check_database_dir(XmlConstant.OPENGAUSS_INSTALL_DIR):
continue
return DataPortStatus()
if not check_database_dir(user_input):
continue
XmlConstant.OPENGAUSS_INSTALL_DIR = os.path.normpath(user_input)
return DataPortStatus()
class DataPortStatus(TemplateStatus):
def work(self):
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
user_input = input(XmlConstant.RESOURCE_DATA.get('input_database_port')).strip()
if user_input.lower() in ('back', 'b'):
return DatabaseInstallStatus()
if not user_input:
XmlConstant.DATABASE_PORT = XmlConstant.DEFAULT_DATABASE_PORT
return PriStandbyStatus()
if not check_port(user_input):
continue
XmlConstant.DATABASE_PORT = user_input
return PriStandbyStatus()
class PriStandbyStatus(TemplateStatus):
def work(self):
XmlConstant.IS_PRI_STANDBY = False
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('choose_pri_standby'))
XmlConstant.select_option(XmlConstant.RESOURCE_DATA.get('deploy_pri_standby'),
XmlConstant.RESOURCE_DATA.get('deploy_single'))
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
user_input = input(XmlConstant.RESOURCE_DATA.get('input_pri_standby')).strip()
if user_input.lower() in ('back', 'b'):
return DataPortStatus()
if not user_input:
XmlConstant.IS_PRI_STANDBY = True
return DdesStatus()
if not user_input.isdigit():
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_num'))
continue
if user_input == "1":
XmlConstant.IS_PRI_STANDBY = True
return DdesStatus()
elif user_input == "2":
XmlConstant.IS_PRI_STANDBY = False
return PriStandbyCountStatus()
else:
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_character'))
continue
class DdesStatus(TemplateStatus):
def work(self):
XmlConstant.IS_DDES = False
XmlConstant.IS_CM = False
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('choose_ddes'))
XmlConstant.select_option(XmlConstant.RESOURCE_DATA.get('not_deploy'), XmlConstant.RESOURCE_DATA.get('deploy'))
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
user_input = input(XmlConstant.RESOURCE_DATA.get('input_ddes')).strip()
if user_input.lower() in ('back', 'b'):
return PriStandbyStatus()
if not user_input:
XmlConstant.IS_DDES = False
return CmStatus()
if not user_input.isdigit():
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_num'))
continue
if user_input == "1":
XmlConstant.IS_DDES = False
return CmStatus()
elif user_input == "2":
XmlConstant.IS_DDES = True
XmlConstant.IS_CM = True
return DdesDssHomeStatus()
else:
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_character'))
continue
class DdesDssHomeStatus(TemplateStatus):
def work(self):
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
user_input = input(XmlConstant.RESOURCE_DATA.get('intput_dss_home')).strip()
if user_input.lower() in ('back', 'b'):
return DdesStatus()
if not user_input:
XmlConstant.DDES_INFO['dss_home'] = XmlConstant.DSS_HOME_DIR
if not check_database_dir(XmlConstant.DDES_INFO['dss_home']):
continue
return DdesDssVgNameStatus()
if not check_database_dir(user_input):
continue
XmlConstant.DDES_INFO['dss_home'] = os.path.normpath(user_input)
return DdesDssVgNameStatus()
class DdesDssVgNameStatus(TemplateStatus):
def work(self):
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
user_input = input(XmlConstant.RESOURCE_DATA.get('intput_ss_dss_vg_name')).strip()
if user_input.lower() in ('back', 'b'):
return DdesDssHomeStatus()
if not user_input:
XmlConstant.DDES_INFO['ss_dss_vg_name'] = XmlConstant.DSS_VG_NAME_DIR
return DdesDssVgInfoStatus()
XmlConstant.DDES_INFO['ss_dss_vg_name'] = user_input
return DdesDssVgInfoStatus()
class DdesDssVgInfoStatus(TemplateStatus):
def work(self):
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
user_input = input(XmlConstant.RESOURCE_DATA.get('input_dss_vg_info')).strip()
if user_input.lower() in ('back', 'b'):
return DdesDssVgNameStatus()
if not user_input:
XmlConstant.DDES_INFO['dss_vg_info'] = XmlConstant.DSS_VG_INFO_DIR
return DdesVotingStatus()
XmlConstant.DDES_INFO['dss_vg_info'] = user_input
return DdesVotingStatus()
class DdesVotingStatus(TemplateStatus):
def work(self):
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
user_input = input(XmlConstant.RESOURCE_DATA.get('input_voting_disk_path')).strip()
if user_input.lower() in ('back', 'b'):
return DdesDssVgInfoStatus()
if not user_input:
XmlConstant.DDES_INFO['votingDiskPath'] = XmlConstant.VOTING_DIR
return DdesShareDiskStatus()
XmlConstant.DDES_INFO['votingDiskPath'] = user_input
return DdesShareDiskStatus()
class DdesShareDiskStatus(TemplateStatus):
def work(self):
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
user_input = input(XmlConstant.RESOURCE_DATA.get('input_share_disk_dir')).strip()
if user_input.lower() in ('back', 'b'):
return DdesVotingStatus()
if not user_input:
XmlConstant.DDES_INFO['shareDiskDir'] = XmlConstant.SHAREDISK_DIR
return CmServerPortStatus()
XmlConstant.DDES_INFO['shareDiskDir'] = user_input
return CmServerPortStatus()
class CmStatus(TemplateStatus):
def work(self):
XmlConstant.IS_CM = False
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('choose_cm'))
XmlConstant.select_option(XmlConstant.RESOURCE_DATA.get('deploy'), XmlConstant.RESOURCE_DATA.get('not_deploy'))
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
user_input = input(XmlConstant.RESOURCE_DATA.get('input_cm')).strip()
if user_input.lower() in ('back', 'b'):
if XmlConstant.IS_DDES:
return DdesShareDiskStatus()
else:
return DdesStatus()
if not user_input:
XmlConstant.IS_CM = True
return CmServerPortStatus()
if not user_input.isdigit():
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_num'))
continue
if user_input == "1":
XmlConstant.IS_CM = True
return CmServerPortStatus()
elif user_input == "2":
XmlConstant.IS_CM = False
return PriStandbyCountStatus()
else:
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_character'))
continue
class CmServerPortStatus(TemplateStatus):
def work(self):
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
user_input = input(XmlConstant.RESOURCE_DATA.get('cm_port')).strip()
if user_input.lower() in ('back', 'b'):
if XmlConstant.IS_DDES:
return DdesShareDiskStatus()
return CmStatus()
if not user_input:
XmlConstant.CM_SERVER_PORT = XmlConstant.DEFAULT_CM_SERVER_PORT
if not check_port(XmlConstant.CM_SERVER_PORT, 'cm', XmlConstant.DATABASE_PORT):
continue
return PriStandbyCountStatus()
if not check_port(user_input, 'cm', XmlConstant.DATABASE_PORT):
continue
XmlConstant.CM_SERVER_PORT = user_input
return PriStandbyCountStatus()
class PriStandbyCountStatus(TemplateStatus):
def work(self):
if not XmlConstant.IS_PRI_STANDBY:
XmlConstant.PRI_STANDBY_COUNT = 1
return PriStandbyIpStatus()
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
user_input = input(XmlConstant.RESOURCE_DATA.get('max_nodes')).strip()
if user_input.lower() in ('back', 'b'):
if XmlConstant.IS_DDES or XmlConstant.IS_CM:
return CmServerPortStatus()
if not XmlConstant.IS_CM:
return CmStatus()
return PriStandbyStatus()
if not user_input:
XmlConstant.PRI_STANDBY_COUNT = 3
return PriStandbyIpStatus()
if not user_input.isdigit():
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_num'))
continue
if 2 <= int(user_input) <= 9:
XmlConstant.PRI_STANDBY_COUNT = int(user_input)
return PriStandbyIpStatus()
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('invalid_character'))
continue
def get_localhost_name():
return socket.gethostname()
def get_localhost_ip():
addr_info = socket.getaddrinfo(get_localhost_name(), None)
for info in addr_info:
# 从地址信息中提取 IPv4 或 IPv6 地址
host_ip = info[NetUtil.ADDRESS_FAMILY_INDEX][NetUtil.IP_ADDRESS_INDEX]
return host_ip
class PriStandbyIpStatus(TemplateStatus):
def work(self):
ip_lists = []
hostname_lists = []
if not XmlConstant.IS_PRI_STANDBY:
hostname_lists.append(get_localhost_name())
ip_lists.append(get_localhost_ip())
XmlConstant.IP_LISTS = ip_lists
XmlConstant.HOSTNAME_LISTS = hostname_lists
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('finish'))
return
for i in range(XmlConstant.TRIES):
if i == 3:
sys.exit(0)
user_input = input(XmlConstant.RESOURCE_DATA.get('input_ip_hostname')).strip()
if user_input.lower() in ('back', 'b'):
return PriStandbyCountStatus()
if not user_input:
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('ip_hostname_empty'))
continue
if not get_ip_hostname(user_input):
continue
GaussLog.printMessage(XmlConstant.RESOURCE_DATA.get('finish'))
return