[svn r58035] allow for passing in ssh_config files, deprecat "identity" argument
--HG-- branch : trunk
This commit is contained in:
parent
37eea51f59
commit
6842e5a769
|
@ -2,6 +2,8 @@
|
||||||
import os, inspect, socket
|
import os, inspect, socket
|
||||||
import sys
|
import sys
|
||||||
from py.magic import autopath ; mypath = autopath()
|
from py.magic import autopath ; mypath = autopath()
|
||||||
|
from py.__.misc.warn import APIWARN
|
||||||
|
|
||||||
import py
|
import py
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
win32 = True
|
win32 = True
|
||||||
|
@ -55,6 +57,7 @@ class InstallableGateway(gateway.Gateway):
|
||||||
class PopenCmdGateway(InstallableGateway):
|
class PopenCmdGateway(InstallableGateway):
|
||||||
def __init__(self, cmd):
|
def __init__(self, cmd):
|
||||||
infile, outfile = os.popen2(cmd)
|
infile, outfile = os.popen2(cmd)
|
||||||
|
self._cmd = cmd
|
||||||
io = inputoutput.Popen2IO(infile, outfile)
|
io = inputoutput.Popen2IO(infile, outfile)
|
||||||
super(PopenCmdGateway, self).__init__(io=io)
|
super(PopenCmdGateway, self).__init__(io=io)
|
||||||
|
|
||||||
|
@ -130,14 +133,16 @@ class SocketGateway(InstallableGateway):
|
||||||
|
|
||||||
|
|
||||||
class SshGateway(PopenCmdGateway):
|
class SshGateway(PopenCmdGateway):
|
||||||
""" This Gateway provides interaction with a remote process,
|
""" This Gateway provides interaction with a remote Python process,
|
||||||
established via the 'ssh' command line binary.
|
established via the 'ssh' command line binary.
|
||||||
The remote side needs to have a Python interpreter executable.
|
The remote side needs to have a Python interpreter executable.
|
||||||
"""
|
"""
|
||||||
def __init__(self, sshaddress, remotepython='python', identity=None):
|
def __init__(self, sshaddress, remotepython='python',
|
||||||
|
identity=None, ssh_config=None):
|
||||||
""" instantiate a remote ssh process with the
|
""" instantiate a remote ssh process with the
|
||||||
given 'sshaddress' and remotepython version.
|
given 'sshaddress' and remotepython version.
|
||||||
you may specify an 'identity' filepath.
|
you may specify an ssh_config file.
|
||||||
|
DEPRECATED: you may specify an 'identity' filepath.
|
||||||
"""
|
"""
|
||||||
self.remoteaddress = sshaddress
|
self.remoteaddress = sshaddress
|
||||||
remotecmd = '%s -u -c "exec input()"' % (remotepython,)
|
remotecmd = '%s -u -c "exec input()"' % (remotepython,)
|
||||||
|
@ -147,9 +152,13 @@ class SshGateway(PopenCmdGateway):
|
||||||
cmdline[i] = "'" + cmdline[i].replace("'", "'\\''") + "'"
|
cmdline[i] = "'" + cmdline[i].replace("'", "'\\''") + "'"
|
||||||
cmd = 'ssh -C'
|
cmd = 'ssh -C'
|
||||||
if identity is not None:
|
if identity is not None:
|
||||||
|
APIWARN("1.0", "pass in 'ssh_config' file instead of identity")
|
||||||
cmd += ' -i %s' % (identity,)
|
cmd += ' -i %s' % (identity,)
|
||||||
|
if ssh_config is not None:
|
||||||
|
cmd += ' -F %s' % (ssh_config)
|
||||||
cmdline.insert(0, cmd)
|
cmdline.insert(0, cmd)
|
||||||
super(SshGateway, self).__init__(' '.join(cmdline))
|
cmd = ' '.join(cmdline)
|
||||||
|
super(SshGateway, self).__init__(cmd)
|
||||||
|
|
||||||
def _remote_bootstrap_gateway(self, io, s=""):
|
def _remote_bootstrap_gateway(self, io, s=""):
|
||||||
extra = "\n".join([
|
extra = "\n".join([
|
||||||
|
|
|
@ -439,6 +439,9 @@ class BasicRemoteExecution:
|
||||||
text = c1.receive()
|
text = c1.receive()
|
||||||
assert text.find("execution disallowed") != -1
|
assert text.find("execution disallowed") != -1
|
||||||
|
|
||||||
|
class BasicCmdbasedRemoteExecution(BasicRemoteExecution):
|
||||||
|
def test_cmdattr(self):
|
||||||
|
assert hasattr(self.gw, '_cmd')
|
||||||
|
|
||||||
def test_channel_endmarker_remote_killterm():
|
def test_channel_endmarker_remote_killterm():
|
||||||
gw = py.execnet.PopenGateway()
|
gw = py.execnet.PopenGateway()
|
||||||
|
@ -571,20 +574,31 @@ class TestSshGateway(BasicRemoteExecution):
|
||||||
py.test.skip("no known ssh target, use -S to set one")
|
py.test.skip("no known ssh target, use -S to set one")
|
||||||
cls.gw = py.execnet.SshGateway(option.sshtarget)
|
cls.gw = py.execnet.SshGateway(option.sshtarget)
|
||||||
|
|
||||||
|
def test_sshconfig_functional(self):
|
||||||
|
tmpdir = py.test.ensuretemp("test_sshconfig")
|
||||||
|
ssh_config = tmpdir.join("ssh_config")
|
||||||
|
ssh_config.write(
|
||||||
|
"Host alias123\n"
|
||||||
|
" HostName %s\n" % (option.sshtarget,))
|
||||||
|
gw = py.execnet.SshGateway("alias123", ssh_config=ssh_config)
|
||||||
|
assert gw._cmd.find("-F") != -1
|
||||||
|
assert gw._cmd.find(str(ssh_config)) != -1
|
||||||
|
pid = gw.remote_exec("import os ; channel.send(os.getpid())").receive()
|
||||||
|
gw.exit()
|
||||||
|
|
||||||
def test_sshaddress(self):
|
def test_sshaddress(self):
|
||||||
assert self.gw.remoteaddress == option.sshtarget
|
assert self.gw.remoteaddress == option.sshtarget
|
||||||
|
|
||||||
def test_failed_connexion(self):
|
def test_connexion_failes_on_non_existing_hosts(self):
|
||||||
gw = py.execnet.SshGateway('nowhere.codespeak.net')
|
py.test.raises(IOError,
|
||||||
try:
|
"py.execnet.SshGateway('nowhere.codespeak.net')")
|
||||||
channel = gw.remote_exec("...")
|
|
||||||
except IOError:
|
def test_deprecated_identity(self):
|
||||||
pass # connexion failed already
|
py.test.deprecated_call(
|
||||||
else:
|
py.test.raises, IOError,
|
||||||
# connexion did not fail yet
|
py.execnet.SshGateway,
|
||||||
py.test.raises(EOFError, channel.receive)
|
'nowhere.codespeak.net', identity='qwe')
|
||||||
# now it did
|
|
||||||
py.test.raises(IOError, gw.remote_exec, "...")
|
|
||||||
|
|
||||||
def test_threads():
|
def test_threads():
|
||||||
gw = py.execnet.PopenGateway()
|
gw = py.execnet.PopenGateway()
|
||||||
|
|
Loading…
Reference in New Issue