Skip to content

Commit

Permalink
Always look up a "front end" name in the SSH config file and possibly…
Browse files Browse the repository at this point in the history
… translate it.

If a "HostName" directive is specified in the SSH config file, the host name or
IP address following it are used in stead of the "frontend =" value from the
GC3Pie config file.

This was supposed to happen since SSH config lookups were implemented, but a
wrong code path resulted in overwriting the output of the "HostName" directive
with the value read in GC3Pie's config file.

Thanks to Kyle Robertson for reporting the bug!
  • Loading branch information
riccardomurri committed Mar 29, 2017
1 parent 40bf084 commit d1e3aa9
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 14 deletions.
2 changes: 1 addition & 1 deletion gc3libs/backends/shellcmd.py
Expand Up @@ -485,7 +485,7 @@ def fget(self):

def fset(self, value):
self._frontend = value
self.transport.remote_frontend = value
self.transport.set_connection_params(value)
return locals()

def _gather_machine_specs(self):
Expand Down
45 changes: 32 additions & 13 deletions gc3libs/backends/transport.py
Expand Up @@ -438,32 +438,38 @@ def __init__(self, remote_frontend,
Additional arguments ``user``, ``port``, ``keyfile``, and
``timeout``, if given, override the above settings.
"""
self.remote_frontend = remote_frontend
self.port = port
self.username = username

self.ssh = paramiko.SSHClient()
self.ignore_ssh_host_keys = ignore_ssh_host_keys
self.sftp = None
self._is_open = False
self.transport_channel = None

# use SSH options, if available
sshcfg = paramiko.SSHConfig()
self._ssh_config = paramiko.SSHConfig()
config_filename = os.path.expanduser(ssh_config or gc3libs.Default.SSH_CONFIG_FILE)
if os.path.exists(config_filename):
with open(config_filename, 'r') as config_file:
sshcfg.parse(config_file)
# check if we have an ssh configuration stanza for this host
ssh_options = sshcfg.lookup(self.remote_frontend)
else:
# no options
ssh_options = {}
self._ssh_config.parse(config_file)

self.set_connection_params(remote_frontend, username, keyfile, port, timeout)


def set_connection_params(self, hostname, username=None, keyfile=None,
port=None, timeout=None):
"""
Set remote host name and other parameters used for new connections.
Currently-established connections are not affected.
The host name is the only mandatory argument; any other parameter will
be read from the SSH configuration file (unless explicitly provided to
this function).
"""
# check if we have an ssh configuration stanza for this host
ssh_options = self._ssh_config.lookup(hostname)

# merge SSH options from the SSH config file with parameters
# we were given in this method call
if 'hostname' in ssh_options:
self.remote_frontend = ssh_options['hostname']
self.remote_frontend = ssh_options.get('hostname', hostname)

if username is None:
self.username = ssh_options.get('user', None)
Expand Down Expand Up @@ -854,6 +860,19 @@ def __init__(self):
# into `.remote_frontend`
self.remote_frontend = (platform.node() or 'localhost')

# pylint: disable=too-many-arguments,unused-argument
def set_connection_params(self, hostname, username=None, keyfile=None,
port=None, timeout=None):
"""
Set the host name stored in this `LocalTransport` instance.
Any other argument is ignored.
This method exists only for interface compatibility with
:class:`SshTranport`, which see.
"""
self.remote_frontend = hostname


def get_proc_state(self, pid):
"""
Getting process state.
Expand Down

0 comments on commit d1e3aa9

Please sign in to comment.