Exemple #1
0
 def verify(self, data, sig):
     """ returns of the good and bad signatures"""
     sigfile = datafile = None
     try:
         # create temporary files
         fd, sigfile = tempfile.mkstemp(prefix="hg-gpg-", suffix=".sig")
         fp = util.fdopen(fd, "wb")
         fp.write(sig)
         fp.close()
         fd, datafile = tempfile.mkstemp(prefix="hg-gpg-", suffix=".txt")
         fp = util.fdopen(fd, "wb")
         fp.write(data)
         fp.close()
         gpgcmd = "%s --logger-fd 1 --status-fd 1 --verify " '"%s" "%s"' % (
             self.path,
             sigfile,
             datafile,
         )
         ret = util.filter("", gpgcmd)
     finally:
         for f in (sigfile, datafile):
             try:
                 if f:
                     os.unlink(f)
             except OSError:
                 pass
     keys = []
     key, fingerprint = None, None
     for l in ret.splitlines():
         # see DETAILS in the gnupg documentation
         # filter the logger output
         if not l.startswith("[GNUPG:]"):
             continue
         l = l[9:]
         if l.startswith("VALIDSIG"):
             # fingerprint of the primary key
             fingerprint = l.split()[10]
         elif l.startswith("ERRSIG"):
             key = l.split(" ", 3)[:2]
             key.append("")
             fingerprint = None
         elif (
             l.startswith("GOODSIG")
             or l.startswith("EXPSIG")
             or l.startswith("EXPKEYSIG")
             or l.startswith("BADSIG")
         ):
             if key is not None:
                 keys.append(key + [fingerprint])
             key = l.split(" ", 2)
             fingerprint = None
     if key is not None:
         keys.append(key + [fingerprint])
     return keys
Exemple #2
0
    def winpopen4(orig, cmd, env=None, newlines=False, bufsize=-1):
        """Same as util.popen4, but manually creates an input pipe with a
        larger than default buffer"""
        import msvcrt

        if sys.version_info[0] < 3:
            import _subprocess

            handles = _subprocess.CreatePipe(None, pipei_bufsize)
            rfd, wfd = [msvcrt.open_osfhandle(h, 0) for h in handles]
        else:
            import _winapi

            handles = _winapi.CreatePipe(None, pipei_bufsize)
            rfd, wfd = [msvcrt.open_osfhandle(h, 0) for h in handles]
            handles = [subprocess.Handle(h) for h in handles]

        handles[0].Detach()
        handles[1].Detach()
        p = subprocess.Popen(
            cmd,
            shell=True,
            bufsize=bufsize,
            close_fds=False,
            stdin=rfd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            universal_newlines=newlines,
            env=env,
        )
        p.stdin = util.fdopen(wfd, "wb", bufsize)
        return p.stdin, p.stdout, p.stderr, p
Exemple #3
0
    def bundle2scratchbranch(op, part):
        """unbundle a bundle2 part containing a changegroup to store"""

        bundler = bundle2.bundle20(op.repo.ui)
        cgversion = part.params.get("cgversion", "01")
        cgpart = bundle2.bundlepart("changegroup", data=part.read())
        cgpart.addparam("version", cgversion)
        bundler.addpart(cgpart)
        buf = util.chunkbuffer(bundler.getchunks())

        fd, bundlefile = tempfile.mkstemp()
        try:
            try:
                fp = util.fdopen(fd, "wb")
                fp.write(buf.read())
            finally:
                fp.close()
            server.storebundle(op, part.params, bundlefile)
        finally:
            try:
                os.unlink(bundlefile)
            except OSError as e:
                if e.errno != errno.ENOENT:
                    raise

        return 1
Exemple #4
0
    def winpopen4(orig, cmd, env=None, newlines=False, bufsize=-1):
        """Same as util.popen4, but manually creates an input pipe with a
        larger than default buffer"""
        import msvcrt

        # pyre-fixme[21]: Could not find module `_subprocess`.
        import _subprocess

        handles = _subprocess.CreatePipe(None, pipei_bufsize)
        rfd, wfd = [msvcrt.open_osfhandle(h, 0) for h in handles]
        handles[0].Detach()
        handles[1].Detach()
        p = subprocess.Popen(
            cmd,
            shell=True,
            bufsize=bufsize,
            close_fds=False,
            stdin=rfd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            universal_newlines=newlines,
            env=env,
        )
        p.stdin = util.fdopen(wfd, "wb", bufsize)
        return p.stdin, p.stdout, p.stderr, p
Exemple #5
0
def rage(ui, repo, *pats, **opts):
    """collect troubleshooting diagnostics

    The rage command collects useful diagnostic information.

    By default, the information will be uploaded to Phabricator and
    instructions about how to ask for help will be printed.

    After submitting to Phabricator, it prints configerable advice::

        [rage]
        advice = Please see our FAQ guide: https://...

    """
    with progress.spinner(ui, "collecting information"):
        msg = _makerage(ui, repo, **opts)

    if opts.get("preview"):
        ui.pager("rage")
        ui.write("%s\n" % msg)
        return

    with progress.spinner(ui, "saving paste"):
        try:
            p = subprocess.Popen(
                ["pastry", "--lang", "hgrage", "--title", "hgrage"],
                stdout=subprocess.PIPE,
                stdin=subprocess.PIPE,
                stderr=subprocess.PIPE,
                shell=pycompat.iswindows,
            )
            out, err = p.communicate(input=msg + "\n")
            ret = p.returncode
        except OSError:
            ui.write(_("Failed calling pastry. (is it in your PATH?)\n"))
            ret = 1

    if ret:
        fd, tmpname = tempfile.mkstemp(prefix="hg-rage-")
        with util.fdopen(fd, r"w") as tmpfp:
            tmpfp.write(msg)
            ui.write(
                _(
                    "Failed to post the diagnostic paste to Phabricator, "
                    "but its contents have been written to:\n\n"
                )
            )
            ui.write(_("  %s\n") % tmpname, label="rage.link")
            ui.write(
                _("\nPlease include this file in the %s.\n")
                % ui.config("ui", "supportcontact")
            )
    else:
        ui.write(
            _("Please post in %s with the following link:\n\n")
            % (ui.config("ui", "supportcontact"))
        )
        ui.write("  " + out + "\n", label="rage.link")
    ui.write(ui.config("rage", "advice", "") + "\n")
Exemple #6
0
def downloadbundle(repo, unknownbinhead):
    index = repo.bundlestore.index
    store = repo.bundlestore.store
    bundleid = index.getbundle(nodemod.hex(unknownbinhead))
    if bundleid is None:
        raise error.Abort("%s head is not known" % nodemod.hex(unknownbinhead))
    data = store.read(bundleid)
    fp = None
    fd, bundlefile = tempfile.mkstemp()
    try:  # guards bundlefile
        try:  # guards fp
            fp = util.fdopen(fd, "wb")
            fp.write(data)
        finally:
            fp.close()
    except Exception:
        try:
            os.unlink(bundlefile)
        except Exception:
            # we would rather see the original exception
            pass
        raise

    return bundlefile
Exemple #7
0
def processparts(orig, repo, op, unbundler):
    if unbundler.params.get("infinitepush") != "True":
        return orig(repo, op, unbundler)

    handleallparts = repo.ui.configbool("infinitepush", "storeallparts")

    partforwardingwhitelist = [constants.scratchmutationparttype]
    try:
        treemfmod = extensions.find("treemanifest")
        partforwardingwhitelist.append(treemfmod.TREEGROUP_PARTTYPE2)
    except KeyError:
        pass

    try:
        snapshot = extensions.find("snapshot")
        partforwardingwhitelist.append(snapshot.bundleparts.snapshotmetadataparttype)
    except KeyError:
        pass

    bundler = bundle2.bundle20(repo.ui)
    compress = repo.ui.config("infinitepush", "bundlecompression", "UN")
    bundler.setcompression(compress)
    cgparams = None
    scratchbookpart = None
    with bundle2.partiterator(repo, op, unbundler) as parts:
        for part in parts:
            bundlepart = None
            if part.type == "replycaps":
                # This configures the current operation to allow reply parts.
                bundle2._processpart(op, part)
            elif part.type == constants.scratchbranchparttype:
                # Scratch branch parts need to be converted to normal
                # changegroup parts, and the extra parameters stored for later
                # when we upload to the store. Eventually those parameters will
                # be put on the actual bundle instead of this part, then we can
                # send a vanilla changegroup instead of the scratchbranch part.
                cgversion = part.params.get("cgversion", "01")
                bundlepart = bundle2.bundlepart("changegroup", data=part.read())
                bundlepart.addparam("version", cgversion)
                cgparams = part.params

                # If we're not dumping all parts into the new bundle, we need to
                # alert the future pushkey and phase-heads handler to skip
                # the part.
                if not handleallparts:
                    op.records.add(
                        constants.scratchbranchparttype + "_skippushkey", True
                    )
                    op.records.add(
                        constants.scratchbranchparttype + "_skipphaseheads", True
                    )
            elif part.type == constants.scratchbookmarksparttype:
                # Save this for later processing. Details below.
                #
                # Upstream https://phab.mercurial-scm.org/D1389 and its
                # follow-ups stop part.seek support to reduce memory usage
                # (https://bz.mercurial-scm.org/5691). So we need to copy
                # the part so it can be consumed later.
                scratchbookpart = copiedpart(part)
            else:
                if handleallparts or part.type in partforwardingwhitelist:
                    # Ideally we would not process any parts, and instead just
                    # forward them to the bundle for storage, but since this
                    # differs from previous behavior, we need to put it behind a
                    # config flag for incremental rollout.
                    bundlepart = bundle2.bundlepart(part.type, data=part.read())
                    for key, value in pycompat.iteritems(part.params):
                        bundlepart.addparam(key, value)

                    # Certain parts require a response
                    if part.type == "pushkey":
                        if op.reply is not None:
                            rpart = op.reply.newpart("reply:pushkey")
                            rpart.addparam("in-reply-to", str(part.id), mandatory=False)
                            rpart.addparam("return", "1", mandatory=False)
                else:
                    bundle2._processpart(op, part)

            if handleallparts:
                op.records.add(part.type, {"return": 1})
            if bundlepart:
                bundler.addpart(bundlepart)

    # If commits were sent, store them
    if cgparams:
        buf = util.chunkbuffer(bundler.getchunks())
        fd, bundlefile = tempfile.mkstemp()
        try:
            try:
                fp = util.fdopen(fd, "wb")
                fp.write(buf.read())
            finally:
                fp.close()
            storebundle(op, cgparams, bundlefile)
        finally:
            try:
                os.unlink(bundlefile)
            except Exception:
                # we would rather see the original exception
                pass

    # The scratch bookmark part is sent as part of a push backup. It needs to be
    # processed after the main bundle has been stored, so that any commits it
    # references are available in the store.
    if scratchbookpart:
        bundle2._processpart(op, scratchbookpart)
Exemple #8
0
    def putcommit(self, files, copies, parents, commit, source, revmap, full, cleanp2):
        for parent in parents:
            try:
                return self.revid(self.childmap[parent])
            except KeyError:
                pass

        # Apply changes to working copy
        for f, v in files:
            data, mode = source.getfile(f, v)
            if data is None:
                self.delete.append(f)
            else:
                self.putfile(f, mode, data)
                if f in copies:
                    self.copies.append([copies[f], f])
        if full:
            self.delete.extend(sorted(self.manifest.difference(files)))
        files = [f[0] for f in files]

        entries = set(self.delete)
        files = frozenset(files)
        entries.update(self.add_dirs(files.difference(entries)))
        if self.copies:
            for s, d in self.copies:
                self._copyfile(s, d)
            self.copies = []
        if self.delete:
            self.xargs(self.delete, "delete")
            for f in self.delete:
                self.manifest.remove(f)
            self.delete = []
        entries.update(self.add_files(files.difference(entries)))
        if self.delexec:
            self.xargs(self.delexec, "propdel", "svn:executable")
            self.delexec = []
        if self.setexec:
            self.xargs(self.setexec, "propset", "svn:executable", "*")
            self.setexec = []

        fd, messagefile = tempfile.mkstemp(prefix="hg-convert-")
        fp = util.fdopen(fd, "w")
        fp.write(commit.desc)
        fp.close()
        try:
            output = self.run0(
                "commit",
                username=util.shortuser(commit.author),
                file=messagefile,
                encoding="utf-8",
            )
            try:
                rev = self.commit_re.search(output).group(1)
            except AttributeError:
                if parents and not files:
                    return parents[0]
                self.ui.warn(_("unexpected svn output:\n"))
                self.ui.warn(output)
                raise error.Abort(_("unable to cope with svn output"))
            if commit.rev:
                self.run(
                    "propset", "hg:convert-rev", commit.rev, revprop=True, revision=rev
                )
            if commit.branch and commit.branch != "default":
                self.run(
                    "propset",
                    "hg:convert-branch",
                    commit.branch,
                    revprop=True,
                    revision=rev,
                )
            for parent in parents:
                self.addchild(parent, rev)
            return self.revid(rev)
        finally:
            os.unlink(messagefile)