Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/sshpeer.py @ 50481:45c7bada5200
hidden: add support to explicitly access hidden changesets with SSH peers
This implements support for using --remote-hidden with an SSH server. The
remote `hg serve --stdio` call is passed the `--hidden` flag as a request to
access hidden changesets.
This approach has benefits similar to the one we used for HTTP peers. It
* works around the lack of global parameters in wire protocol v1,
* reuses the `--hidden` flag (that does not use the wireproto), and
* can be safely ignored by older client (fitting the best effort contract).
Same as for HTTP, the feature is experimental so we have all the room we needs
to update the implementation in the future if deemed necessary.
The SSH version of the `--remote-hidden` config uses the same configuration as
the HTTP support to control the access to this feature. The name of the user
running the command is used for the checking.
Test written by Pierre-Yves David.
author | Manuel Jacob <me@manueljacob.de> |
---|---|
date | Sat, 13 Apr 2019 03:44:55 +0200 |
parents | 3a2df812e1c7 |
children | 60f9602b413e |
comparison
equal
deleted
inserted
replaced
50480:afb27fc92717 | 50481:45c7bada5200 |
---|---|
175 # We add our own stack trace, because the stacktrace when called | 175 # We add our own stack trace, because the stacktrace when called |
176 # from __del__ is useless. | 176 # from __del__ is useless. |
177 ui.develwarn(b'missing close on SSH connection created at:\n%s' % warn) | 177 ui.develwarn(b'missing close on SSH connection created at:\n%s' % warn) |
178 | 178 |
179 | 179 |
180 def _makeconnection(ui, sshcmd, args, remotecmd, path, sshenv=None): | 180 def _makeconnection( |
181 ui, sshcmd, args, remotecmd, path, sshenv=None, remotehidden=False | |
182 ): | |
181 """Create an SSH connection to a server. | 183 """Create an SSH connection to a server. |
182 | 184 |
183 Returns a tuple of (process, stdin, stdout, stderr) for the | 185 Returns a tuple of (process, stdin, stdout, stderr) for the |
184 spawned process. | 186 spawned process. |
185 """ | 187 """ |
186 cmd = b'%s %s %s' % ( | 188 cmd = b'%s %s %s' % ( |
187 sshcmd, | 189 sshcmd, |
188 args, | 190 args, |
189 procutil.shellquote( | 191 procutil.shellquote( |
190 b'%s -R %s serve --stdio' | 192 b'%s -R %s serve --stdio%s' |
191 % (_serverquote(remotecmd), _serverquote(path)) | 193 % ( |
194 _serverquote(remotecmd), | |
195 _serverquote(path), | |
196 b' --hidden' if remotehidden else b'', | |
197 ) | |
192 ), | 198 ), |
193 ) | 199 ) |
194 | 200 |
195 ui.debug(b'running %s\n' % cmd) | 201 ui.debug(b'running %s\n' % cmd) |
196 | 202 |
391 ``caps`` is a set of capabilities supported by the remote. | 397 ``caps`` is a set of capabilities supported by the remote. |
392 ``autoreadstderr`` denotes whether to automatically read from | 398 ``autoreadstderr`` denotes whether to automatically read from |
393 stderr and to forward its output. | 399 stderr and to forward its output. |
394 """ | 400 """ |
395 super().__init__(ui, path=path, remotehidden=remotehidden) | 401 super().__init__(ui, path=path, remotehidden=remotehidden) |
396 if remotehidden: | |
397 msg = _( | |
398 b"ignoring `--remote-hidden` request\n" | |
399 b"(access to hidden changeset for ssh peers not supported " | |
400 b"yet)\n" | |
401 ) | |
402 ui.warn(msg) | |
403 # self._subprocess is unused. Keeping a handle on the process | 402 # self._subprocess is unused. Keeping a handle on the process |
404 # holds a reference and prevents it from being garbage collected. | 403 # holds a reference and prevents it from being garbage collected. |
405 self._subprocess = proc | 404 self._subprocess = proc |
406 | 405 |
407 # And we hook up our "doublepipe" wrapper to allow querying | 406 # And we hook up our "doublepipe" wrapper to allow querying |
414 self._pipei = stdout | 413 self._pipei = stdout |
415 self._pipee = stderr | 414 self._pipee = stderr |
416 self._caps = caps | 415 self._caps = caps |
417 self._autoreadstderr = autoreadstderr | 416 self._autoreadstderr = autoreadstderr |
418 self._initstack = b''.join(util.getstackframes(1)) | 417 self._initstack = b''.join(util.getstackframes(1)) |
418 self._remotehidden = remotehidden | |
419 | 419 |
420 # Commands that have a "framed" response where the first line of the | 420 # Commands that have a "framed" response where the first line of the |
421 # response contains the length of that response. | 421 # response contains the length of that response. |
422 _FRAMED_COMMANDS = { | 422 _FRAMED_COMMANDS = { |
423 b'batch', | 423 b'batch', |
681 res = ui.system(cmd, blockedtag=b'sshpeer', environ=sshenv) | 681 res = ui.system(cmd, blockedtag=b'sshpeer', environ=sshenv) |
682 if res != 0: | 682 if res != 0: |
683 raise error.RepoError(_(b'could not create remote repo')) | 683 raise error.RepoError(_(b'could not create remote repo')) |
684 | 684 |
685 proc, stdin, stdout, stderr = _makeconnection( | 685 proc, stdin, stdout, stderr = _makeconnection( |
686 ui, sshcmd, args, remotecmd, remotepath, sshenv | 686 ui, |
687 sshcmd, | |
688 args, | |
689 remotecmd, | |
690 remotepath, | |
691 sshenv, | |
692 remotehidden=remotehidden, | |
687 ) | 693 ) |
688 | 694 |
689 peer = _make_peer( | 695 peer = _make_peer( |
690 ui, path, proc, stdin, stdout, stderr, remotehidden=remotehidden | 696 ui, path, proc, stdin, stdout, stderr, remotehidden=remotehidden |
691 ) | 697 ) |