summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--git_config.py53
1 files changed, 41 insertions, 12 deletions
diff --git a/git_config.py b/git_config.py
index 1382d5db..138470c5 100644
--- a/git_config.py
+++ b/git_config.py
@@ -356,18 +356,21 @@ class RefSpec(object):
356 return s 356 return s
357 357
358 358
359_ssh_cache = {} 359_master_processes = []
360_master_keys = set()
360_ssh_master = True 361_ssh_master = True
361 362
362def _open_ssh(host, port=None): 363def _open_ssh(host, port=None):
363 global _ssh_master 364 global _ssh_master
364 365
366 # Check to see whether we already think that the master is running; if we
367 # think it's already running, return right away.
365 if port is not None: 368 if port is not None:
366 key = '%s:%s' % (host, port) 369 key = '%s:%s' % (host, port)
367 else: 370 else:
368 key = host 371 key = host
369 372
370 if key in _ssh_cache: 373 if key in _master_keys:
371 return True 374 return True
372 375
373 if not _ssh_master \ 376 if not _ssh_master \
@@ -377,15 +380,39 @@ def _open_ssh(host, port=None):
377 # 380 #
378 return False 381 return False
379 382
380 command = ['ssh', 383 # We will make two calls to ssh; this is the common part of both calls.
381 '-o','ControlPath %s' % ssh_sock(), 384 command_base = ['ssh',
382 '-M', 385 '-o','ControlPath %s' % ssh_sock(),
383 '-N', 386 host]
384 host]
385
386 if port is not None: 387 if port is not None:
387 command[3:3] = ['-p',str(port)] 388 command_base[1:1] = ['-p',str(port)]
388 389
390 # Since the key wasn't in _master_keys, we think that master isn't running.
391 # ...but before actually starting a master, we'll double-check. This can
392 # be important because we can't tell that that 'git@myhost.com' is the same
393 # as 'myhost.com' where "User git" is setup in the user's ~/.ssh/config file.
394 check_command = command_base + ['-O','check']
395 try:
396 Trace(': %s', ' '.join(check_command))
397 check_process = subprocess.Popen(check_command,
398 stdout=subprocess.PIPE,
399 stderr=subprocess.PIPE)
400 check_process.communicate() # read output, but ignore it...
401 isnt_running = check_process.wait()
402
403 if not isnt_running:
404 # Our double-check found that the master _was_ infact running. Add to
405 # the list of keys.
406 _master_keys.add(key)
407 return True
408 except Exception:
409 # Ignore excpetions. We we will fall back to the normal command and print
410 # to the log there.
411 pass
412
413 command = command_base[:1] + \
414 ['-M', '-N'] + \
415 command_base[1:]
389 try: 416 try:
390 Trace(': %s', ' '.join(command)) 417 Trace(': %s', ' '.join(command))
391 p = subprocess.Popen(command) 418 p = subprocess.Popen(command)
@@ -396,20 +423,22 @@ def _open_ssh(host, port=None):
396 % (host,port, str(e)) 423 % (host,port, str(e))
397 return False 424 return False
398 425
399 _ssh_cache[key] = p 426 _master_processes.append(p)
427 _master_keys.add(key)
400 time.sleep(1) 428 time.sleep(1)
401 return True 429 return True
402 430
403def close_ssh(): 431def close_ssh():
404 terminate_ssh_clients() 432 terminate_ssh_clients()
405 433
406 for key,p in _ssh_cache.iteritems(): 434 for p in _master_processes:
407 try: 435 try:
408 os.kill(p.pid, SIGTERM) 436 os.kill(p.pid, SIGTERM)
409 p.wait() 437 p.wait()
410 except OSError: 438 except OSError:
411 pass 439 pass
412 _ssh_cache.clear() 440 del _master_processes[:]
441 _master_keys.clear()
413 442
414 d = ssh_sock(create=False) 443 d = ssh_sock(create=False)
415 if d: 444 if d: