diff options
Diffstat (limited to 'git_config.py')
| -rw-r--r-- | git_config.py | 67 |
1 files changed, 52 insertions, 15 deletions
diff --git a/git_config.py b/git_config.py index 4a42c047..286e89ca 100644 --- a/git_config.py +++ b/git_config.py | |||
| @@ -25,7 +25,10 @@ from signal import SIGTERM | |||
| 25 | from urllib2 import urlopen, HTTPError | 25 | from urllib2 import urlopen, HTTPError |
| 26 | from error import GitError, UploadError | 26 | from error import GitError, UploadError |
| 27 | from trace import Trace | 27 | from trace import Trace |
| 28 | from git_command import GitCommand, _ssh_sock | 28 | |
| 29 | from git_command import GitCommand | ||
| 30 | from git_command import ssh_sock | ||
| 31 | from git_command import terminate_ssh_clients | ||
| 29 | 32 | ||
| 30 | R_HEADS = 'refs/heads/' | 33 | R_HEADS = 'refs/heads/' |
| 31 | R_TAGS = 'refs/tags/' | 34 | R_TAGS = 'refs/tags/' |
| @@ -365,18 +368,21 @@ class RefSpec(object): | |||
| 365 | return s | 368 | return s |
| 366 | 369 | ||
| 367 | 370 | ||
| 368 | _ssh_cache = {} | 371 | _master_processes = [] |
| 372 | _master_keys = set() | ||
| 369 | _ssh_master = True | 373 | _ssh_master = True |
| 370 | 374 | ||
| 371 | def _open_ssh(host, port=None): | 375 | def _open_ssh(host, port=None): |
| 372 | global _ssh_master | 376 | global _ssh_master |
| 373 | 377 | ||
| 378 | # Check to see whether we already think that the master is running; if we | ||
| 379 | # think it's already running, return right away. | ||
| 374 | if port is not None: | 380 | if port is not None: |
| 375 | key = '%s:%s' % (host, port) | 381 | key = '%s:%s' % (host, port) |
| 376 | else: | 382 | else: |
| 377 | key = host | 383 | key = host |
| 378 | 384 | ||
| 379 | if key in _ssh_cache: | 385 | if key in _master_keys: |
| 380 | return True | 386 | return True |
| 381 | 387 | ||
| 382 | if not _ssh_master \ | 388 | if not _ssh_master \ |
| @@ -386,15 +392,39 @@ def _open_ssh(host, port=None): | |||
| 386 | # | 392 | # |
| 387 | return False | 393 | return False |
| 388 | 394 | ||
| 389 | command = ['ssh', | 395 | # We will make two calls to ssh; this is the common part of both calls. |
| 390 | '-o','ControlPath %s' % _ssh_sock(), | 396 | command_base = ['ssh', |
| 391 | '-M', | 397 | '-o','ControlPath %s' % ssh_sock(), |
| 392 | '-N', | 398 | host] |
| 393 | host] | ||
| 394 | |||
| 395 | if port is not None: | 399 | if port is not None: |
| 396 | command[3:3] = ['-p',str(port)] | 400 | command_base[1:1] = ['-p',str(port)] |
| 397 | 401 | ||
| 402 | # Since the key wasn't in _master_keys, we think that master isn't running. | ||
| 403 | # ...but before actually starting a master, we'll double-check. This can | ||
| 404 | # be important because we can't tell that that 'git@myhost.com' is the same | ||
| 405 | # as 'myhost.com' where "User git" is setup in the user's ~/.ssh/config file. | ||
| 406 | check_command = command_base + ['-O','check'] | ||
| 407 | try: | ||
| 408 | Trace(': %s', ' '.join(check_command)) | ||
| 409 | check_process = subprocess.Popen(check_command, | ||
| 410 | stdout=subprocess.PIPE, | ||
| 411 | stderr=subprocess.PIPE) | ||
| 412 | check_process.communicate() # read output, but ignore it... | ||
| 413 | isnt_running = check_process.wait() | ||
| 414 | |||
| 415 | if not isnt_running: | ||
| 416 | # Our double-check found that the master _was_ infact running. Add to | ||
| 417 | # the list of keys. | ||
| 418 | _master_keys.add(key) | ||
| 419 | return True | ||
| 420 | except Exception: | ||
| 421 | # Ignore excpetions. We we will fall back to the normal command and print | ||
| 422 | # to the log there. | ||
| 423 | pass | ||
| 424 | |||
| 425 | command = command_base[:1] + \ | ||
| 426 | ['-M', '-N'] + \ | ||
| 427 | command_base[1:] | ||
| 398 | try: | 428 | try: |
| 399 | Trace(': %s', ' '.join(command)) | 429 | Trace(': %s', ' '.join(command)) |
| 400 | p = subprocess.Popen(command) | 430 | p = subprocess.Popen(command) |
| @@ -405,20 +435,24 @@ def _open_ssh(host, port=None): | |||
| 405 | % (host,port, str(e)) | 435 | % (host,port, str(e)) |
| 406 | return False | 436 | return False |
| 407 | 437 | ||
| 408 | _ssh_cache[key] = p | 438 | _master_processes.append(p) |
| 439 | _master_keys.add(key) | ||
| 409 | time.sleep(1) | 440 | time.sleep(1) |
| 410 | return True | 441 | return True |
| 411 | 442 | ||
| 412 | def close_ssh(): | 443 | def close_ssh(): |
| 413 | for key,p in _ssh_cache.iteritems(): | 444 | terminate_ssh_clients() |
| 445 | |||
| 446 | for p in _master_processes: | ||
| 414 | try: | 447 | try: |
| 415 | os.kill(p.pid, SIGTERM) | 448 | os.kill(p.pid, SIGTERM) |
| 416 | p.wait() | 449 | p.wait() |
| 417 | except OSError: | 450 | except OSError: |
| 418 | pass | 451 | pass |
| 419 | _ssh_cache.clear() | 452 | del _master_processes[:] |
| 453 | _master_keys.clear() | ||
| 420 | 454 | ||
| 421 | d = _ssh_sock(create=False) | 455 | d = ssh_sock(create=False) |
| 422 | if d: | 456 | if d: |
| 423 | try: | 457 | try: |
| 424 | os.rmdir(os.path.dirname(d)) | 458 | os.rmdir(os.path.dirname(d)) |
| @@ -540,8 +574,11 @@ class Remote(object): | |||
| 540 | def SshReviewUrl(self, userEmail): | 574 | def SshReviewUrl(self, userEmail): |
| 541 | if self.ReviewProtocol != 'ssh': | 575 | if self.ReviewProtocol != 'ssh': |
| 542 | return None | 576 | return None |
| 577 | username = self._config.GetString('review.%s.username' % self.review) | ||
| 578 | if username is None: | ||
| 579 | username = userEmail.split("@")[0] | ||
| 543 | return 'ssh://%s@%s:%s/%s' % ( | 580 | return 'ssh://%s@%s:%s/%s' % ( |
| 544 | userEmail.split("@")[0], | 581 | username, |
| 545 | self._review_host, | 582 | self._review_host, |
| 546 | self._review_port, | 583 | self._review_port, |
| 547 | self.projectname) | 584 | self.projectname) |
