diff --git a/aiida/transport/plugins/ssh.py b/aiida/transport/plugins/ssh.py index a1e6c7f29f..80e578ff49 100644 --- a/aiida/transport/plugins/ssh.py +++ b/aiida/transport/plugins/ssh.py @@ -188,7 +188,7 @@ def _convert_timeout_fromstring(cls, string): def _get_timeout_suggestion_string(cls, computer): """ Return a suggestion for the specific field. - + Provide 60s as a default timeout for connections. """ config = parse_sshconfig(computer.hostname) @@ -398,7 +398,7 @@ def _get_gss_host_suggestion_string(cls, computer): def __init__(self, machine, **kwargs): """ Initialize the SshTransport class. - + :param machine: the machine to connect to :param load_system_host_keys: (optional, default False) if False, do not load the system host keys @@ -447,11 +447,11 @@ def __init__(self, machine, **kwargs): def open(self): """ Open a SSHClient to the machine possibly using the parameters given - in the __init__. - + in the __init__. + Also opens a sftp channel, ready to be used. The current working directory is set explicitly, so it is not None. - + :raise InvalidOperation: if the channel is already open """ from aiida.common.exceptions import InvalidOperation @@ -484,9 +484,9 @@ def open(self): def close(self): """ Close the SFTP channel, and the SSHClient. - + :todo: correctly manage exceptions - + :raise InvalidOperation: if the channel is already open """ from aiida.common.exceptions import InvalidOperation @@ -533,7 +533,7 @@ def __str__(self): def chdir(self, path): """ Change directory of the SFTP session. Emulated internally by - paramiko. + paramiko. Differently from paramiko, if you pass None to chdir, nothing happens and the cwd is unchanged. @@ -900,7 +900,7 @@ def get(self, remotepath, localpath, callback=None, dereference=True, overwrite= :param remotepath: a remote path :param localpath: an (absolute) local path :param dereference: follow symbolic links. - Default = True (default behaviour in paramiko). + Default = True (default behaviour in paramiko). False is not implemented. :param overwrite: if True overwrites files and folders. Default = False @@ -997,8 +997,8 @@ def gettree(self, remotepath, localpath, callback=None, dereference=True, overwr :param remotepath: a remote path :param localpath: an (absolute) local path - :param dereference: follow symbolic links. - Default = True (default behaviour in paramiko). + :param dereference: follow symbolic links. + Default = True (default behaviour in paramiko). False is not implemented. :param overwrite: if True overwrites files and folders. Default = False @@ -1061,8 +1061,8 @@ def copyfile(self, remotesource, remotedestination, dereference=False, pattern=N """ Copy a file from remote source to remote destination Redirects to copy(). - - :param remotesource: + + :param remotesource: :param remotedestination: :param dereference: :param pattern: @@ -1263,10 +1263,10 @@ def _exec_command_internal(self, command, combine_stderr=False, bufsize=-1): stderr on the same buffer (i.e., stdout). Note: If combine_stderr is True, stderr will always be empty. :param bufsize: same meaning of the one used by paramiko. - + :return: a tuple with (stdin, stdout, stderr, channel), where stdin, stdout and stderr behave as file-like objects, - plus the methods provided by paramiko, and channel is a + plus the methods provided by paramiko, and channel is a paramiko.Channel object. """ channel = self.sshclient.get_transport().open_session() @@ -1292,7 +1292,7 @@ def _exec_command_internal(self, command, combine_stderr=False, bufsize=-1): def exec_command_wait(self, command, stdin=None, combine_stderr=False, bufsize=-1): """ Executes the specified command and waits for it to finish. - + :param command: the command to execute :param stdin: (optional,default=None) can be a string or a file-like object. @@ -1324,11 +1324,11 @@ def exec_command_wait(self, command, stdin=None, combine_stderr=False, bufsize=- ssh_stdin.flush() ssh_stdin.channel.shutdown_write() - output_text = stdout.read() - - # I get the return code (blocking, but in principle I waited above) + # I get the return code (blocking) retval = channel.recv_exit_status() + # needs to be after 'recv_exit_status', otherwise it might hang + output_text = stdout.read() stderr_text = stderr.read() return retval, output_text, stderr_text @@ -1367,10 +1367,10 @@ def gotocomputer_command(self, remotedir): def symlink(self, remotesource, remotedestination): """ - Create a symbolic link between the remote source and the remote + Create a symbolic link between the remote source and the remote destination. - - :param remotesource: remote source. Can contain a pattern. + + :param remotesource: remote source. Can contain a pattern. :param remotedestination: remote destination """ # paramiko gives some errors if path is starting with '.'