Skip to content

Commit

Permalink
Add the SshAutoTransport transport plugin
Browse files Browse the repository at this point in the history
This is an alternative to the `SshFabricTransport` that does not depend
on the `fabric` library but instead simply modifies the `SshTransport`
plugin to not require specifying any connection arguments, but that are
instead automatically parsed from the SSH config. The `fabric` plugin
anyway uses `paramiko` under the hood to perform the actual connections,
just as the `SshTransport` plugin, and the logic to automatically
determine connection parameters is not that complicated for default
input arguments to the `fabric.Connection` class. It does do some clever
stuff with proxy commands and jumps, but that is also already
implemented by `SshTransport`. So there is little reason to add another
dependency.
  • Loading branch information
sphuber committed Jul 20, 2024
1 parent 73e1a03 commit 22a6e69
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 2 deletions.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ requires-python = '>=3.9'
[project.entry-points.'aiida.transports']
'core.local' = 'aiida.transports.plugins.local:LocalTransport'
'core.ssh' = 'aiida.transports.plugins.ssh:SshTransport'
'core.ssh_auto' = 'aiida.transports.plugins.ssh_auto:SshAutoTransport'
'core.ssh_fabric' = 'aiida.transports.plugins.ssh_fabric:SshFabricTransport'

[project.entry-points.'aiida.workflows']
Expand Down
50 changes: 50 additions & 0 deletions src/aiida/transports/plugins/ssh_auto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
###########################################################################
# Copyright (c), The AiiDA team. All rights reserved. #
# This file is part of the AiiDA code. #
# #
# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core #
# For further information on the license, see the LICENSE.txt file #
# For further information please visit http://www.aiida.net #
###########################################################################
"""Plugin for transport over SSH (and SFTP for file transfer)."""

import pathlib

import paramiko

from .ssh import SshTransport

__all__ = ('SshAutoTransport',)


class SshAutoTransport(SshTransport):
"""Support connection, command execution and data transfer to remote computers via SSH+SFTP."""

_valid_connect_params = []
_valid_auth_options = []

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs, key_policy='AutoAddPolicy')

config_ssh = paramiko.SSHConfig()

with (pathlib.Path('~').expanduser() / '.ssh' / 'config').open() as handle:
config_ssh.parse(handle)

if self._machine not in config_ssh.get_hostnames():
self.logger.warning(
f'The host `{self._machine}` is not defined in SSH config, connection will most likely fail to open.'
)

config_host = config_ssh.lookup(self._machine)

self._connect_args = {
'port': config_host.get('port', 22),
'username': config_host.get('user'),
'key_filename': config_host.get('identityfile', []),
'timeout': config_host.get('connecttimeout', 60),
'proxy_command': config_host.get('proxycommand', None),
'proxy_jump': config_host.get('proxyjump', None),
}

self._machine = config_host['hostname']
1 change: 1 addition & 0 deletions src/aiida/transports/plugins/ssh_fabric.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
exposed on the ``fabric.Connection`` instance and is proxied to the ``_client`` attribute of the class where the
``SshTransport`` base class expects to find it.
"""

import fabric

from aiida.common.exceptions import InvalidOperation
Expand Down
3 changes: 1 addition & 2 deletions tests/engine/daemon/test_execmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from aiida.common.folders import SandboxFolder
from aiida.engine.daemon import execmanager
from aiida.orm import CalcJobNode, FolderData, PortableCode, RemoteData, SinglefileData
from aiida.plugins import entry_point
from aiida.transports.plugins.local import LocalTransport


Expand All @@ -40,7 +39,7 @@ def file_hierarchy_simple():
}


@pytest.fixture(params=entry_point.get_entry_point_names('aiida.transports'))
@pytest.fixture(params=('core.local', 'core.ssh'))
def node_and_calc_info(aiida_localhost, aiida_computer_ssh, aiida_code_installed, request):
"""Return a ``CalcJobNode`` and associated ``CalcInfo`` instance."""

Expand Down
2 changes: 2 additions & 0 deletions tests/transports/test_all_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ def custom_transport(request) -> Transport:
kwargs = {'machine': 'localhost', 'timeout': 30, 'load_system_host_keys': True, 'key_policy': 'AutoAddPolicy'}
elif request.param == 'core.ssh_fabric':
kwargs = {'machine': 'localhost'}
elif request.param == 'core.ssh_auto':
kwargs = {'machine': 'localhost'}
else:
kwargs = {}

Expand Down

0 comments on commit 22a6e69

Please sign in to comment.