Source code for datalad_next.patches.sshconnector

"""Provide proper arguments for scp-command calls in `SSHConnection`

The original code has errors in the methods ``BaseSSHConnection.put``
``BaseSSHConnection.get``. Both methods use ``self.sshri.hostname`` to
determine the target for an ``scp``-command. They should instead use
``self.sshri.as_str()`` in order to include a user specification into the
target.

The changes in this patch use ``self.sshri.as_str()`` to provide the correct
targets for ``scp``-commands.
"""

import logging

from datalad.support.sshconnector import (
    StdOutErrCapture,
    ensure_list,
)
from datalad_next.patches import apply_patch


# use same logger as -core
lgr = logging.getLogger('datalad.support.sshconnector')


# The method 'BaseSSHConnection_get' is a patched version of
# 'datalad/support/sshconnector.py:BaseSSHConnection.get'
# from datalad@e0b357d9b8ca5f432638c23c0cb7c373028c8e52
[docs] def BaseSSHConnection_get(self, source, destination, recursive=False, preserve_attrs=False): """Copies source file/folder from remote to a local destination. Note: this method performs escaping of filenames to an extent that moderately weird ones should work (spaces, quotes, pipes, other characters with special shell meaning), but more complicated cases might require appropriate external preprocessing of filenames. Parameters ---------- source : str or list file/folder path(s) to copy from the remote host destination : str file/folder path to copy to on the local host recursive : bool flag to enable recursive copying of given sources preserve_attrs : bool preserve modification times, access times, and modes from the original file Returns ------- str stdout, stderr of the copy operation. """ # make sure we have an open connection, will test if action is needed # by itself self.open() scp_cmd = self._get_scp_command_spec(recursive, preserve_attrs) # add source filepath(s) to scp command, prefixed with the remote host # PATCH in the line below: replaces `self.sshri.hostname` with `self.sshri.as_str()` scp_cmd += ["%s:%s" % (self.sshri.as_str(), self._quote_filename(s)) for s in ensure_list(source)] # add destination path scp_cmd += [destination] out = self.runner.run(scp_cmd, protocol=StdOutErrCapture) return out['stdout'], out['stderr']
# The method 'BaseSSHConnection_put' is a patched version of # 'datalad/support/sshconnector.py:BaseSSHConnection.put' # from datalad@e0b357d9b8ca5f432638c23c0cb7c373028c8e52
[docs] def BaseSSHConnection_put(self, source, destination, recursive=False, preserve_attrs=False): """Copies source file/folder to destination on the remote. Note: this method performs escaping of filenames to an extent that moderately weird ones should work (spaces, quotes, pipes, other characters with special shell meaning), but more complicated cases might require appropriate external preprocessing of filenames. Parameters ---------- source : str or list file/folder path(s) to copy from on local destination : str file/folder path to copy to on remote recursive : bool flag to enable recursive copying of given sources preserve_attrs : bool preserve modification times, access times, and modes from the original file Returns ------- str stdout, stderr of the copy operation. """ # make sure we have an open connection, will test if action is needed # by itself self.open() scp_cmd = self._get_scp_command_spec(recursive, preserve_attrs) # add source filepath(s) to scp command scp_cmd += ensure_list(source) # add destination path scp_cmd += ['%s:%s' % ( # PATCH in the line below: replaces `self.sshri.hostname` with `self.sshri.as_str()` self.sshri.as_str(), self._quote_filename(destination), )] out = self.runner.run(scp_cmd, protocol=StdOutErrCapture) return out['stdout'], out['stderr']
apply_patch( modname='datalad.support.sshconnector', objname='BaseSSHConnection', attrname='get', patch=BaseSSHConnection_get, ) apply_patch( modname='datalad.support.sshconnector', objname='BaseSSHConnection', attrname='put', patch=BaseSSHConnection_put, )