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 )