summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2012-01-11 14:58:54 -0800
committerShawn O. Pearce <sop@google.com>2012-01-11 16:18:40 -0800
commitc9571423f843340de19ef576ccaa418ac72fdb58 (patch)
tree938fdcdde76dfc1cc8b299e0f6d96648242902e1
parent34fb20f67c7bdca2b1321a40f2fd558f9a34d866 (diff)
downloadgit-repo-c9571423f843340de19ef576ccaa418ac72fdb58.tar.gz
upload: Support uploading to Gerrit over https://v1.7.8.2
If SSH is not available, Gerrit returns NOT_AVAILABLE to the /ssh_info query made by repo upload. In this case fallback to the /p/$PROJECT URL that Gerrit also exports and use that for uploads. Change-Id: I1e3e39ab709ecc0a692614a41a42446426f39c08
-rw-r--r--git_config.py75
-rw-r--r--project.py31
2 files changed, 42 insertions, 64 deletions
diff --git a/git_config.py b/git_config.py
index a52677cf..17937649 100644
--- a/git_config.py
+++ b/git_config.py
@@ -527,7 +527,7 @@ class Remote(object):
527 self.projectname = self._Get('projectname') 527 self.projectname = self._Get('projectname')
528 self.fetch = map(lambda x: RefSpec.FromString(x), 528 self.fetch = map(lambda x: RefSpec.FromString(x),
529 self._Get('fetch', all=True)) 529 self._Get('fetch', all=True))
530 self._review_protocol = None 530 self._review_url = None
531 531
532 def _InsteadOf(self): 532 def _InsteadOf(self):
533 globCfg = GitConfig.ForUser() 533 globCfg = GitConfig.ForUser()
@@ -554,9 +554,8 @@ class Remote(object):
554 connectionUrl = self._InsteadOf() 554 connectionUrl = self._InsteadOf()
555 return _preconnect(connectionUrl) 555 return _preconnect(connectionUrl)
556 556
557 @property 557 def ReviewUrl(self, userEmail):
558 def ReviewProtocol(self): 558 if self._review_url is None:
559 if self._review_protocol is None:
560 if self.review is None: 559 if self.review is None:
561 return None 560 return None
562 561
@@ -565,67 +564,47 @@ class Remote(object):
565 u = 'http://%s' % u 564 u = 'http://%s' % u
566 if u.endswith('/Gerrit'): 565 if u.endswith('/Gerrit'):
567 u = u[:len(u) - len('/Gerrit')] 566 u = u[:len(u) - len('/Gerrit')]
568 if not u.endswith('/ssh_info'): 567 if u.endswith('/ssh_info'):
569 if not u.endswith('/'): 568 u = u[:len(u) - len('/ssh_info')]
570 u += '/' 569 if not u.endswith('/'):
571 u += 'ssh_info' 570 u += '/'
571 http_url = u
572 572
573 if u in REVIEW_CACHE: 573 if u in REVIEW_CACHE:
574 info = REVIEW_CACHE[u] 574 self._review_url = REVIEW_CACHE[u]
575 self._review_protocol = info[0]
576 self._review_host = info[1]
577 self._review_port = info[2]
578 elif 'REPO_HOST_PORT_INFO' in os.environ: 575 elif 'REPO_HOST_PORT_INFO' in os.environ:
579 info = os.environ['REPO_HOST_PORT_INFO'] 576 host, port = os.environ['REPO_HOST_PORT_INFO'].split()
580 self._review_protocol = 'ssh' 577 self._review_url = self._SshReviewUrl(userEmail, host, port)
581 self._review_host = info.split(" ")[0] 578 REVIEW_CACHE[u] = self._review_url
582 self._review_port = info.split(" ")[1]
583
584 REVIEW_CACHE[u] = (
585 self._review_protocol,
586 self._review_host,
587 self._review_port)
588 else: 579 else:
589 try: 580 try:
590 info = urllib2.urlopen(u).read() 581 info_url = u + 'ssh_info'
591 if info == 'NOT_AVAILABLE': 582 info = urllib2.urlopen(info_url).read()
592 raise UploadError('%s: SSH disabled' % self.review)
593 if '<' in info: 583 if '<' in info:
594 # Assume the server gave us some sort of HTML 584 # Assume the server gave us some sort of HTML
595 # response back, like maybe a login page. 585 # response back, like maybe a login page.
596 # 586 #
597 raise UploadError('%s: Cannot parse response' % u) 587 raise UploadError('%s: Cannot parse response' % info_url)
598 588
599 self._review_protocol = 'ssh' 589 if info == 'NOT_AVAILABLE':
600 self._review_host = info.split(" ")[0] 590 # Assume HTTP if SSH is not enabled.
601 self._review_port = info.split(" ")[1] 591 self._review_url = http_url + 'p/'
602 except urllib2.HTTPError, e:
603 if e.code == 404:
604 self._review_protocol = 'http-post'
605 self._review_host = None
606 self._review_port = None
607 else: 592 else:
608 raise UploadError('Upload over SSH unavailable') 593 host, port = info.split()
594 self._review_url = self._SshReviewUrl(userEmail, host, port)
595 except urllib2.HTTPError, e:
596 raise UploadError('%s: %s' % (self.review, str(e)))
609 except urllib2.URLError, e: 597 except urllib2.URLError, e:
610 raise UploadError('%s: %s' % (self.review, str(e))) 598 raise UploadError('%s: %s' % (self.review, str(e)))
611 599
612 REVIEW_CACHE[u] = ( 600 REVIEW_CACHE[u] = self._review_url
613 self._review_protocol, 601 return self._review_url + self.projectname
614 self._review_host,
615 self._review_port)
616 return self._review_protocol
617 602
618 def SshReviewUrl(self, userEmail): 603 def _SshReviewUrl(self, userEmail, host, port):
619 if self.ReviewProtocol != 'ssh':
620 return None
621 username = self._config.GetString('review.%s.username' % self.review) 604 username = self._config.GetString('review.%s.username' % self.review)
622 if username is None: 605 if username is None:
623 username = userEmail.split("@")[0] 606 username = userEmail.split('@')[0]
624 return 'ssh://%s@%s:%s/%s' % ( 607 return 'ssh://%s@%s:%s/' % (username, host, port)
625 username,
626 self._review_host,
627 self._review_port,
628 self.projectname)
629 608
630 def ToLocal(self, rev): 609 def ToLocal(self, rev):
631 """Convert a remote revision string to something we have locally. 610 """Convert a remote revision string to something we have locally.
diff --git a/project.py b/project.py
index 8b9a3fc4..f48472b4 100644
--- a/project.py
+++ b/project.py
@@ -866,31 +866,30 @@ class Project(object):
866 branch.remote.projectname = self.name 866 branch.remote.projectname = self.name
867 branch.remote.Save() 867 branch.remote.Save()
868 868
869 if branch.remote.ReviewProtocol == 'ssh': 869 url = branch.remote.ReviewUrl(self.UserEmail)
870 if dest_branch.startswith(R_HEADS): 870 if url is None:
871 dest_branch = dest_branch[len(R_HEADS):] 871 raise UploadError('review not configured')
872 cmd = ['push']
872 873
874 if url.startswith('ssh://'):
873 rp = ['gerrit receive-pack'] 875 rp = ['gerrit receive-pack']
874 for e in people[0]: 876 for e in people[0]:
875 rp.append('--reviewer=%s' % sq(e)) 877 rp.append('--reviewer=%s' % sq(e))
876 for e in people[1]: 878 for e in people[1]:
877 rp.append('--cc=%s' % sq(e)) 879 rp.append('--cc=%s' % sq(e))
878
879 ref_spec = '%s:refs/for/%s' % (R_HEADS + branch.name, dest_branch)
880 if auto_topic:
881 ref_spec = ref_spec + '/' + branch.name
882
883 cmd = ['push']
884 cmd.append('--receive-pack=%s' % " ".join(rp)) 880 cmd.append('--receive-pack=%s' % " ".join(rp))
885 cmd.append(branch.remote.SshReviewUrl(self.UserEmail))
886 cmd.append(ref_spec)
887 881
888 if GitCommand(self, cmd, bare = True).Wait() != 0: 882 cmd.append(url)
889 raise UploadError('Upload failed')
890 883
891 else: 884 if dest_branch.startswith(R_HEADS):
892 raise UploadError('Unsupported protocol %s' \ 885 dest_branch = dest_branch[len(R_HEADS):]
893 % branch.remote.review) 886 ref_spec = '%s:refs/for/%s' % (R_HEADS + branch.name, dest_branch)
887 if auto_topic:
888 ref_spec = ref_spec + '/' + branch.name
889 cmd.append(ref_spec)
890
891 if GitCommand(self, cmd, bare = True).Wait() != 0:
892 raise UploadError('Upload failed')
894 893
895 msg = "posted to %s for %s" % (branch.remote.review, dest_branch) 894 msg = "posted to %s for %s" % (branch.remote.review, dest_branch)
896 self.bare_git.UpdateRef(R_PUB + branch.name, 895 self.bare_git.UpdateRef(R_PUB + branch.name,