From baedf1fb089d8391d65570ed70f9c9d005a32571 Mon Sep 17 00:00:00 2001 From: Xing Guo Date: Mon, 6 May 2024 13:57:58 +0800 Subject: [PATCH] [7X] Skip ssh if segments are on the same host with coordinator. (#16812) We can skip ssh connections if segments are on the same host with the coordinator. We can save some time when executing commands. E.g., with this patch, we don't ssh connection when creating the demo cluster and the creation time can be reduced from 18s to 10s on my laptop. Besides, we can skip setting up ssh keys for deploying the demo cluster. --- gpMgmt/bin/gppylib/commands/base.py | 16 +++++++++++----- gpMgmt/bin/gppylib/commands/gp.py | 6 ++++-- .../operations/detect_unreachable_hosts.py | 8 +++++++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/gpMgmt/bin/gppylib/commands/base.py b/gpMgmt/bin/gppylib/commands/base.py index 464a2014454..87290cb11ff 100755 --- a/gpMgmt/bin/gppylib/commands/base.py +++ b/gpMgmt/bin/gppylib/commands/base.py @@ -22,6 +22,7 @@ import os import signal +import socket import subprocess import sys import time @@ -502,14 +503,19 @@ def execute(self, cmd, pickled=False, start_new_session=False): # Escape \ and " for remote execution cmd.cmdStr = cmd.cmdStr.replace('\\','\\\\').replace('"', '\\"') - cmd.cmdStr = "ssh -o StrictHostKeyChecking=no -o ServerAliveInterval=60 " \ - "{targethost} \"{gphome} {cmdstr}\"".format(targethost=self.targetHost, - gphome=". %s/greenplum_path.sh;" % self.gphome, - cmdstr=cmd.cmdStr) + + localhost = socket.gethostname() + if localhost != self.targetHost: + cmd.cmdStr = "ssh -o StrictHostKeyChecking=no -o ServerAliveInterval=60 " \ + "{targethost} \"{gphome} {cmdstr}\"".format(targethost=self.targetHost, + gphome=". %s/greenplum_path.sh;" % self.gphome, + cmdstr=cmd.cmdStr) + else: + cmd.cmdStr = "bash -c \"{gphome} {cmdstr}\"".format(gphome=". %s/greenplum_path.sh;" % self.gphome, + cmdstr=cmd.cmdStr) LocalExecutionContext.execute(self, cmd, pickled=pickled, start_new_session=start_new_session) if (cmd.get_stderr().startswith('ssh_exchange_identification: Connection closed by remote host')): self.__retry(cmd, 0, pickled) - pass def __retry(self, cmd, count, pickled): if count == SSH_MAX_RETRY: diff --git a/gpMgmt/bin/gppylib/commands/gp.py b/gpMgmt/bin/gppylib/commands/gp.py index 129ee13d50c..3ec845203a8 100644 --- a/gpMgmt/bin/gppylib/commands/gp.py +++ b/gpMgmt/bin/gppylib/commands/gp.py @@ -1651,11 +1651,13 @@ def list_addrs(hostname=None, include_loopback=False): cmd = ["echo 'START_CMD_OUTPUT'; %s/libexec/ifaddrs" % GPHOME] if not include_loopback: cmd.append('--no-loopback') - if hostname: + localhost = socket.gethostname() + if hostname and hostname != localhost: args = ['ssh', '-n', hostname] args.append(' '.join(cmd)) else: - args = cmd + args = ['bash', '-c'] + args.append(' '.join(cmd)) result = subprocess.check_output(args).decode() return result.split('START_CMD_OUTPUT\n')[1].splitlines() diff --git a/gpMgmt/bin/gppylib/operations/detect_unreachable_hosts.py b/gpMgmt/bin/gppylib/operations/detect_unreachable_hosts.py index 7ce465704a4..0e2d92da00e 100644 --- a/gpMgmt/bin/gppylib/operations/detect_unreachable_hosts.py +++ b/gpMgmt/bin/gppylib/operations/detect_unreachable_hosts.py @@ -2,6 +2,7 @@ from gppylib.commands.base import Command from gppylib.commands import base from gppylib.gparray import STATUS_DOWN +import socket logger = gplog.get_default_logger() @@ -12,8 +13,13 @@ def get_unreachable_segment_hosts(hosts, num_workers): pool = base.WorkerPool(numWorkers=num_workers) try: + localhost = socket.gethostname() for host in set(hosts): - cmd = Command(name='check %s is up' % host, cmdStr="ssh %s 'echo %s'" % (host, host)) + cmd = None + if host != localhost: + cmd = Command(name='check %s is up' % host, cmdStr="ssh %s 'echo %s'" % (host, host)) + else: + cmd = Command(name='check %s is up' % host, cmdStr="echo {}".format(host)) pool.addCommand(cmd) pool.join() finally: