aiidateam / aiida-core

The official repository for the AiiDA code
https://aiida-core.readthedocs.io
Other
435 stars 188 forks source link

Support `None` for SSH key file specification in `verdi computer configure ssh` #4101

Open ConradJohnston opened 4 years ago

ConradJohnston commented 4 years ago

Currently, when configuring an SSH connection, one must specify an SSH key. It no value is specified, an empty string is stored as the key path and so breaks the transport.

When port forwarding (see also #4100), it would be convenient to be able to not specify an SSH key. An empty string here should be interpreted as None and handled. This is different to local transport as we want to get to somewhere that is behind an SSH connection, it's just that for the local leg we don't need to present an SSH key.

chrisjsewell commented 4 years ago

Are you sure you can't use !?

$ verdi computer configure ssh 3
Info: enter "?" for help
Info: enter "!" to ignore the default and set no value
User name [aiida]: 
port Nr [22]: 
Look for keys [False]: 
SSH key file []: !
ConradJohnston commented 4 years ago

Hi @chrisjsewell , I agree that in principle ! should work, but it seems to fill an empty string which then leads to this failure when trying to make the SSH connection:

[FAILED]: Error while trying to connect to the computer
  Full traceback:
  Traceback (most recent call last):
    File "/Users/cjohnson/Code/aiida-core/aiida/cmdline/commands/cmd_computer.py", line 503, in computer_test
      with transport:
    File "/Users/cjohnson/Code/aiida-core/aiida/transports/transport.py", line 96, in __enter__
      self.open()
    File "/Users/cjohnson/Code/aiida-core/aiida/transports/plugins/ssh.py", line 414, in open
      self._client.connect(self._machine, **connection_arguments)
    File "/Users/cjohnson/.virtualenvs/aiidapy/lib/python3.7/site-packages/paramiko/client.py", line 446, in connect
      passphrase,
    File "/Users/cjohnson/.virtualenvs/aiidapy/lib/python3.7/site-packages/paramiko/client.py", line 677, in _auth
      key_filename, pkey_class, passphrase
    File "/Users/cjohnson/.virtualenvs/aiidapy/lib/python3.7/site-packages/paramiko/client.py", line 586, in _key_from_filepath
      key = klass.from_private_key_file(key_path, password)
    File "/Users/cjohnson/.virtualenvs/aiidapy/lib/python3.7/site-packages/paramiko/pkey.py", line 235, in from_private_key_file
      key = cls(filename=filename, password=password)
    File "/Users/cjohnson/.virtualenvs/aiidapy/lib/python3.7/site-packages/paramiko/rsakey.py", line 55, in __init__
      self._from_private_key_file(filename, password)
    File "/Users/cjohnson/.virtualenvs/aiidapy/lib/python3.7/site-packages/paramiko/rsakey.py", line 175, in _from_private_key_file
      data = self._read_private_key_file("RSA", filename, password)
    File "/Users/cjohnson/.virtualenvs/aiidapy/lib/python3.7/site-packages/paramiko/pkey.py", line 307, in _read_private_key_file
      with open(filename, "r") as f:
  FileNotFoundError: [Errno 2] No such file or directory: ''
Warning: 1 out of 0 tests failed
giovannipizzi commented 4 years ago

Hi, I think I had fixed it a few days ago here: #4055

Could you check that this fix works (it's now in develop)?

ltalirz commented 4 years ago

I just tested this on the tutorial VM:

In [2]: c =load_computer('sshtest')

In [3]: au=c.get_authinfo(u)

In [4]: au.get_auth_params() Out[4]: {'port': 22, 'gss_kex': False, 'timeout': 60, 'compress': True, 'gss_auth': False, 'gss_host': 'localhost', 'username': 'max', 'key_policy': 'RejectPolicy', 'allow_agent': True, 'key_filename': '', 'look_for_keys': True, 'proxy_command': '', 'safe_interval': 30.0, 'gss_deleg_creds': False, 'load_system_host_keys': True}



Is this correct or should there be `None` for the `key_filename`?
I currently don't have a paswordless SSH host set up to test further...
giovannipizzi commented 4 years ago

If you check my fix, you'll see that in practice it's a workaround to ignore empty strings for the key_filename (they won't be passed to paramiko) so this should work