Merge pull request #1474 from efiop/1473

ssh: `user` and `port` configuration
This commit is contained in:
Paweł Redzyński
2019-01-08 17:01:53 +01:00
committed by GitHub
4 changed files with 97 additions and 17 deletions
+2 -1
View File
@@ -714,7 +714,8 @@ def parse_args(argv=None):
help='Name.')
remote_add_parser.add_argument(
'url',
help='URL.')
help='URL. See full list of supported urls at '
'https://dvc.org/doc/commands-reference/remote')
remote_add_parser.add_argument(
'-d',
'--default',
+8 -4
View File
@@ -1,3 +1,4 @@
import getpass
import posixpath
from dvc.utils.compat import urlparse
@@ -21,15 +22,18 @@ class OutputSSH(OutputBase):
remote=remote,
cache=cache,
metric=metric)
host = remote.host if remote else self.group('host')
port = remote.port if remote else RemoteSSH.DEFAULT_PORT
user = remote.user if remote else self.group('user')
parsed = urlparse(path)
host = remote.host if remote else parsed.hostname
port = remote.port if remote else (parsed.port
or RemoteSSH.DEFAULT_PORT)
user = remote.user if remote else (parsed.username
or getpass.getuser())
if remote:
path = posixpath.join(remote.prefix,
urlparse(path).path.lstrip('/'))
else:
path = self.match(self.url).group('path')
path = parsed.path
self.path_info = {'scheme': 'ssh',
'host': host,
+18 -12
View File
@@ -9,10 +9,12 @@ except ImportError:
import dvc.prompt as prompt
import dvc.logger as logger
from dvc.progress import progress
from dvc.remote.base import RemoteBase, RemoteBaseCmdError
from dvc.config import Config
from dvc.progress import progress
from dvc.utils.compat import urlparse
from dvc.exceptions import DvcException
from dvc.remote.base import RemoteBase, RemoteBaseCmdError
def sizeof_fmt(num, suffix='B'):
@@ -44,8 +46,9 @@ class RemoteSSHCmdError(RemoteBaseCmdError):
class RemoteSSH(RemoteBase):
scheme = 'ssh'
# NOTE: temporarily only absolute paths are allowed
REGEX = r'^ssh://((?P<user>.*)@)?(?P<host>[^/]*):(?P<path>/.*)$'
# NOTE: we support both URL-like (ssh://[user@]host.xz[:port]/path) and
# SCP-like (ssh://[user@]host.xz:path) urls.
REGEX = r'^ssh://.*$'
REQUIRES = {'paramiko': paramiko}
@@ -58,14 +61,17 @@ class RemoteSSH(RemoteBase):
def __init__(self, project, config):
super(RemoteSSH, self).__init__(project, config)
self.url = config.get(Config.SECTION_REMOTE_URL, '/')
self.host = self.group('host')
self.user = self.group('user')
if not self.user:
self.user = config.get(Config.SECTION_REMOTE_USER,
getpass.getuser())
self.prefix = self.group('path')
self.port = config.get(Config.SECTION_REMOTE_PORT, self.DEFAULT_PORT)
self.url = config.get(Config.SECTION_REMOTE_URL, 'ssh://')
parsed = urlparse(self.url)
self.host = parsed.hostname
self.user = (config.get(Config.SECTION_REMOTE_USER)
or parsed.username
or getpass.getuser())
self.prefix = parsed.path
self.port = (config.get(Config.SECTION_REMOTE_PORT)
or parsed.port
or self.DEFAULT_PORT)
self.keyfile = config.get(Config.SECTION_REMOTE_KEY_FILE, None)
self.timeout = config.get(Config.SECTION_REMOTE_TIMEOUT, self.TIMEOUT)
self.password = config.get(Config.SECTION_REMOTE_PASSWORD, None)
+69
View File
@@ -0,0 +1,69 @@
import getpass
from unittest import TestCase
from dvc.remote.ssh import RemoteSSH
class TestRemoteSSH(TestCase):
def test_user(self):
url = 'ssh://127.0.0.1:/path/to/dir'
config = {'url': url}
remote = RemoteSSH(None, config)
self.assertEqual(remote.user, getpass.getuser())
user = 'test1'
url = 'ssh://{}@127.0.0.1:/path/to/dir'.format(user)
config = {'url': url}
remote = RemoteSSH(None, config)
self.assertEqual(remote.user, user)
user = 'test2'
config['user'] = user
remote = RemoteSSH(None, config)
self.assertEqual(remote.user, user)
def test_url(self):
user = 'test'
host = '123.45.67.89'
port = 1234
path = '/path/to/dir'
# URL ssh://[user@]host.xz[:port]/path
url = 'ssh://{}@{}:{}{}'.format(user, host, port, path)
config = {'url': url}
remote = RemoteSSH(None, config)
self.assertEqual(remote.user, user)
self.assertEqual(remote.host, host)
self.assertEqual(remote.port, port)
self.assertEqual(remote.prefix, path)
# SCP-like URL ssh://[user@]host.xz:path
url = 'ssh://{}@{}:{}'.format(user, host, path)
config = {'url': url}
remote = RemoteSSH(None, config)
self.assertEqual(remote.user, user)
self.assertEqual(remote.host, host)
self.assertEqual(remote.port, remote.DEFAULT_PORT)
self.assertEqual(remote.prefix, path)
def test_port(self):
url = 'ssh://127.0.0.1/path/to/dir'
config = {'url': url}
remote = RemoteSSH(None, config)
self.assertEqual(remote.port, remote.DEFAULT_PORT)
port = 1234
url = 'ssh://127.0.0.1:{}/path/to/dir'.format(port)
config = {'url': url}
remote = RemoteSSH(None, config)
self.assertEqual(remote.port, port)
port = 4321
config['port'] = port
remote = RemoteSSH(None, config)
self.assertEqual(remote.port, port)