From 505899efb06c8eddcf77598fbce19fa01e6a39e0 Mon Sep 17 00:00:00 2001 From: axiaxixixixi <306232627@qq.com> Date: Fri, 8 Nov 2024 17:44:28 +0800 Subject: [PATCH] =?UTF-8?q?ipv6=E9=80=82=E9=85=8DCM=E6=94=AF=E6=8C=81VIP?= =?UTF-8?q?=E4=BB=B2=E8=A3=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/base_utils/os/hosts_util.py | 35 ++++++++++++- script/base_utils/os/net_util.py | 5 +- script/gspylib/common/Common.py | 24 +++------ script/gspylib/common/DbClusterInfo.py | 3 +- script/gspylib/component/CM/CM.py | 8 +-- script/gspylib/threads/SshTool.py | 69 ++++++++++++-------------- 6 files changed, 82 insertions(+), 62 deletions(-) diff --git a/script/base_utils/os/hosts_util.py b/script/base_utils/os/hosts_util.py index 0d83f427..0dbc59e5 100644 --- a/script/base_utils/os/hosts_util.py +++ b/script/base_utils/os/hosts_util.py @@ -19,8 +19,10 @@ class HostsUtil: ip_type = os.environ.get("IP_TYPE") if ip_type == NetUtil.NET_IPV6: socket_family = socket.AF_INET6 - else: + elif ip_type == NetUtil.NET_IPV4: socket_family = socket.AF_INET + else: + return "" try: addr_info = socket.getaddrinfo(hostname, None, socket_family) host_ip = addr_info[0][NetUtil.ADDRESS_FAMILY_INDEX][NetUtil.IP_ADDRESS_INDEX] @@ -164,3 +166,34 @@ class HostsUtil: finally: lock.release() return True + + @staticmethod + def add_square_bracket_if_ipv6(host): + """ + function: add square bracket for ipv6 to scpCmd + input: host + output: scp_host + """ + if not host: + return "" + if NetUtil.get_ip_version(host) == NetUtil.NET_IPV6: + # scp file is to the ipv6 address, needs to add [] to ipaddress: + # scp a.txt [2407:c080:1200:22a0:613f:8d3b:caa:2335]:/data + scp_host = "[" + host + "]" + else: + # if host is ipv4 or hostname + scp_host = host + return scp_host + + @staticmethod + def remove_square_bracket_if_exist(host): + """ + function: remove square bracket for ipv6 to scpCmd + input: host + output: host + """ + if not host: + return "" + if host[:1] == '[' and host[-1:] == ']': + host = host.strip('[]') + return host diff --git a/script/base_utils/os/net_util.py b/script/base_utils/os/net_util.py index 69649734..ccd0a713 100644 --- a/script/base_utils/os/net_util.py +++ b/script/base_utils/os/net_util.py @@ -240,8 +240,9 @@ class NetUtil(object): for iface in interfaces(): if key in ifaddresses(iface): - ip_address = ifaddresses(iface)[key][0]['addr'] - yield (iface, ip_address) + for addr_info in ifaddresses(iface)[key]: + ip_address = addr_info['addr'] + yield (iface, ip_address) @staticmethod def getHostNameByIPAddr(ip_address): diff --git a/script/gspylib/common/Common.py b/script/gspylib/common/Common.py index b6013145..5dd5b3eb 100644 --- a/script/gspylib/common/Common.py +++ b/script/gspylib/common/Common.py @@ -39,7 +39,7 @@ import copy from subprocess import PIPE from subprocess import Popen from base_utils.os.password_util import PasswordUtil - +from base_utils.os.hosts_util import HostsUtil # The installation starts, but the package is not decompressed completely. # The lib64/libz.so.1 file is incomplete, and the hashlib depends on the # libz.so.1 file. @@ -711,7 +711,7 @@ class DefaultValue(): ''' function: get local host ip by the hostname input : NA - output: hostIp + output: host_ip ''' # get hostname hostname = socket.gethostname() @@ -721,20 +721,12 @@ class DefaultValue(): "/etc/hosts | grep -E \" %s \"" % (hostname, hostname) (status, output) = subprocess.getstatusoutput(cmd) if (status == 0 and output != ""): - hostIp = output.strip().split(' ')[0].strip() - return hostIp - - # get local host by os function - addr_info = socket.getaddrinfo(hostname, None) - for info in addr_info: - # Extract IPv4 or IPv6 addresses from address information - hostIp = info[NetUtil.ADDRESS_FAMILY_INDEX][NetUtil.IP_ADDRESS_INDEX] - # due to two loopback address in ubuntu, 127.0.1.1 are choosed by hostname. - # there is need to choose 127.0.0.1 - version = LinuxDistro.linux_distribution()[1].split('/')[0] - if version == "buster" and hostIp == "127.0.1.1": - hostIp = "127.0.0.1" - return hostIp + host_ip = output.strip().split(' ')[0].strip() + return host_ip + + # get local host by os function or hosts_file + host_ip = HostsUtil.hostname_to_ip(hostname) + return host_ip @staticmethod def GetPythonUCS(): diff --git a/script/gspylib/common/DbClusterInfo.py b/script/gspylib/common/DbClusterInfo.py index c1839754..ea85d219 100644 --- a/script/gspylib/common/DbClusterInfo.py +++ b/script/gspylib/common/DbClusterInfo.py @@ -4072,7 +4072,8 @@ class dbClusterInfo(): ipList_tmp = multiIpList[i].split(",") for ip in ipList_tmp: ipList.append(ip.strip()) - ipList = self.compress_ips(ipList) + if prefix != "floatIpMap": + ipList = self.compress_ips(ipList) ipNum = len(ipList) if (ipNum != InstCount): raise Exception(ErrorCode.GAUSS_502["GAUSS_50204"] diff --git a/script/gspylib/component/CM/CM.py b/script/gspylib/component/CM/CM.py index 48d6c499..3f90b654 100644 --- a/script/gspylib/component/CM/CM.py +++ b/script/gspylib/component/CM/CM.py @@ -75,9 +75,7 @@ class VipResAttr(): self.float_ip = float_ip def __str__(self): - return str(vars(self)).replace(':', '=').replace('\'', '').replace( - ' ', '').replace('{', '"').replace('}', '"').replace(';', ' ') - + return f'"resources_type={self.resources_type},float_ip={self.float_ip}"' class VipInstAttr(): """ @@ -87,9 +85,7 @@ class VipInstAttr(): self.base_ip = base_ip def __str__(self): - return str(vars(self)).replace(':', '=').replace('\'', '').replace( - ' ', '').replace('{', '"').replace('}', '"').replace(';', ' ') - + return f'"base_ip={self.base_ip}"' class VipAddInst(): """ diff --git a/script/gspylib/threads/SshTool.py b/script/gspylib/threads/SshTool.py index 363efb4d..bec9ad48 100644 --- a/script/gspylib/threads/SshTool.py +++ b/script/gspylib/threads/SshTool.py @@ -35,7 +35,6 @@ from gspylib.common.Common import DefaultValue from base_utils.os.env_util import EnvUtil from base_utils.os.file_util import FileUtil from base_utils.os.net_util import NetUtil -from base_utils.os.cmd_util import CmdUtil from domain_utils.domain_common.cluster_constants import ClusterConstants from base_utils.security.sensitive_mask import SensitiveMask from gspylib.common.Constants import Constants @@ -118,6 +117,7 @@ class SshTool(): self._finalizer = weakref.finalize(self, self.clen_ssh_result_files) self.__sessions = {} self.is_ip = False + self.host_ips_names_map = {} if hostNames: # if not ip, convert hostname to ip @@ -571,6 +571,8 @@ class SshTool(): if localMode: if not self.is_ip: hostList = [HostsUtil.ip_to_hostname(hostList[0])] + if hostList[0] in self.host_ips_names_map: + hostList = [self.host_ips_names_map[hostList[0]]] resultMap[hostList[0]] = DefaultValue.SUCCESS if status == 0 \ else DefaultValue.FAILURE outputCollect = "[%s] %s:\n%s" \ @@ -831,7 +833,7 @@ class SshTool(): mpprcFile = env_file else: mpprcFile = EnvUtil.getEnv(DefaultValue.MPPRC_FILE_ENV) - + if mpprcFile and os.path.isfile(mpprcFile): cmd = "source %s && echo $GPHOME" % mpprcFile (status, output) = subprocess.getstatusoutput(cmd) @@ -848,37 +850,30 @@ class SshTool(): local_mode = check_local_mode(hosts) else: hosts = copy.deepcopy(hostList) - for host in hosts: - if NetUtil.get_ip_version(host) == NetUtil.NET_IPV6: - # scp file is to the ipv6 address, needs to add [] to ipaddress: - # scp a.txt [2407:c080:1200:22a0:613f:8d3b:caa:2335]:/data - ssh_hosts.append("[" + host + "]") - else: - # if host is ipv4 or hostname - ssh_hosts.append(host) if local_mode and \ - srcFile != targetDir and \ - srcFile != os.path.join(targetDir, os.path.split(srcFile)[1]): + srcFile != targetDir and \ + srcFile != os.path.join(targetDir, os.path.split(srcFile)[1]): scpCmd = "cp -r %s %s" % (srcFile, targetDir) else: # cp file on local node - self.cp_file_on_local_node(srcFile, targetDir, resultMap, ssh_hosts) - if not ssh_hosts: + self.cp_file_on_local_node(srcFile, targetDir, resultMap, hosts) + if not hosts: return + hosts = [HostsUtil.add_square_bracket_if_ipv6(host) for host in hosts] scpCmd = "%s -r -v -t %s -p %s -H %s -o %s -e %s %s %s" \ - " 2>&1 | tee %s" % (pscppre, self.__timeout, - parallel_num, - " -H ".join(ssh_hosts), - self.__outputPath, - self.__errorPath, srcFile, - targetDir, self.__resultFile) + " 2>&1 | tee %s" % (pscppre, self.__timeout, + parallel_num, + " -H ".join(hosts), + self.__outputPath, + self.__errorPath, srcFile, + targetDir, self.__resultFile) (status, output) = subprocess.getstatusoutput(scpCmd) - - # If sending the file fails, we retry 3 * 10s to avoid the + hosts = [HostsUtil.remove_square_bracket_if_exist(host) for host in hosts] + # If sending the file fails, we retry 3 * 10s to avoid the # failure caused by intermittent network disconnection. such as Broken pipe. # If the fails is caused by timeout. no need to retry. max_retry_times = 3 - while(max_retry_times > 0 and status != 0 and output.find("Timed out") < 0): + while (max_retry_times > 0 and status != 0 and output.find("Timed out") < 0): max_retry_times -= 1 time.sleep(10) (status, output) = subprocess.getstatusoutput(scpCmd) @@ -896,42 +891,44 @@ class SshTool(): if local_mode: dir_permission = 0o700 if not self.is_ip: - ssh_hosts = [HostsUtil.ip_to_hostname(ssh_hosts[0])] + if hosts[0] in self.host_ips_names_map: + hosts = [self.host_ips_names_map[hosts[0]]] if status == 0: - resultMap[ssh_hosts[0]] = DefaultValue.SUCCESS - outputCollect = "[%s] %s:\n%s" % ("SUCCESS", ssh_hosts[0], + resultMap[hosts[0]] = DefaultValue.SUCCESS + outputCollect = "[%s] %s:\n%s" % ("SUCCESS", hosts[0], SensitiveMask.mask_pwd(output)) if not os.path.exists(self.__outputPath): os.makedirs(self.__outputPath, mode=dir_permission) - file_path = os.path.join(self.__outputPath, ssh_hosts[0]) + file_path = os.path.join(self.__outputPath, hosts[0]) FileUtil.createFileInSafeMode(file_path) with open(file_path, "w") as fp: fp.write(SensitiveMask.mask_pwd(output)) fp.flush() fp.close() else: - resultMap[ssh_hosts[0]] = DefaultValue.FAILURE - outputCollect = "[%s] %s:\n%s" % ("FAILURE", ssh_hosts[0], + resultMap[hosts[0]] = DefaultValue.FAILURE + outputCollect = "[%s] %s:\n%s" % ("FAILURE", hosts[0], SensitiveMask.mask_pwd(output)) if not os.path.exists(self.__errorPath): os.makedirs(self.__errorPath, mode=dir_permission) - file_path = os.path.join(self.__errorPath, ssh_hosts[0]) + file_path = os.path.join(self.__errorPath, hosts[0]) FileUtil.createFileInSafeMode(file_path) with open(file_path, "w") as fp: fp.write(SensitiveMask.mask_pwd(output)) fp.flush() fp.close() else: - resultMap, outputCollect = self.parseSshResult(ssh_hosts) + resultMap, outputCollect = self.parseSshResult(hosts) except Exception as e: self.clen_ssh_result_files() raise Exception(str(e)) - - for host in ssh_hosts: + + for host in hosts: if not local_mode and not self.is_ip: - host = HostsUtil.ip_to_hostname(host) + if host in self.host_ips_names_map: + host = self.host_ips_names_map[host] if resultMap.get(host) != DefaultValue.SUCCESS: raise Exception(ErrorCode.GAUSS_502["GAUSS_50216"] % ("file [%s]" % srcFile) + @@ -1027,9 +1024,9 @@ class SshTool(): continue if len(resultPair) >= 4 and resultPair[2] == "[FAILURE]": - resultMap[resultPair[3]] = "Failure" + resultMap[HostsUtil.remove_square_bracket_if_exist(resultPair[3])] = "Failure" if len(resultPair) >= 4 and resultPair[2] == "[SUCCESS]": - resultMap[resultPair[3]] = "Success" + resultMap[HostsUtil.remove_square_bracket_if_exist(resultPair[3])] = "Success" if len(resultMap) != hostNum: raise Exception(ErrorCode.GAUSS_516["GAUSS_51637"] -- Gitee