Patchwork D1923: bundle2: specify what capabilities will be used for

login
register
mail settings
Submitter phabricator
Date Jan. 21, 2018, 12:45 a.m.
Message ID <differential-rev-PHID-DREV-jgd54i6y2peudaunpzzt-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/27014/
State Superseded
Headers show

Comments

phabricator - Jan. 21, 2018, 12:45 a.m.
indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  We currently assume there is a symmetric relationship of bundle2
  capabilities between client and server. However, this may not always be
  the case.
  
  We need a bundle2 capability to advertise bundle2 streaming clone support
  on servers to differentiate it from the existing, legacy streaming clone
  support.
  
  However, servers may wish to disable streaming clone support. If bundle2
  capabilities were the same between client and server, a client (which
  may also be a server) that has disabled streaming clone support would
  not be able to perform a streaming clone itself!
  
  This commit introduces a "role" argument to bundle2.getrepocaps() that
  explicitly defines the role being performed. This will allow us (and
  extensions) to alter bundle2 capabilities depending on the operation
  being performed.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1923

AFFECTED FILES
  mercurial/bundle2.py
  mercurial/bundlerepo.py
  mercurial/exchange.py
  mercurial/localrepo.py
  mercurial/wireproto.py

CHANGE DETAILS




To: indygreg, #hg-reviewers
Cc: mercurial-devel

Patch

diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -780,7 +780,7 @@ 
         else:
             caps.append('streamreqs=%s' % ','.join(sorted(requiredformats)))
     if repo.ui.configbool('experimental', 'bundle2-advertise'):
-        capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
+        capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo, role='server'))
         caps.append('bundle2=' + urlreq.quote(capsblob))
     caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority))
 
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -577,7 +577,8 @@ 
     def _restrictcapabilities(self, caps):
         if self.ui.configbool('experimental', 'bundle2-advertise'):
             caps = set(caps)
-            capsblob = bundle2.encodecaps(bundle2.getrepocaps(self))
+            capsblob = bundle2.encodecaps(bundle2.getrepocaps(self,
+                                                              role='client'))
             caps.add('bundle2=' + urlreq.quote(capsblob))
         return caps
 
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -1015,7 +1015,8 @@ 
 
     # create reply capability
     capsblob = bundle2.encodecaps(bundle2.getrepocaps(pushop.repo,
-                                                      allowpushback=pushback))
+                                                      allowpushback=pushback,
+                                                      role='client'))
     bundler.newpart('replycaps', data=capsblob)
     replyhandlers = []
     for partgenname in b2partsgenorder:
@@ -1448,7 +1449,7 @@ 
     """pull data using bundle2
 
     For now, the only supported data are changegroup."""
-    kwargs = {'bundlecaps': caps20to10(pullop.repo)}
+    kwargs = {'bundlecaps': caps20to10(pullop.repo, role='client')}
 
     # make ui easier to access
     ui = pullop.repo.ui
@@ -1680,10 +1681,10 @@ 
             pullop.repo.invalidatevolatilesets()
     return tr
 
-def caps20to10(repo):
+def caps20to10(repo, role):
     """return a set with appropriate options to use bundle20 during getbundle"""
     caps = {'HG20'}
-    capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
+    capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo, role=role))
     caps.add('bundle2=' + urlreq.quote(capsblob))
     return caps
 
diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py
--- a/mercurial/bundlerepo.py
+++ b/mercurial/bundlerepo.py
@@ -543,7 +543,7 @@ 
             kwargs = {}
             kwargs[r'common'] = common
             kwargs[r'heads'] = rheads
-            kwargs[r'bundlecaps'] = exchange.caps20to10(repo)
+            kwargs[r'bundlecaps'] = exchange.caps20to10(repo, role='client')
             kwargs[r'cg'] = True
             b2 = other.getbundle('incoming', **kwargs)
             fname = bundle = changegroup.writechunks(ui, b2._forwardchunks(),
diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -1490,11 +1490,18 @@ 
                 'stream': ('v2',),
                }
 
-def getrepocaps(repo, allowpushback=False):
+def getrepocaps(repo, allowpushback=False, role=None):
     """return the bundle2 capabilities for a given repo
 
     Exists to allow extensions (like evolution) to mutate the capabilities.
+
+    The returned value is used for servers advertising their capabilities as
+    well as clients advertising their capabilities to servers as part of
+    bundle2 requests. The ``role`` argument specifies which is which.
     """
+    if role not in ('client', 'server'):
+        raise error.ProgrammingError('role argument must be client or server')
+
     caps = capabilities.copy()
     caps['changegroup'] = tuple(sorted(
         changegroup.supportedincomingversions(repo)))