mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
Check for existing SSH ControlMaster
Be more thorough about checking for an existing ssh master by running a test command first, and only opening up a new master if the test fails to connect. Change-Id: I56fe8e7b4dbc123675b7f259e81d359ed0cd55cf Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
parent
b715b14807
commit
06d029c1c8
@ -356,18 +356,21 @@ class RefSpec(object):
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
_ssh_cache = {}
|
_master_processes = []
|
||||||
|
_master_keys = set()
|
||||||
_ssh_master = True
|
_ssh_master = True
|
||||||
|
|
||||||
def _open_ssh(host, port=None):
|
def _open_ssh(host, port=None):
|
||||||
global _ssh_master
|
global _ssh_master
|
||||||
|
|
||||||
|
# Check to see whether we already think that the master is running; if we
|
||||||
|
# think it's already running, return right away.
|
||||||
if port is not None:
|
if port is not None:
|
||||||
key = '%s:%s' % (host, port)
|
key = '%s:%s' % (host, port)
|
||||||
else:
|
else:
|
||||||
key = host
|
key = host
|
||||||
|
|
||||||
if key in _ssh_cache:
|
if key in _master_keys:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not _ssh_master \
|
if not _ssh_master \
|
||||||
@ -377,15 +380,39 @@ def _open_ssh(host, port=None):
|
|||||||
#
|
#
|
||||||
return False
|
return False
|
||||||
|
|
||||||
command = ['ssh',
|
# We will make two calls to ssh; this is the common part of both calls.
|
||||||
'-o','ControlPath %s' % ssh_sock(),
|
command_base = ['ssh',
|
||||||
'-M',
|
'-o','ControlPath %s' % ssh_sock(),
|
||||||
'-N',
|
host]
|
||||||
host]
|
|
||||||
|
|
||||||
if port is not None:
|
if port is not None:
|
||||||
command[3:3] = ['-p',str(port)]
|
command_base[1:1] = ['-p',str(port)]
|
||||||
|
|
||||||
|
# Since the key wasn't in _master_keys, we think that master isn't running.
|
||||||
|
# ...but before actually starting a master, we'll double-check. This can
|
||||||
|
# be important because we can't tell that that 'git@myhost.com' is the same
|
||||||
|
# as 'myhost.com' where "User git" is setup in the user's ~/.ssh/config file.
|
||||||
|
check_command = command_base + ['-O','check']
|
||||||
|
try:
|
||||||
|
Trace(': %s', ' '.join(check_command))
|
||||||
|
check_process = subprocess.Popen(check_command,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE)
|
||||||
|
check_process.communicate() # read output, but ignore it...
|
||||||
|
isnt_running = check_process.wait()
|
||||||
|
|
||||||
|
if not isnt_running:
|
||||||
|
# Our double-check found that the master _was_ infact running. Add to
|
||||||
|
# the list of keys.
|
||||||
|
_master_keys.add(key)
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
# Ignore excpetions. We we will fall back to the normal command and print
|
||||||
|
# to the log there.
|
||||||
|
pass
|
||||||
|
|
||||||
|
command = command_base[:1] + \
|
||||||
|
['-M', '-N'] + \
|
||||||
|
command_base[1:]
|
||||||
try:
|
try:
|
||||||
Trace(': %s', ' '.join(command))
|
Trace(': %s', ' '.join(command))
|
||||||
p = subprocess.Popen(command)
|
p = subprocess.Popen(command)
|
||||||
@ -396,20 +423,22 @@ def _open_ssh(host, port=None):
|
|||||||
% (host,port, str(e))
|
% (host,port, str(e))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
_ssh_cache[key] = p
|
_master_processes.append(p)
|
||||||
|
_master_keys.add(key)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def close_ssh():
|
def close_ssh():
|
||||||
terminate_ssh_clients()
|
terminate_ssh_clients()
|
||||||
|
|
||||||
for key,p in _ssh_cache.iteritems():
|
for p in _master_processes:
|
||||||
try:
|
try:
|
||||||
os.kill(p.pid, SIGTERM)
|
os.kill(p.pid, SIGTERM)
|
||||||
p.wait()
|
p.wait()
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
_ssh_cache.clear()
|
del _master_processes[:]
|
||||||
|
_master_keys.clear()
|
||||||
|
|
||||||
d = ssh_sock(create=False)
|
d = ssh_sock(create=False)
|
||||||
if d:
|
if d:
|
||||||
|
Loading…
Reference in New Issue
Block a user