Beispiel #1
0
    def ReviewUrl(self, userEmail, validate_certs):
        if self._review_url is None:
            if self.review is None:
                return None

            u = self.review
            if u.startswith('persistent-'):
                u = u[len('persistent-'):]
            if u.split(':')[0] not in ('http', 'https', 'sso', 'ssh'):
                u = 'http://%s' % u
            if u.endswith('/Gerrit'):
                u = u[:len(u) - len('/Gerrit')]
            if u.endswith('/ssh_info'):
                u = u[:len(u) - len('/ssh_info')]
            if not u.endswith('/'):
                u += '/'
            http_url = u

            if u in REVIEW_CACHE:
                self._review_url = REVIEW_CACHE[u]
            elif 'REPO_HOST_PORT_INFO' in os.environ:
                host, port = os.environ['REPO_HOST_PORT_INFO'].split()
                self._review_url = self._SshReviewUrl(userEmail, host, port)
                REVIEW_CACHE[u] = self._review_url
            elif u.startswith('sso:') or u.startswith('ssh:'):
                self._review_url = u  # Assume it's right
                REVIEW_CACHE[u] = self._review_url
            elif 'REPO_IGNORE_SSH_INFO' in os.environ:
                self._review_url = http_url
                REVIEW_CACHE[u] = self._review_url
            else:
                try:
                    info_url = u + 'ssh_info'
                    if not validate_certs:
                        context = ssl._create_unverified_context()
                        info = urllib.request.urlopen(info_url,
                                                      context=context).read()
                    else:
                        info = urllib.request.urlopen(info_url).read()
                    if info == 'NOT_AVAILABLE' or '<' in info:
                        # If `info` contains '<', we assume the server gave us some sort
                        # of HTML response back, like maybe a login page.
                        #
                        # Assume HTTP if SSH is not enabled or ssh_info doesn't look right.
                        self._review_url = http_url
                    else:
                        host, port = info.split()
                        self._review_url = self._SshReviewUrl(
                            userEmail, host, port)
                except urllib.error.HTTPError as e:
                    raise UploadError('%s: %s' % (self.review, str(e)))
                except urllib.error.URLError as e:
                    raise UploadError('%s: %s' % (self.review, str(e)))
                except HTTPException as e:
                    raise UploadError('%s: %s' %
                                      (self.review, e.__class__.__name__))

                REVIEW_CACHE[u] = self._review_url
        return self._review_url + self.projectname
Beispiel #2
0
    def ReviewUrl(self, userEmail, validate_certs):
        if self._review_url is None:
            if self.review is None:
                return None

            u = self.review
            if u.startswith("persistent-"):
                u = u[len("persistent-") :]
            if u.split(":")[0] not in ("http", "https", "sso", "ssh"):
                u = "http://%s" % u
            if u.endswith("/Gerrit"):
                u = u[: len(u) - len("/Gerrit")]
            if u.endswith("/ssh_info"):
                u = u[: len(u) - len("/ssh_info")]
            if not u.endswith("/"):
                u += "/"
            http_url = u

            if u in REVIEW_CACHE:
                self._review_url = REVIEW_CACHE[u]
            elif "REPO_HOST_PORT_INFO" in os.environ:
                host, port = os.environ["REPO_HOST_PORT_INFO"].split()
                self._review_url = self._SshReviewUrl(userEmail, host, port)
                REVIEW_CACHE[u] = self._review_url
            elif u.startswith("sso:") or u.startswith("ssh:"):
                self._review_url = u  # Assume it's right
                REVIEW_CACHE[u] = self._review_url
            elif "REPO_IGNORE_SSH_INFO" in os.environ:
                self._review_url = http_url
                REVIEW_CACHE[u] = self._review_url
            else:
                try:
                    info_url = u + "ssh_info"
                    if not validate_certs:
                        context = ssl._create_unverified_context()
                        info = urllib.request.urlopen(info_url, context=context).read()
                    else:
                        info = urllib.request.urlopen(info_url).read()
                    if info == b"NOT_AVAILABLE" or b"<" in info:
                        # If `info` contains '<', we assume the server gave us some sort
                        # of HTML response back, like maybe a login page.
                        #
                        # Assume HTTP if SSH is not enabled or ssh_info doesn't look right.
                        self._review_url = http_url
                    else:
                        info = info.decode("utf-8")
                        host, port = info.split()
                        self._review_url = self._SshReviewUrl(userEmail, host, port)
                except urllib.error.HTTPError as e:
                    raise UploadError("%s: %s" % (self.review, str(e)))
                except urllib.error.URLError as e:
                    raise UploadError("%s: %s" % (self.review, str(e)))
                except HTTPException as e:
                    raise UploadError("%s: %s" % (self.review, e.__class__.__name__))

                REVIEW_CACHE[u] = self._review_url
        return self._review_url + self.projectname
Beispiel #3
0
    def UploadForReview(self,
                        branch=None,
                        replace_changes=None,
                        people=([], [])):
        """Uploads the named branch for code review.
    """
        if branch is None:
            branch = self.CurrentBranch
        if branch is None:
            raise GitError('not currently on a branch')

        branch = self.GetBranch(branch)
        if not branch.LocalMerge:
            raise GitError('branch %s does not track a remote' % branch.name)
        if not branch.remote.review:
            raise GitError('remote %s has no review url' % branch.remote.name)

        dest_branch = branch.merge
        if not dest_branch.startswith(R_HEADS):
            dest_branch = R_HEADS + dest_branch

        if not branch.remote.projectname:
            branch.remote.projectname = self.name
            branch.remote.Save()

        if branch.remote.ReviewProtocol == 'ssh':
            if dest_branch.startswith(R_HEADS):
                dest_branch = dest_branch[len(R_HEADS):]

            rp = ['gerrit receive-pack']
            for e in people[0]:
                rp.append('--reviewer=%s' % sq(e))
            for e in people[1]:
                rp.append('--cc=%s' % sq(e))

            cmd = ['push']
            cmd.append('--receive-pack=%s' % " ".join(rp))
            cmd.append(branch.remote.SshReviewUrl(self.UserEmail))
            cmd.append('%s:refs/for/%s' % (R_HEADS + branch.name, dest_branch))
            if replace_changes:
                for change_id, commit_id in replace_changes.iteritems():
                    cmd.append('%s:refs/changes/%s/new' %
                               (commit_id, change_id))
            if GitCommand(self, cmd, bare=True).Wait() != 0:
                raise UploadError('Upload failed')

        else:
            raise UploadError('Unsupported protocol %s' \
              % branch.remote.review)

        msg = "posted to %s for %s" % (branch.remote.review, dest_branch)
        self.bare_git.UpdateRef(R_PUB + branch.name,
                                R_HEADS + branch.name,
                                message=msg)
Beispiel #4
0
    def ReviewProtocol(self):
        if self._review_protocol is None:
            if self.review is None:
                return None

            u = self.review
            if not u.startswith('http:') and not u.startswith('https:'):
                u = 'http://%s' % u
            if u.endswith('/Gerrit'):
                u = u[:len(u) - len('/Gerrit')]
            if not u.endswith('/ssh_info'):
                if not u.endswith('/'):
                    u += '/'
                u += 'ssh_info'

            if u in REVIEW_CACHE:
                info = REVIEW_CACHE[u]
                self._review_protocol = info[0]
                self._review_host = info[1]
                self._review_port = info[2]
            elif 'REPO_HOST_PORT_INFO' in os.environ:
                info = os.environ['REPO_HOST_PORT_INFO']
                self._review_protocol = 'ssh'
                self._review_host = info.split(" ")[0]
                self._review_port = info.split(" ")[1]

                REVIEW_CACHE[u] = (self._review_protocol, self._review_host,
                                   self._review_port)
            else:
                try:
                    info = urllib2.urlopen(u).read()
                    if info == 'NOT_AVAILABLE':
                        raise UploadError('%s: SSH disabled' % self.review)
                    if '<' in info:
                        # Assume the server gave us some sort of HTML
                        # response back, like maybe a login page.
                        #
                        raise UploadError('%s: Cannot parse response' % u)

                    self._review_protocol = 'ssh'
                    self._review_host = info.split(" ")[0]
                    self._review_port = info.split(" ")[1]
                except urllib2.HTTPError, e:
                    if e.code == 404:
                        self._review_protocol = 'http-post'
                        self._review_host = None
                        self._review_port = None
                    else:
                        raise UploadError('Upload over SSH unavailable')
                except urllib2.URLError, e:
                    raise UploadError('%s: %s' % (self.review, str(e)))

                REVIEW_CACHE[u] = (self._review_protocol, self._review_host,
                                   self._review_port)
Beispiel #5
0
    def ReviewUrl(self, userEmail):
        if self._review_url is None:
            if self.review is None:
                return None

            u = self.review
            if not u.startswith('http:') and not u.startswith('https:'):
                u = 'http://%s' % u
            if u.endswith('/Gerrit'):
                u = u[:len(u) - len('/Gerrit')]
            if u.endswith('/ssh_info'):
                u = u[:len(u) - len('/ssh_info')]
            if not u.endswith('/'):
                u += '/'
            http_url = u

            if u in REVIEW_CACHE:
                self._review_url = REVIEW_CACHE[u]
            elif 'REPO_HOST_PORT_INFO' in os.environ:
                host, port = os.environ['REPO_HOST_PORT_INFO'].split()
                self._review_url = self._SshReviewUrl(userEmail, host, port)
                REVIEW_CACHE[u] = self._review_url
            else:
                try:
                    info_url = u + 'ssh_info'
                    info = urllib.request.urlopen(info_url).read()
                    if '<' in info:
                        # Assume the server gave us some sort of HTML
                        # response back, like maybe a login page.
                        #
                        raise UploadError('%s: Cannot parse response' %
                                          info_url)

                    if info == 'NOT_AVAILABLE':
                        # Assume HTTP if SSH is not enabled.
                        self._review_url = http_url + 'p/'
                    else:
                        host, port = info.split()
                        self._review_url = self._SshReviewUrl(
                            userEmail, host, port)
                except urllib.error.HTTPError as e:
                    raise UploadError('%s: %s' % (self.review, str(e)))
                except urllib.error.URLError as e:
                    raise UploadError('%s: %s' % (self.review, str(e)))

                REVIEW_CACHE[u] = self._review_url
        return self._review_url + self.projectname
Beispiel #6
0
  def ReviewProtocol(self):
    if self._review_protocol is None:
      if self.review is None:
        return None

      u = self.review
      if not u.startswith('http:') and not u.startswith('https:'):
        u = 'http://%s' % u
      if u.endswith('/Gerrit'):
        u = u[:len(u) - len('/Gerrit')]
      if not u.endswith('/ssh_info'):
        if not u.endswith('/'):
          u += '/'
        u += 'ssh_info'

      if u in REVIEW_CACHE:
        info = REVIEW_CACHE[u]
        self._review_protocol = info[0]
        self._review_host = info[1]
        self._review_port = info[2]
      else:
        try:
          info = urlopen(u).read()
          if info == 'NOT_AVAILABLE':
            raise UploadError('Upload over ssh unavailable')
          if '<' in info:
            # Assume the server gave us some sort of HTML
            # response back, like maybe a login page.
            #
            raise UploadError('Cannot read %s:\n%s' % (u, info))

          self._review_protocol = 'ssh'
          self._review_host = info.split(" ")[0]
          self._review_port = info.split(" ")[1]
        except HTTPError, e:
          if e.code == 404:
            self._review_protocol = 'http-post'
            self._review_host = None
            self._review_port = None
          else:
            raise UploadError('Cannot guess Gerrit version')

        REVIEW_CACHE[u] = (
          self._review_protocol,
          self._review_host,
          self._review_port)
Beispiel #7
0
    def Push(self, branch_base, branch=None, dest_branch=None, force=False):
        """Pushs the named branch.
    """
        project = branch_base.project
        if branch is None:
            branch = project.CurrentBranch
        if branch is None:
            raise GitError('not currently on a branch')

        branch = project.GetBranch(branch)
        if not branch.LocalMerge:
            raise GitError('branch %s does not track a remote' % branch.name)

        if dest_branch is None:
            dest_branch = project.dest_branch
        if dest_branch is None:
            dest_branch = branch.merge
        if not dest_branch.startswith(R_HEADS):
            dest_branch = R_HEADS + dest_branch

        if not branch.remote.projectname:
            branch.remote.projectname = project.name
            branch.remote.Save()

        remote = branch.remote.name
        cmd = ['push']

        if force:
            cmd.append('--force')

        cmd.append(remote)

        if dest_branch.startswith(R_HEADS):
            dest_branch = dest_branch[len(R_HEADS):]

        push_type = 'heads'
        ref_spec = '%s:refs/%s/%s' % (R_HEADS + branch.name, push_type,
                                      dest_branch)
        cmd.append(ref_spec)

        if GitCommand(project, cmd, bare=True).Wait() != 0:
            raise UploadError('Push failed')
Beispiel #8
0
    def ReviewUrl(self, userEmail):
        if self._review_url is None:
            if self.review is None:
                return None

            u = self.review
            if u.endswith('/Gerrit'):
                u = u[:len(u) - len('/Gerrit')]
            if u.endswith('/ssh_info'):
                u = u[:len(u) - len('/ssh_info')]
            if not u.endswith('/'):
                u += '/'

            if u in REVIEW_CACHE:
                self._review_url = REVIEW_CACHE[u]
            elif 'REPO_HOST_PORT_INFO' in os.environ:
                host, port = os.environ['REPO_HOST_PORT_INFO'].split()
                self._review_url = self._SshReviewUrl(userEmail, host, port)
                REVIEW_CACHE[u] = self._review_url
            else:
                try:
                    # NOTE: contrary to original repo: do not switch automatically to ssh, since this is contra-intuitive
                    # try to fetch ssh infos from http gerrit server if protocol not specified
                    protocolSeperator = "://"
                    protocolSepIndex = u.find(protocolSeperator)
                    if protocolSepIndex == -1:
                        protocols = ["http", "https"]
                        for prefix in protocols:
                            http_url = '%s://%s' % (prefix, u)
                            info_url = http_url + 'ssh_info'
                            info = None
                            try:
                                info = portable.stream2str(
                                    urllib.request.urlopen(info_url).read())
                                if '<' in info:
                                    # Assume the server gave us some sort of HTML
                                    # response back, like maybe a login page.
                                    #
                                    raise UploadError(
                                        '%s: Cannot parse response' % info_url)
                                if info != 'NOT_AVAILABLE':
                                    host, port = info.split()
                                    self._review_url = self._SshReviewUrl(
                                        userEmail, host, port)

                            except Exception as e:
                                Trace(
                                    "could not get ssh infos of %s from %s (received %s), error %s",
                                    u, info_url, info, e)
                                info = 'NOT_AVAILABLE'

                        if not self._review_url:
                            # Assume HTTP if SSH is not enabled.
                            self._review_url = http_url + 'p/'
                            Trace(
                                "warning: proceed upload with http url %s since no protocol given and no infos could be retrieved from %s",
                                self._review_url, info_url)

                        print("detected %s as review url" % self._review_url)
                    else:
                        self._review_url = u
                except urllib.error.HTTPError as e:
                    raise UploadError('%s: %s' % (self.review, str(e)))
                except urllib.error.URLError as e:
                    raise UploadError('%s: %s' % (self.review, str(e)))

                REVIEW_CACHE[u] = self._review_url
        return self._review_url + self.projectname