mercurial/wireprotov1server.py
author Gregory Szorc <gregory.szorc@gmail.com>
Mon, 10 Dec 2018 18:04:12 +0000
changeset 40923 3ed77780f4a6
parent 40075 ad8d8dc9be3f
child 41365 876494fd967d
permissions -rw-r--r--
wireprotov2: send linknodes to emitfilerevisions() Previously, linknodes were calculated within emitfilerevisions() by using filectx.introrev(), which would always use the linkrev/linknode as recorded by storage. This is wrong for cases where the receiver doesn't have the changeset the linknode refers to. This commit changes the logic for linknode emission so the mapping of filenode to linknode is computed by the caller and passed into emitfilerevisions(). As part of the change, linknodes for "filesdata" in the haveparents=False case are now correct: the existing code performed a manifest walk and it was trivial to plug in the correct linknode. However, behavior for the haveparents=True case is still wrong because it relies on filtering linkrevs against the outgoing set in order to determine what to send. This will be fixed in a subsequent commit. The change test test-wireproto-exchangev2-shallow.t is a bit wonky. The test repo has 6 revisions. The changed test is performing a shallow clone with depth=1. So, only file data for revision 5 is present locally. So, the new behavior of associating the linknode with revision 5 for every file revision seems correct. Of course, when backfilling old revisions, we'll want to update the linknode. But this problem requires wire protocol support and we'll cross that bridge later. Differential Revision: https://phab.mercurial-scm.org/D5405
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37785
b4d85bc122bd wireproto: rename wireproto to wireprotov1server (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37784
diff changeset
     1
# wireprotov1server.py - Wire protocol version 1 server functionality
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2005-2010 Matt Mackall <mpm@selenic.com>
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
     8
from __future__ import absolute_import
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
     9
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    10
import os
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    11
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    12
from .i18n import _
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    13
from .node import (
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    14
    hex,
32260
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
    15
    nullid,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    16
)
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    17
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    18
from . import (
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    19
    bundle2,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    20
    changegroup as changegroupmod,
34097
f7d41b85bbf6 changegroup: replace changegroupsubset with makechangegroup
Durham Goode <durham@fb.com>
parents: 34062
diff changeset
    21
    discovery,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    22
    encoding,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    23
    error,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    24
    exchange,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    25
    pushkey as pushkeymod,
30924
48dea083f66d py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30914
diff changeset
    26
    pycompat,
26443
d947086d8973 streamclone: move code out of exchange.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25993
diff changeset
    27
    streamclone,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    28
    util,
36073
cd6ab329c5c7 wireprototypes: move wire protocol response types to new module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36071
diff changeset
    29
    wireprototypes,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    30
)
20903
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    31
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
    32
from .utils import (
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
    33
    procutil,
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
    34
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
    35
)
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
    36
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    37
urlerr = util.urlerr
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    38
urlreq = util.urlreq
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    39
30909
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    40
bundle2requiredmain = _('incompatible Mercurial client; bundle2 required')
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    41
bundle2requiredhint = _('see https://www.mercurial-scm.org/wiki/'
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    42
                        'IncompatibleClient')
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    43
bundle2required = '%s\n(%s)\n' % (bundle2requiredmain, bundle2requiredhint)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
    44
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    45
def clientcompressionsupport(proto):
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    46
    """Returns a list of compression methods supported by the client.
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    47
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    48
    Returns a list of the compression methods supported by the client
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    49
    according to the protocol capabilities. If no such capability has
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    50
    been announced, fallback to the default of zlib and uncompressed.
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    51
    """
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    52
    for cap in proto.getprotocaps():
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    53
        if cap.startswith('comp='):
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    54
            return cap[5:].split(',')
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    55
    return ['zlib', 'none']
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
    56
20902
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
    57
# wire protocol command can either return a string or one of these classes.
15017
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
    58
29590
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    59
def getdispatchrepo(repo, proto, command):
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    60
    """Obtain the repo used for processing wire protocol commands.
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    61
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    62
    The intent of this function is to serve as a monkeypatch point for
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    63
    extensions that need commands to operate on different repo views under
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    64
    specialized circumstances.
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    65
    """
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    66
    return repo.filtered('served')
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    67
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
def dispatch(repo, proto, command):
29590
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
    69
    repo = getdispatchrepo(repo, proto, command)
37295
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
    70
37782
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
    71
    func, spec = commands[command]
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    72
    args = proto.getargs(spec)
37485
0b7475ea38cf wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37414
diff changeset
    73
37782
99accae4cc59 wireproto: reimplement dispatch() for version 2 server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37781
diff changeset
    74
    return func(repo, proto, *args)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    76
def options(cmd, keys, others):
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    77
    opts = {}
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    78
    for k in keys:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    79
        if k in others:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    80
            opts[k] = others[k]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    81
            del others[k]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    82
    if others:
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
    83
        procutil.stderr.write("warning: %s ignored unexpected arguments %s\n"
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
    84
                              % (cmd, ",".join(others)))
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    85
    return opts
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
    86
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    87
def bundle1allowed(repo, action):
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    88
    """Whether a bundle1 operation is allowed from the server.
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    89
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    90
    Priority is:
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    91
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    92
    1. server.bundle1gd.<action> (if generaldelta active)
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    93
    2. server.bundle1.<action>
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    94
    3. server.bundle1gd (if generaldelta active)
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    95
    4. server.bundle1
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    96
    """
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    97
    ui = repo.ui
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    98
    gd = 'generaldelta' in repo.requirements
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
    99
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   100
    if gd:
34613
5e61cd5fb0fc configitems: register the 'server.bundle*' family of config
Boris Feld <boris.feld@octobus.net>
parents: 34322
diff changeset
   101
        v = ui.configbool('server', 'bundle1gd.%s' % action)
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   102
        if v is not None:
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   103
            return v
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   104
34613
5e61cd5fb0fc configitems: register the 'server.bundle*' family of config
Boris Feld <boris.feld@octobus.net>
parents: 34322
diff changeset
   105
    v = ui.configbool('server', 'bundle1.%s' % action)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   106
    if v is not None:
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   107
        return v
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   108
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   109
    if gd:
33220
40861b2254a5 configitems: register the 'server.bundle1gd' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33219
diff changeset
   110
        v = ui.configbool('server', 'bundle1gd')
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   111
        if v is not None:
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   112
            return v
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   113
33219
ffb1d0f541f5 configitems: register the 'server.bundle1' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32880
diff changeset
   114
    return ui.configbool('server', 'bundle1')
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   115
37781
352932a11905 wireproto: move command registration types to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37780
diff changeset
   116
commands = wireprototypes.commanddict()
20906
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   117
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   118
def wireprotocommand(name, args=None, permission='push'):
35980
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   119
    """Decorator to declare a wire protocol command.
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   120
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   121
    ``name`` is the name of the wire protocol command being provided.
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   122
37535
69e46c1834ac wireproto: define and expose types of wire command arguments
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37534
diff changeset
   123
    ``args`` defines the named arguments accepted by the command. It is
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   124
    a space-delimited list of argument names. ``*`` denotes a special value
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   125
    that says to accept all named arguments.
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   126
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   127
    ``permission`` defines the permission type needed to run this command.
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   128
    Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   129
    respectively. Default is to assume command requires ``push`` permissions
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   130
    because otherwise commands not declaring their permissions could modify
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   131
    a repository that is supposed to be read-only.
35980
b4976912a6ef wireproto: improve docstring for @wireprotocommand
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35979
diff changeset
   132
    """
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   133
    transports = {k for k, v in wireprototypes.TRANSPORTS.items()
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   134
                  if v['version'] == 1}
36609
abc3b9801563 wireproto: allow wire protocol commands to declare transport support
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36535
diff changeset
   135
37053
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   136
    # Because SSHv2 is a mirror of SSHv1, we allow "batch" commands through to
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   137
    # SSHv2.
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   138
    # TODO undo this hack when SSH is using the unified frame protocol.
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   139
    if name == b'batch':
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   140
        transports.add(wireprototypes.SSHV2)
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   141
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   142
    if permission not in ('push', 'pull'):
36840
ef68493d652b wireproto: raise ProgrammingError instead of Abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36835
diff changeset
   143
        raise error.ProgrammingError('invalid wire protocol permission; '
ef68493d652b wireproto: raise ProgrammingError instead of Abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36835
diff changeset
   144
                                     'got %s; expected "push" or "pull"' %
ef68493d652b wireproto: raise ProgrammingError instead of Abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36835
diff changeset
   145
                                     permission)
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   146
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   147
    if args is None:
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   148
        args = ''
37535
69e46c1834ac wireproto: define and expose types of wire command arguments
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37534
diff changeset
   149
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   150
    if not isinstance(args, bytes):
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   151
        raise error.ProgrammingError('arguments for version 1 commands '
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   152
                                     'must be declared as bytes')
37535
69e46c1834ac wireproto: define and expose types of wire command arguments
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37534
diff changeset
   153
20906
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   154
    def register(func):
37780
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   155
        if name in commands:
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   156
            raise error.ProgrammingError('%s command already registered '
8acd3a9ac4fd wireproto: make version 2 @wireprotocommand an independent function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37779
diff changeset
   157
                                         'for version 1' % name)
37781
352932a11905 wireproto: move command registration types to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37780
diff changeset
   158
        commands[name] = wireprototypes.commandentry(
352932a11905 wireproto: move command registration types to wireprototypes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37780
diff changeset
   159
            func, args=args, transports=transports, permission=permission)
37295
45b39c69fae0 wireproto: separate commands tables for version 1 and 2 commands
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37293
diff changeset
   160
20906
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   161
        return func
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   162
    return register
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   163
36755
ff4bc0ab6740 wireproto: check permissions when executing "batch" command (BC) (SEC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36754
diff changeset
   164
# TODO define a more appropriate permissions type to use for this.
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   165
@wireprotocommand('batch', 'cmds *', permission='pull')
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   166
def batch(repo, proto, cmds, others):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   167
    unescapearg = wireprototypes.unescapebatcharg
18382
f3b21beb9802 filtering: rename filters to their antonyms
Kevin Bullock <kbullock@ringworld.org>
parents: 18381
diff changeset
   168
    repo = repo.filtered("served")
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   169
    res = []
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   170
    for pair in cmds.split(';'):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   171
        op, args = pair.split(' ', 1)
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   172
        vals = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   173
        for a in args.split(','):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   174
            if a:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   175
                n, v = a.split('=')
29734
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   176
                vals[unescapearg(n)] = unescapearg(v)
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   177
        func, spec = commands[op]
36755
ff4bc0ab6740 wireproto: check permissions when executing "batch" command (BC) (SEC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36754
diff changeset
   178
36801
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36800
diff changeset
   179
        # Validate that client has permissions to perform this command.
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36800
diff changeset
   180
        perm = commands[op].permission
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36800
diff changeset
   181
        assert perm in ('push', 'pull')
66de4555cefd wireproto: formalize permissions checking as part of protocol interface
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36800
diff changeset
   182
        proto.checkperm(perm)
36755
ff4bc0ab6740 wireproto: check permissions when executing "batch" command (BC) (SEC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36754
diff changeset
   183
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   184
        if spec:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   185
            keys = spec.split()
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   186
            data = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   187
            for k in keys:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   188
                if k == '*':
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   189
                    star = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   190
                    for key in vals.keys():
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   191
                        if key not in keys:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   192
                            star[key] = vals[key]
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   193
                    data['*'] = star
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   194
                else:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   195
                    data[k] = vals[k]
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   196
            result = func(repo, proto, *[data[k] for k in keys])
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   197
        else:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   198
            result = func(repo, proto)
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   199
        if isinstance(result, wireprototypes.ooberror):
15017
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
   200
            return result
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   201
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   202
        # For now, all batchable commands must return bytesresponse or
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   203
        # raw bytes (for backwards compatibility).
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   204
        assert isinstance(result, (wireprototypes.bytesresponse, bytes))
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   205
        if isinstance(result, wireprototypes.bytesresponse):
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   206
            result = result.data
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   207
        res.append(wireprototypes.escapebatcharg(result))
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   208
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   209
    return wireprototypes.bytesresponse(';'.join(res))
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   210
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   211
@wireprotocommand('between', 'pairs', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   212
def between(repo, proto, pairs):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   213
    pairs = [wireprototypes.decodelist(p, '-') for p in pairs.split(" ")]
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   214
    r = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   215
    for b in repo.between(pairs):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   216
        r.append(wireprototypes.encodelist(b) + "\n")
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   217
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   218
    return wireprototypes.bytesresponse(''.join(r))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   219
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   220
@wireprotocommand('branchmap', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   221
def branchmap(repo, proto):
18281
898c575833c9 clfilter: drop extra filtering in wireprotocol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18280
diff changeset
   222
    branchmap = repo.branchmap()
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   223
    heads = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   224
    for branch, nodes in branchmap.iteritems():
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
   225
        branchname = urlreq.quote(encoding.fromlocal(branch))
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   226
        branchnodes = wireprototypes.encodelist(nodes)
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   227
        heads.append('%s %s' % (branchname, branchnodes))
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   228
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   229
    return wireprototypes.bytesresponse('\n'.join(heads))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   230
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   231
@wireprotocommand('branches', 'nodes', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   232
def branches(repo, proto, nodes):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   233
    nodes = wireprototypes.decodelist(nodes)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   234
    r = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   235
    for b in repo.branches(nodes):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   236
        r.append(wireprototypes.encodelist(b) + "\n")
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   237
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   238
    return wireprototypes.bytesresponse(''.join(r))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   239
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   240
@wireprotocommand('clonebundles', '', permission='pull')
26857
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   241
def clonebundles(repo, proto):
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   242
    """Server command for returning info for available bundles to seed clones.
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   243
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   244
    Clients will parse this response and determine what bundle to fetch.
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   245
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   246
    Extensions may wrap this command to filter or dynamically emit data
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   247
    depending on the request. e.g. you could advertise URLs for the closest
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   248
    data center given the client's IP address.
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   249
    """
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   250
    return wireprototypes.bytesresponse(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   251
        repo.vfs.tryread('clonebundles.manifest'))
20774
cdc3ac896997 wireproto: extract capabilities list in outside the wireproto function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20671
diff changeset
   252
36612
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   253
wireprotocaps = ['lookup', 'branchmap', 'pushkey',
37053
cd0ca979a8b8 wireproto: nominally don't expose "batch" to version 2 wire transports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36991
diff changeset
   254
                 'known', 'getbundle', 'unbundlehash']
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   255
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   256
def _capabilities(repo, proto):
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   257
    """return a list of capabilities for a repo
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   258
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   259
    This function exists to allow extensions to easily wrap capabilities
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   260
    computation
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   261
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   262
    - returns a lists: easy to alter
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   263
    - change done here will be propagated to both `capabilities` and `hello`
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20969
diff changeset
   264
      command without any other action needed.
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   265
    """
20774
cdc3ac896997 wireproto: extract capabilities list in outside the wireproto function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20671
diff changeset
   266
    # copy to prevent modification of the global list
cdc3ac896997 wireproto: extract capabilities list in outside the wireproto function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20671
diff changeset
   267
    caps = list(wireprotocaps)
36612
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   268
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   269
    # Command of same name as capability isn't exposed to version 1 of
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   270
    # transports. So conditionally add it.
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   271
    if commands.commandavailable('changegroupsubset', proto):
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   272
        caps.append('changegroupsubset')
e89959970a08 wireproto: don't expose changegroupsubset capability if not available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36611
diff changeset
   273
32744
33b7283a3828 streamclone: consider secret changesets (BC) (issue5589)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32291
diff changeset
   274
    if streamclone.allowservergeneration(repo):
33225
90a1b62bdc91 configitems: register the 'server.preferuncompressed' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33224
diff changeset
   275
        if repo.ui.configbool('server', 'preferuncompressed'):
16361
6097ede2be4d protocol: Add the stream-preferred capability
Benoit Allard <benoit@aeteurope.nl>
parents: 15925
diff changeset
   276
            caps.append('stream-preferred')
12296
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   277
        requiredformats = repo.requirements & repo.supportedformats
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   278
        # if our local revlogs are just revlogv1, add 'stream' cap
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32260
diff changeset
   279
        if not requiredformats - {'revlogv1'}:
12296
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   280
            caps.append('stream')
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   281
        # otherwise, add 'streamreqs' detailing our local revlog format
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   282
        else:
26911
d7e5e4da8394 stream: sort stream capability before serialisation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26857
diff changeset
   283
            caps.append('streamreqs=%s' % ','.join(sorted(requiredformats)))
33499
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33225
diff changeset
   284
    if repo.ui.configbool('experimental', 'bundle2-advertise'):
35783
c97639ad6874 bundle2: specify what capabilities will be used for
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35782
diff changeset
   285
        capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo, role='server'))
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
   286
        caps.append('bundle2=' + urlreq.quote(capsblob))
28666
ae53ecc47414 bundle: move writebundle() from changegroup.py to bundle2.py (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 28530
diff changeset
   287
    caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority))
30563
e118233172fe wireproto: only advertise HTTP-specific capabilities to HTTP peers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30473
diff changeset
   288
40075
ad8d8dc9be3f narrow: move adding of narrow server capabilities to core
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 38678
diff changeset
   289
    if repo.ui.configbool('experimental', 'narrow'):
ad8d8dc9be3f narrow: move adding of narrow server capabilities to core
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 38678
diff changeset
   290
        caps.append(wireprototypes.NARROWCAP)
ad8d8dc9be3f narrow: move adding of narrow server capabilities to core
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 38678
diff changeset
   291
        if repo.ui.configbool('experimental', 'narrowservebrokenellipses'):
ad8d8dc9be3f narrow: move adding of narrow server capabilities to core
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 38678
diff changeset
   292
            caps.append(wireprototypes.ELLIPSESCAP)
ad8d8dc9be3f narrow: move adding of narrow server capabilities to core
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 38678
diff changeset
   293
36613
6e585bca962e wireproto: add transport specific capabilities in the transport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36612
diff changeset
   294
    return proto.addcapabilities(repo, caps)
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   295
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20969
diff changeset
   296
# If you are writing an extension and consider wrapping this function. Wrap
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   297
# `_capabilities` instead.
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   298
@wireprotocommand('capabilities', permission='pull')
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   299
def capabilities(repo, proto):
37413
33af46d639b4 wireproto: send server capabilities in canonical order
Joerg Sonnenberger <joerg@bec.de>
parents: 37412
diff changeset
   300
    caps = _capabilities(repo, proto)
33af46d639b4 wireproto: send server capabilities in canonical order
Joerg Sonnenberger <joerg@bec.de>
parents: 37412
diff changeset
   301
    return wireprototypes.bytesresponse(' '.join(sorted(caps)))
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   302
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   303
@wireprotocommand('changegroup', 'roots', permission='pull')
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   304
def changegroup(repo, proto, roots):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   305
    nodes = wireprototypes.decodelist(roots)
34100
1632999d4bed changegroup: replace changegroup with makechangegroup
Durham Goode <durham@fb.com>
parents: 34097
diff changeset
   306
    outgoing = discovery.outgoing(repo, missingroots=nodes,
1632999d4bed changegroup: replace changegroup with makechangegroup
Durham Goode <durham@fb.com>
parents: 34097
diff changeset
   307
                                  missingheads=repo.heads())
1632999d4bed changegroup: replace changegroup with makechangegroup
Durham Goode <durham@fb.com>
parents: 34097
diff changeset
   308
    cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
35705
8cdb671dbd0b wireproto: drop support for reader interface from streamres (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35491
diff changeset
   309
    gen = iter(lambda: cg.read(32768), '')
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   310
    return wireprototypes.streamres(gen=gen)
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   311
36611
6906547c8476 wireproto: don't expose legacy commands to version 2 of wire protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36609
diff changeset
   312
@wireprotocommand('changegroupsubset', 'bases heads',
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   313
                  permission='pull')
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   314
def changegroupsubset(repo, proto, bases, heads):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   315
    bases = wireprototypes.decodelist(bases)
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   316
    heads = wireprototypes.decodelist(heads)
34097
f7d41b85bbf6 changegroup: replace changegroupsubset with makechangegroup
Durham Goode <durham@fb.com>
parents: 34062
diff changeset
   317
    outgoing = discovery.outgoing(repo, missingroots=bases,
f7d41b85bbf6 changegroup: replace changegroupsubset with makechangegroup
Durham Goode <durham@fb.com>
parents: 34062
diff changeset
   318
                                  missingheads=heads)
f7d41b85bbf6 changegroup: replace changegroupsubset with makechangegroup
Durham Goode <durham@fb.com>
parents: 34062
diff changeset
   319
    cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
35705
8cdb671dbd0b wireproto: drop support for reader interface from streamres (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35491
diff changeset
   320
    gen = iter(lambda: cg.read(32768), '')
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   321
    return wireprototypes.streamres(gen=gen)
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   322
36800
0b18604db95e wireproto: declare permissions requirements in @wireprotocommand (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36760
diff changeset
   323
@wireprotocommand('debugwireargs', 'one two *',
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   324
                  permission='pull')
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   325
def debugwireargs(repo, proto, one, two, others):
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   326
    # only accept optional args from the known set
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   327
    opts = options('debugwireargs', ['three', 'four'], others)
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   328
    return wireprototypes.bytesresponse(repo.debugwireargs(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   329
        one, two, **pycompat.strkwargs(opts)))
13720
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   330
37498
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   331
def find_pullbundle(repo, proto, opts, clheads, heads, common):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   332
    """Return a file object for the first matching pullbundle.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   333
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   334
    Pullbundles are specified in .hg/pullbundles.manifest similar to
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   335
    clonebundles.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   336
    For each entry, the bundle specification is checked for compatibility:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   337
    - Client features vs the BUNDLESPEC.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   338
    - Revisions shared with the clients vs base revisions of the bundle.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   339
      A bundle can be applied only if all its base revisions are known by
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   340
      the client.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   341
    - At least one leaf of the bundle's DAG is missing on the client.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   342
    - Every leaf of the bundle's DAG is part of node set the client wants.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   343
      E.g. do not send a bundle of all changes if the client wants only
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   344
      one specific branch of many.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   345
    """
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   346
    def decodehexstring(s):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   347
        return set([h.decode('hex') for h in s.split(';')])
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   348
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   349
    manifest = repo.vfs.tryread('pullbundles.manifest')
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   350
    if not manifest:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   351
        return None
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   352
    res = exchange.parseclonebundlesmanifest(repo, manifest)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   353
    res = exchange.filterclonebundleentries(repo, res)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   354
    if not res:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   355
        return None
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   356
    cl = repo.changelog
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   357
    heads_anc = cl.ancestors([cl.rev(rev) for rev in heads], inclusive=True)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   358
    common_anc = cl.ancestors([cl.rev(rev) for rev in common], inclusive=True)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   359
    compformats = clientcompressionsupport(proto)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   360
    for entry in res:
38678
7e4a856a4f05 pullbundle: fix handling of gzip bundlespecs
Joerg Sonnenberger <joerg@bec.de>
parents: 38164
diff changeset
   361
        comp = entry.get('COMPRESSION')
7e4a856a4f05 pullbundle: fix handling of gzip bundlespecs
Joerg Sonnenberger <joerg@bec.de>
parents: 38164
diff changeset
   362
        altcomp = util.compengines._bundlenames.get(comp)
7e4a856a4f05 pullbundle: fix handling of gzip bundlespecs
Joerg Sonnenberger <joerg@bec.de>
parents: 38164
diff changeset
   363
        if comp and comp not in compformats and altcomp not in compformats:
37498
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   364
            continue
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   365
        # No test yet for VERSION, since V2 is supported by any client
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   366
        # that advertises partial pulls
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   367
        if 'heads' in entry:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   368
            try:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   369
                bundle_heads = decodehexstring(entry['heads'])
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   370
            except TypeError:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   371
                # Bad heads entry
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   372
                continue
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   373
            if bundle_heads.issubset(common):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   374
                continue # Nothing new
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   375
            if all(cl.rev(rev) in common_anc for rev in bundle_heads):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   376
                continue # Still nothing new
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   377
            if any(cl.rev(rev) not in heads_anc and
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   378
                   cl.rev(rev) not in common_anc for rev in bundle_heads):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   379
                continue
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   380
        if 'bases' in entry:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   381
            try:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   382
                bundle_bases = decodehexstring(entry['bases'])
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   383
            except TypeError:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   384
                # Bad bases entry
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   385
                continue
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   386
            if not all(cl.rev(rev) in common_anc for rev in bundle_bases):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   387
                continue
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   388
        path = entry['URL']
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   389
        repo.ui.debug('sending pullbundle "%s"\n' % path)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   390
        try:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   391
            return repo.vfs.open(path)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   392
        except IOError:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   393
            repo.ui.debug('pullbundle "%s" not accessible\n' % path)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   394
            continue
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   395
    return None
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   396
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   397
@wireprotocommand('getbundle', '*', permission='pull')
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   398
def getbundle(repo, proto, others):
37613
96d735601ca1 wireproto: move gboptsmap to wireprototypes and rename (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37612
diff changeset
   399
    opts = options('getbundle', wireprototypes.GETBUNDLE_ARGUMENTS.keys(),
96d735601ca1 wireproto: move gboptsmap to wireprototypes and rename (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37612
diff changeset
   400
                   others)
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   401
    for k, v in opts.iteritems():
37613
96d735601ca1 wireproto: move gboptsmap to wireprototypes and rename (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37612
diff changeset
   402
        keytype = wireprototypes.GETBUNDLE_ARGUMENTS[k]
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   403
        if keytype == 'nodes':
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   404
            opts[k] = wireprototypes.decodelist(v)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   405
        elif keytype == 'csv':
25403
30ab130af221 wireprotocol: distinguish list and set in getbundle argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25339
diff changeset
   406
            opts[k] = list(v.split(','))
30ab130af221 wireprotocol: distinguish list and set in getbundle argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25339
diff changeset
   407
        elif keytype == 'scsv':
19201
309c439cdbaa bundle-ng: add bundlecaps argument to getbundle() command
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 19176
diff changeset
   408
            opts[k] = set(v.split(','))
21988
12cd3827b860 wireproto: add a ``boolean`` type for getbundle parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21728
diff changeset
   409
        elif keytype == 'boolean':
26686
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   410
            # Client should serialize False as '0', which is a non-empty string
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   411
            # so it evaluates as a True bool.
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   412
            if v == '0':
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   413
                opts[k] = False
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   414
            else:
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   415
                opts[k] = bool(v)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   416
        elif keytype != 'plain':
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   417
            raise KeyError('unknown getbundle option type %s'
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   418
                           % keytype)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   419
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   420
    if not bundle1allowed(repo, 'pull'):
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   421
        if not exchange.bundle2requested(opts.get('bundlecaps')):
36223
2e07dc514073 wireprotoserver: add version to HTTP protocol name (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36221
diff changeset
   422
            if proto.name == 'http-v1':
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   423
                return wireprototypes.ooberror(bundle2required)
30912
3d4afc2fdcd7 bundle1: fix bundle1-denied reporting for pull over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30910
diff changeset
   424
            raise error.Abort(bundle2requiredmain,
3d4afc2fdcd7 bundle1: fix bundle1-denied reporting for pull over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30910
diff changeset
   425
                              hint=bundle2requiredhint)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   426
35787
a84dbc87dae9 exchange: send bundle2 stream clones uncompressed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35785
diff changeset
   427
    prefercompressed = True
35782
9d249f3de730 wireproto: don't compress errors from getbundle()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35760
diff changeset
   428
30914
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   429
    try:
37498
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   430
        clheads = set(repo.changelog.heads())
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   431
        heads = set(opts.get('heads', set()))
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   432
        common = set(opts.get('common', set()))
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   433
        common.discard(nullid)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   434
        if (repo.ui.configbool('server', 'pullbundle') and
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   435
            'partial-pull' in proto.getprotocaps()):
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   436
            # Check if a pre-built bundle covers this request.
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   437
            bundle = find_pullbundle(repo, proto, opts, clheads, heads, common)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   438
            if bundle:
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   439
                return wireprototypes.streamres(gen=util.filechunkiter(bundle),
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   440
                                                prefer_uncompressed=True)
aacfca6f9767 wireproto: support for pullbundles
Joerg Sonnenberger <joerg@bec.de>
parents: 37490
diff changeset
   441
33223
d227451ee280 configitems: register the 'server.disablefullbundle' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33220
diff changeset
   442
        if repo.ui.configbool('server', 'disablefullbundle'):
32260
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   443
            # Check to see if this is a full clone.
35760
133a678673cb clone: allow bundle2's stream clone with 'server.disablefullbundle'
Boris Feld <boris.feld@octobus.net>
parents: 35759
diff changeset
   444
            changegroup = opts.get('cg', True)
133a678673cb clone: allow bundle2's stream clone with 'server.disablefullbundle'
Boris Feld <boris.feld@octobus.net>
parents: 35759
diff changeset
   445
            if changegroup and not common and clheads == heads:
32260
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   446
                raise error.Abort(
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   447
                    _('server has pull-based clones disabled'),
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   448
                    hint=_('remove --pull if specified or upgrade Mercurial'))
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   449
35785
ba15580e53d5 exchange: return bundle info from getbundlechunks() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35783
diff changeset
   450
        info, chunks = exchange.getbundlechunks(repo, 'serve',
ba15580e53d5 exchange: return bundle info from getbundlechunks() (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35783
diff changeset
   451
                                                **pycompat.strkwargs(opts))
35787
a84dbc87dae9 exchange: send bundle2 stream clones uncompressed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35785
diff changeset
   452
        prefercompressed = info.get('prefercompressed', True)
30914
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   453
    except error.Abort as exc:
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   454
        # cleanly forward Abort error to the client
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   455
        if not exchange.bundle2requested(opts.get('bundlecaps')):
36223
2e07dc514073 wireprotoserver: add version to HTTP protocol name (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36221
diff changeset
   456
            if proto.name == 'http-v1':
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   457
                return wireprototypes.ooberror(pycompat.bytestr(exc) + '\n')
30914
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   458
            raise # cannot do better for bundle1 + ssh
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   459
        # bundle2 request expect a bundle2 reply
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   460
        bundler = bundle2.bundle20(repo.ui)
36258
af0a19d8812b py3: get bytes-repr of network errors portably
Augie Fackler <augie@google.com>
parents: 36223
diff changeset
   461
        manargs = [('message', pycompat.bytestr(exc))]
30914
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   462
        advargs = []
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   463
        if exc.hint is not None:
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   464
            advargs.append(('hint', exc.hint))
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   465
        bundler.addpart(bundle2.bundlepart('error:abort',
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   466
                                           manargs, advargs))
35782
9d249f3de730 wireproto: don't compress errors from getbundle()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35760
diff changeset
   467
        chunks = bundler.getchunks()
35787
a84dbc87dae9 exchange: send bundle2 stream clones uncompressed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35785
diff changeset
   468
        prefercompressed = False
35782
9d249f3de730 wireproto: don't compress errors from getbundle()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35760
diff changeset
   469
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   470
    return wireprototypes.streamres(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   471
        gen=chunks, prefer_uncompressed=not prefercompressed)
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   472
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   473
@wireprotocommand('heads', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   474
def heads(repo, proto):
18281
898c575833c9 clfilter: drop extra filtering in wireprotocol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18280
diff changeset
   475
    h = repo.heads()
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   476
    return wireprototypes.bytesresponse(wireprototypes.encodelist(h) + '\n')
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   477
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   478
@wireprotocommand('hello', permission='pull')
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   479
def hello(repo, proto):
36221
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   480
    """Called as part of SSH handshake to obtain server info.
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   481
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   482
    Returns a list of lines describing interesting things about the
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   483
    server, in an RFC822-like format.
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   484
36221
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   485
    Currently, the only one defined is ``capabilities``, which consists of a
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   486
    line of space separated tokens describing server abilities:
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   487
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   488
        capabilities: <token0> <token1> <token2>
62bca1c50e96 wireproto: improve docstring for "hello"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36074
diff changeset
   489
    """
36074
2f7290555c96 wireproto: introduce type for raw byte responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36073
diff changeset
   490
    caps = capabilities(repo, proto).data
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   491
    return wireprototypes.bytesresponse('capabilities: %s\n' % caps)
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   492
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   493
@wireprotocommand('listkeys', 'namespace', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   494
def listkeys(repo, proto, namespace):
36529
33c6f8f0388d wireproto: sort response to listkeys
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36431
diff changeset
   495
    d = sorted(repo.listkeys(encoding.tolocal(namespace)).items())
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   496
    return wireprototypes.bytesresponse(pushkeymod.encodekeys(d))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   497
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   498
@wireprotocommand('lookup', 'key', permission='pull')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   499
def lookup(repo, proto, key):
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   500
    try:
15925
f9fc46698352 wireproto: refuse to lookup secret csets
Matt Mackall <mpm@selenic.com>
parents: 15713
diff changeset
   501
        k = encoding.tolocal(key)
37353
ac666c5c2e0c wireproto: use repo.lookup() for lookup command
Martin von Zweigbergk <martinvonz@google.com>
parents: 37320
diff changeset
   502
        n = repo.lookup(k)
ac666c5c2e0c wireproto: use repo.lookup() for lookup command
Martin von Zweigbergk <martinvonz@google.com>
parents: 37320
diff changeset
   503
        r = hex(n)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   504
        success = 1
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25493
diff changeset
   505
    except Exception as inst:
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
   506
        r = stringutil.forcebytestr(inst)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   507
        success = 0
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   508
    return wireprototypes.bytesresponse('%d %s\n' % (success, r))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   509
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   510
@wireprotocommand('known', 'nodes *', permission='pull')
14436
5adb52524779 wireproto: enable optional args for known() for future extensibility
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14419
diff changeset
   511
def known(repo, proto, nodes, others):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   512
    v = ''.join(b and '1' or '0'
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   513
                for b in repo.known(wireprototypes.decodelist(nodes)))
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   514
    return wireprototypes.bytesresponse(v)
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   515
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   516
@wireprotocommand('protocaps', 'caps', permission='pull')
37393
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   517
def protocaps(repo, proto, caps):
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   518
    if proto.name == wireprototypes.SSHV1:
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   519
        proto._protocaps = set(caps.split(' '))
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   520
    return wireprototypes.bytesresponse('OK')
afcfdf53e4b5 wireproto: provide accessors for client capabilities
Joerg Sonnenberger <joerg@bec.de>
parents: 37353
diff changeset
   521
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   522
@wireprotocommand('pushkey', 'namespace key old new', permission='push')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   523
def pushkey(repo, proto, namespace, key, old, new):
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   524
    # compatibility with pre-1.8 clients which were accidentally
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   525
    # sending raw binary nodes rather than utf-8-encoded hex
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
   526
    if len(new) == 20 and stringutil.escapestr(new) != new:
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   527
        # looks like it could be a binary node
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   528
        try:
14064
e4bfb9c337f3 remove unused imports and variables
Alexander Solovyov <alexander@solovyov.net>
parents: 14048
diff changeset
   529
            new.decode('utf-8')
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   530
            new = encoding.tolocal(new) # but cleanly decodes as UTF-8
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   531
        except UnicodeDecodeError:
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   532
            pass # binary, leave unmodified
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   533
    else:
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   534
        new = encoding.tolocal(new) # normal path
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   535
36066
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
   536
    with proto.mayberedirectstdio() as output:
35979
ae79cf6f9c82 wireproto: remove unnecessary exception trapping
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35860
diff changeset
   537
        r = repo.pushkey(encoding.tolocal(namespace), encoding.tolocal(key),
ae79cf6f9c82 wireproto: remove unnecessary exception trapping
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35860
diff changeset
   538
                         encoding.tolocal(old), new) or False
17793
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   539
36066
2ad145fbde54 wireprotoserver: add context manager mechanism for redirecting stdio
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35982
diff changeset
   540
    output = output.getvalue() if output else ''
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   541
    return wireprototypes.bytesresponse('%d\n%s' % (int(r), output))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   542
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   543
@wireprotocommand('stream_out', permission='pull')
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
   544
def stream(repo, proto):
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
   545
    '''If the server supports streaming clone, it advertises the "stream"
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
   546
    capability with a value representing the version and flags of the repo
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
   547
    it is serving. Client checks to see if it understands the format.
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
   548
    '''
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   549
    return wireprototypes.streamreslegacy(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   550
        streamclone.generatev1wireproto(repo))
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
   551
37779
379d54eae6eb wireproto: don't pass transportpolicy argument
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37614
diff changeset
   552
@wireprotocommand('unbundle', 'heads', permission='push')
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
   553
def unbundle(repo, proto, heads):
37612
5e71dea79aae wireproto: move value encoding functions to wireprototypes (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37546
diff changeset
   554
    their_heads = wireprototypes.decodelist(heads)
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
   555
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   556
    with proto.mayberedirectstdio() as output:
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
   557
        try:
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   558
            exchange.check_heads(repo, their_heads, 'preparing changes')
37414
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   559
            cleanup = lambda: None
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   560
            try:
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   561
                payload = proto.getpayload()
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   562
                if repo.ui.configbool('server', 'streamunbundle'):
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   563
                    def cleanup():
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   564
                        # Ensure that the full payload is consumed, so
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   565
                        # that the connection doesn't contain trailing garbage.
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   566
                        for p in payload:
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   567
                            pass
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   568
                    fp = util.chunkbuffer(payload)
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   569
                else:
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   570
                    # write bundle data to temporary file as it can be big
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   571
                    fp, tempname = None, None
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   572
                    def cleanup():
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   573
                        if fp:
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   574
                            fp.close()
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   575
                        if tempname:
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   576
                            os.unlink(tempname)
38164
aac4be30e250 py3: wrap tempfile.mkstemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 37785
diff changeset
   577
                    fd, tempname = pycompat.mkstemp(prefix='hg-unbundle-')
37414
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   578
                    repo.ui.debug('redirecting incoming bundle to %s\n' %
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   579
                        tempname)
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   580
                    fp = os.fdopen(fd, pycompat.sysstr('wb+'))
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   581
                    r = 0
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   582
                    for p in payload:
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   583
                        fp.write(p)
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   584
                    fp.seek(0)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   585
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   586
                gen = exchange.readbundle(repo.ui, fp, None)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   587
                if (isinstance(gen, changegroupmod.cg1unpacker)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   588
                    and not bundle1allowed(repo, 'push')):
36223
2e07dc514073 wireprotoserver: add version to HTTP protocol name (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36221
diff changeset
   589
                    if proto.name == 'http-v1':
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   590
                        # need to special case http because stderr do not get to
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   591
                        # the http client on failed push so we need to abuse
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   592
                        # some other error type to make sure the message get to
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   593
                        # the user.
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   594
                        return wireprototypes.ooberror(bundle2required)
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   595
                    raise error.Abort(bundle2requiredmain,
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   596
                                      hint=bundle2requiredhint)
24796
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
   597
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   598
                r = exchange.unbundle(repo, gen, their_heads, 'serve',
36069
957e773614d0 wireprotoserver: rename _client to client (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36067
diff changeset
   599
                                      proto.client())
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   600
                if util.safehasattr(r, 'addpart'):
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   601
                    # The return looks streamable, we are in the bundle2 case
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   602
                    # and should return a stream.
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   603
                    return wireprototypes.streamreslegacy(gen=r.getchunks())
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   604
                return wireprototypes.pushres(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   605
                    r, output.getvalue() if output else '')
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   606
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   607
            finally:
37414
2d965bfeb8f6 wireproto: allow direct stream processing for unbundle
Joerg Sonnenberger <joerg@bec.de>
parents: 37413
diff changeset
   608
                cleanup()
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   609
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   610
        except (error.BundleValueError, error.Abort, error.PushRaced) as exc:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   611
            # handle non-bundle2 case first
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   612
            if not getattr(exc, 'duringunbundle2', False):
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   613
                try:
25493
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
   614
                    raise
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   615
                except error.Abort:
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   616
                    # The old code we moved used procutil.stderr directly.
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   617
                    # We did not change it to minimise code change.
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   618
                    # This need to be moved to something proper.
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   619
                    # Feel free to do it.
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   620
                    procutil.stderr.write("abort: %s\n" % exc)
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   621
                    if exc.hint is not None:
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   622
                        procutil.stderr.write("(%s)\n" % exc.hint)
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   623
                    procutil.stderr.flush()
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   624
                    return wireprototypes.pushres(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   625
                        0, output.getvalue() if output else '')
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   626
                except error.PushRaced:
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   627
                    return wireprototypes.pusherr(
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   628
                        pycompat.bytestr(exc),
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   629
                        output.getvalue() if output else '')
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   630
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   631
            bundler = bundle2.bundle20(repo.ui)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   632
            for out in getattr(exc, '_bundle2salvagedoutput', ()):
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   633
                bundler.addpart(out)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   634
            try:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   635
                try:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   636
                    raise
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   637
                except error.PushkeyFailed as exc:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   638
                    # check client caps
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   639
                    remotecaps = getattr(exc, '_replycaps', None)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   640
                    if (remotecaps is not None
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   641
                            and 'pushkey' not in remotecaps.get('error', ())):
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   642
                        # no support remote side, fallback to Abort handler.
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   643
                        raise
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   644
                    part = bundler.newpart('error:pushkey')
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   645
                    part.addparam('in-reply-to', exc.partid)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   646
                    if exc.namespace is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   647
                        part.addparam('namespace', exc.namespace,
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   648
                                      mandatory=False)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   649
                    if exc.key is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   650
                        part.addparam('key', exc.key, mandatory=False)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   651
                    if exc.new is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   652
                        part.addparam('new', exc.new, mandatory=False)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   653
                    if exc.old is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   654
                        part.addparam('old', exc.old, mandatory=False)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   655
                    if exc.ret is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   656
                        part.addparam('ret', exc.ret, mandatory=False)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   657
            except error.BundleValueError as exc:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   658
                errpart = bundler.newpart('error:unsupportedcontent')
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   659
                if exc.parttype is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   660
                    errpart.addparam('parttype', exc.parttype)
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   661
                if exc.params:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   662
                    errpart.addparam('params', '\0'.join(exc.params))
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   663
            except error.Abort as exc:
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
   664
                manargs = [('message', stringutil.forcebytestr(exc))]
36067
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   665
                advargs = []
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   666
                if exc.hint is not None:
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   667
                    advargs.append(('hint', exc.hint))
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   668
                bundler.addpart(bundle2.bundlepart('error:abort',
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   669
                                                   manargs, advargs))
caca3ac2ac04 wireproto: use maybecapturestdio() for push responses (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36066
diff changeset
   670
            except error.PushRaced as exc:
36314
be9c497e0bfd wireproto: fix lingering str(exception) with util.forcebytestr(exception)
Augie Fackler <augie@google.com>
parents: 36258
diff changeset
   671
                bundler.newpart('error:pushraced',
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37053
diff changeset
   672
                                [('message', stringutil.forcebytestr(exc))])
37293
d5d665f6615a wireproto: stop aliasing wire protocol types (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37119
diff changeset
   673
            return wireprototypes.streamreslegacy(gen=bundler.getchunks())