sshpeer: allow for additional environment passing to ssh exe
authorKostia Balytskyi <ikostia@fb.com>
Thu, 14 Dec 2017 14:31:57 +0000
changeset 35436 31d21309635b
parent 35435 f01101100043
child 35437 cf532a62e337
sshpeer: allow for additional environment passing to ssh exe We already have the ability to customize the ssh command line arguments, let's add the ability to customize its environment as well. Example use-case is ssh.exe from Git on Windows. If `HOME` enviroment variable is present and has some non-empty value, ssh.exe will try to access that location for some stuff (for example, it seems for resolving `~` in `.ssh/config`). Git for Windows seems to sometimess set this variable to the value of `/home/username` which probably works under Git Bash, but does not work in a native `cmd.exe` or `powershell`. Whatever the root cause, setting `HOME` to be an empty string heals things. Therefore, some distributors might want to set `sshenv.HOME=` in the configuration (seems less intrusive that forcing everyone to tweak their env). Test Plan: - rt Differential Revision: https://phab.mercurial-scm.org/D1683
mercurial/sshpeer.py
tests/test-ssh.t
--- a/mercurial/sshpeer.py	Wed Dec 13 17:03:39 2017 -0800
+++ b/mercurial/sshpeer.py	Thu Dec 14 14:31:57 2017 +0000
@@ -136,6 +136,8 @@
 
         sshcmd = self.ui.config("ui", "ssh")
         remotecmd = self.ui.config("ui", "remotecmd")
+        sshaddenv = dict(self.ui.configitems("sshenv"))
+        sshenv = util.shellenviron(sshaddenv)
 
         args = util.sshargs(sshcmd, self._host, self._user, self._port)
 
@@ -144,11 +146,11 @@
                 util.shellquote("%s init %s" %
                     (_serverquote(remotecmd), _serverquote(self._path))))
             ui.debug('running %s\n' % cmd)
-            res = ui.system(cmd, blockedtag='sshpeer')
+            res = ui.system(cmd, blockedtag='sshpeer', environ=sshenv)
             if res != 0:
                 self._abort(error.RepoError(_("could not create remote repo")))
 
-        self._validaterepo(sshcmd, args, remotecmd)
+        self._validaterepo(sshcmd, args, remotecmd, sshenv)
 
     # Begin of _basepeer interface.
 
@@ -180,7 +182,7 @@
 
     # End of _basewirecommands interface.
 
-    def _validaterepo(self, sshcmd, args, remotecmd):
+    def _validaterepo(self, sshcmd, args, remotecmd, sshenv=None):
         # cleanup up previous run
         self._cleanup()
 
@@ -196,7 +198,7 @@
         # no buffer allow the use of 'select'
         # feel free to remove buffering and select usage when we ultimately
         # move to threading.
-        sub = util.popen4(cmd, bufsize=0)
+        sub = util.popen4(cmd, bufsize=0, env=sshenv)
         self._pipeo, self._pipei, self._pipee, self._subprocess = sub
 
         self._pipei = util.bufferedinputpipe(self._pipei)
--- a/tests/test-ssh.t	Wed Dec 13 17:03:39 2017 -0800
+++ b/tests/test-ssh.t	Thu Dec 14 14:31:57 2017 +0000
@@ -596,3 +596,21 @@
   abort: no suitable response from remote hg!
   (Please see http://company/internalwiki/ssh.html)
   [255]
+
+test that custom environment is passed down to ssh executable
+  $ cat >>dumpenv <<EOF
+  > #! /bin/sh
+  > echo \$VAR >&2
+  > EOF
+  $ chmod +x dumpenv
+  $ hg pull ssh://something --config ui.ssh="./dumpenv"
+  pulling from ssh://something/
+  remote: 
+  abort: no suitable response from remote hg!
+  [255]
+  $ hg pull ssh://something --config ui.ssh="./dumpenv" --config sshenv.VAR=17
+  pulling from ssh://something/
+  remote: 17
+  abort: no suitable response from remote hg!
+  [255]
+