mercurial/sshpeer.py
changeset 35935 00b9e26d727b
parent 35934 94ba29934f00
child 35936 f8f034344b39
equal deleted inserted replaced
35934:94ba29934f00 35935:00b9e26d727b
   129         except (IOError, ValueError):
   129         except (IOError, ValueError):
   130             pass
   130             pass
   131 
   131 
   132         pipee.close()
   132         pipee.close()
   133 
   133 
       
   134 def _makeconnection(ui, sshcmd, args, remotecmd, path, sshenv=None):
       
   135     """Create an SSH connection to a server.
       
   136 
       
   137     Returns a tuple of (process, stdin, stdout, stderr) for the
       
   138     spawned process.
       
   139     """
       
   140     cmd = '%s %s %s' % (
       
   141         sshcmd,
       
   142         args,
       
   143         util.shellquote('%s -R %s serve --stdio' % (
       
   144             _serverquote(remotecmd), _serverquote(path))))
       
   145 
       
   146     ui.debug('running %s\n' % cmd)
       
   147     cmd = util.quotecommand(cmd)
       
   148 
       
   149     # no buffer allow the use of 'select'
       
   150     # feel free to remove buffering and select usage when we ultimately
       
   151     # move to threading.
       
   152     stdin, stdout, stderr, proc = util.popen4(cmd, bufsize=0, env=sshenv)
       
   153 
       
   154     stdout = doublepipe(ui, util.bufferedinputpipe(stdout), stderr)
       
   155     stdin = doublepipe(ui, stdin, stderr)
       
   156 
       
   157     return proc, stdin, stdout, stderr
       
   158 
   134 class sshpeer(wireproto.wirepeer):
   159 class sshpeer(wireproto.wirepeer):
   135     def __init__(self, ui, path, create=False, sshstate=None):
   160     def __init__(self, ui, path, create=False, sshstate=None):
   136         self._url = path
   161         self._url = path
   137         self._ui = ui
   162         self._ui = ui
   138         self._pipeo = self._pipei = self._pipee = None
   163         # self._subprocess is unused. Keeping a handle on the process
   139 
   164         # holds a reference and prevents it from being garbage collected.
   140         u = util.url(path, parsequery=False, parsefragment=False)
   165         self._subprocess, self._pipei, self._pipeo, self._pipee = sshstate
   141         self._path = u.path or '.'
   166 
   142 
   167         self._validaterepo()
   143         self._validaterepo(*sshstate)
       
   144 
   168 
   145     # Begin of _basepeer interface.
   169     # Begin of _basepeer interface.
   146 
   170 
   147     @util.propertycache
   171     @util.propertycache
   148     def ui(self):
   172     def ui(self):
   170     def capabilities(self):
   194     def capabilities(self):
   171         return self._caps
   195         return self._caps
   172 
   196 
   173     # End of _basewirecommands interface.
   197     # End of _basewirecommands interface.
   174 
   198 
   175     def _validaterepo(self, sshcmd, args, remotecmd, sshenv=None):
   199     def _validaterepo(self):
   176         assert self._pipei is None
       
   177 
       
   178         cmd = '%s %s %s' % (sshcmd, args,
       
   179             util.shellquote("%s -R %s serve --stdio" %
       
   180                 (_serverquote(remotecmd), _serverquote(self._path))))
       
   181         self.ui.debug('running %s\n' % cmd)
       
   182         cmd = util.quotecommand(cmd)
       
   183 
       
   184         # while self._subprocess isn't used, having it allows the subprocess to
       
   185         # to clean up correctly later
       
   186         #
       
   187         # no buffer allow the use of 'select'
       
   188         # feel free to remove buffering and select usage when we ultimately
       
   189         # move to threading.
       
   190         sub = util.popen4(cmd, bufsize=0, env=sshenv)
       
   191         self._pipeo, self._pipei, self._pipee, self._subprocess = sub
       
   192 
       
   193         self._pipei = util.bufferedinputpipe(self._pipei)
       
   194         self._pipei = doublepipe(self.ui, self._pipei, self._pipee)
       
   195         self._pipeo = doublepipe(self.ui, self._pipeo, self._pipee)
       
   196 
       
   197         def badresponse():
   200         def badresponse():
   198             msg = _("no suitable response from remote hg")
   201             msg = _("no suitable response from remote hg")
   199             hint = self.ui.config("ui", "ssherrorhint")
   202             hint = self.ui.config("ui", "ssherrorhint")
   200             self._abort(error.RepoError(msg, hint=hint))
   203             self._abort(error.RepoError(msg, hint=hint))
   201 
   204 
   378         ui.debug('running %s\n' % cmd)
   381         ui.debug('running %s\n' % cmd)
   379         res = ui.system(cmd, blockedtag='sshpeer', environ=sshenv)
   382         res = ui.system(cmd, blockedtag='sshpeer', environ=sshenv)
   380         if res != 0:
   383         if res != 0:
   381             raise error.RepoError(_('could not create remote repo'))
   384             raise error.RepoError(_('could not create remote repo'))
   382 
   385 
   383     sshstate = (sshcmd, args, remotecmd, sshenv)
   386     proc, stdin, stdout, stderr = _makeconnection(ui, sshcmd, args, remotecmd,
       
   387                                                   remotepath, sshenv)
       
   388 
       
   389     sshstate = (proc, stdout, stdin, stderr)
   384 
   390 
   385     return sshpeer(ui, path, create=create, sshstate=sshstate)
   391     return sshpeer(ui, path, create=create, sshstate=sshstate)