diff options
Diffstat (limited to 'lorrycontroller/hosts.py')
-rw-r--r-- | lorrycontroller/hosts.py | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/lorrycontroller/hosts.py b/lorrycontroller/hosts.py index 39cae57..fb892dc 100644 --- a/lorrycontroller/hosts.py +++ b/lorrycontroller/hosts.py @@ -14,6 +14,10 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import abc +import shlex +import urllib.parse + +import cliapp class DownstreamHost(abc.ABC): @@ -119,3 +123,37 @@ class UpstreamHost(abc.ABC): DownstreamHost.prepare_repo. ''' pass + + +class SshCommand: + def __init__(self, urlstring, **options): + try: + url = urllib.parse.urlsplit(urlstring, allow_fragments=False) + url.port + except ValueError: + raise cliapp.AppException('Invalid URL: %s' % urlstring) + + if url.scheme != 'ssh': + raise cliapp.AppException('Not an SSH URL: %s' % urlstring) + if url.path not in ['', '/']: + raise cliapp.AppException('Unexpected path part in SSH URL') + if url.query != '': + raise cliapp.AppException('Unexpected query part in SSH URL') + if url.password is not None: + raise cliapp.AppException('Unexpected password in SSH URL') + + self._ssh_args = ['ssh', '-oBatchMode=yes'] + for key, value in options.items(): + self._ssh_args.append('-o%s=%s' % (key, value)) + if url.username is not None: + self._ssh_args.append('-oUser=%s' % url.username) + if url.port is not None: + self._ssh_args.append('-p%i' % url.port) + self._ssh_args.append(url.hostname) + + def run(self, args): + quoted_args = [shlex.quote(arg) for arg in args] + stdout = cliapp.runcmd(self._ssh_args + quoted_args) + if isinstance(stdout, bytes): + stdout = stdout.decode('utf-8', errors='replace') + return stdout |