diff options
author | Ben Hutchings <ben.hutchings@codethink.co.uk> | 2020-06-01 17:16:29 +0100 |
---|---|---|
committer | Ben Hutchings <ben.hutchings@codethink.co.uk> | 2020-06-01 17:16:29 +0100 |
commit | 1306be9e3ccc086153ffe0e28d2d7062f45dc157 (patch) | |
tree | 05420f7226c21c621b4319abd8909574aa01d218 /lorrycontroller | |
parent | a1d1913dcc2c73a961921213c9cfe8fc2cddbdae (diff) | |
parent | f5d6b9a5124dd133251aed8202e0ba8a4dda4f4a (diff) | |
download | lorry-controller-1306be9e3ccc086153ffe0e28d2d7062f45dc157.tar.gz |
Merge branch 'bwh/remote-downstreams' into bwh/gitea-support
Diffstat (limited to 'lorrycontroller')
-rw-r--r-- | lorrycontroller/gerrit.py | 34 | ||||
-rw-r--r-- | lorrycontroller/gitlab.py | 18 | ||||
-rw-r--r-- | lorrycontroller/hosts.py | 38 |
3 files changed, 62 insertions, 28 deletions
diff --git a/lorrycontroller/gerrit.py b/lorrycontroller/gerrit.py index c5498e2..5a35920 100644 --- a/lorrycontroller/gerrit.py +++ b/lorrycontroller/gerrit.py @@ -37,26 +37,20 @@ class GerritDownstream(hosts.DownstreamHost): 'Cannot create non-private repositories in Gerrit') def __init__(self, app_settings): - # XXX These need to be configurable - host = 'localhost' - port = 29418 - user = 'lorry' - - self._ssh_command_args = [ - 'ssh', '-oStrictHostKeyChecking=no', '-oBatchMode=yes', '-p%i' % port, - '%s@%s' % (user, host)] - - def _ssh_command(self, command): - out = cliapp.runcmd(self._ssh_command_args + command) - if isinstance(out, bytes): - out = out.decode('utf-8', errors='replace') - return out + url = app_settings['downstream-ssh-url'] + if url is None: + url = 'ssh://lorry@localhost:29418' + key_check = 'no' + else: + key_check = 'yes' + self._ssh_command = hosts.SshCommand( + url, StrictHostKeyChecking=key_check) def _has_project(self, name): # There's no 'does this project exist' command in Gerrit 2.9.4; 'list # all projects with this prefix' is as close we can get. - output = self._ssh_command([ + output = self._ssh_command.run([ 'gerrit', 'ls-projects', '--type=ALL', '--prefix=%s' % name]) projects = output.strip().split('\n') @@ -76,17 +70,17 @@ class GerritDownstream(hosts.DownstreamHost): logging.info('Project %s exists in local Gerrit already.', name) else: - self._ssh_command(['gerrit', 'create-project', name]) + self._ssh_command.run(['gerrit', 'create-project', name]) logging.info('Created %s project in local Gerrit.', name) # We can only set this metadata if we're the owner of the # repository. For now, ignore failures. try: if 'head' in metadata: - self._ssh_command(['gerrit', 'set-head', name, - '--new-head', metadata['head']]) + self._ssh_command.run(['gerrit', 'set-head', name, + '--new-head', metadata['head']]) if 'description' in metadata: - self._ssh_command(['gerrit', 'set-project', name, - '-d', metadata['description']]) + self._ssh_command.run(['gerrit', 'set-project', name, + '-d', metadata['description']]) except cliapp.AppException: pass diff --git a/lorrycontroller/gitlab.py b/lorrycontroller/gitlab.py index 759cdb0..4fdbab2 100644 --- a/lorrycontroller/gitlab.py +++ b/lorrycontroller/gitlab.py @@ -37,9 +37,8 @@ class MissingGitlabModuleError(Exception): pass -def _init_gitlab(host, token): +def _init_gitlab(url, token): if gitlab: - url = "http://" + host return gitlab.Gitlab(url, token) else: raise MissingGitlabModuleError('gitlab module missing\n' @@ -61,10 +60,10 @@ class GitlabDownstream(hosts.DownstreamHost): app_settings.require('gitlab-private-token') def __init__(self, app_settings): - # XXX This needs to be configurable - host = 'localhost' - - self.gl = _init_gitlab(host, app_settings['gitlab-private-token']) + url = app_settings['downstream-http-url'] + if url is None: + url = 'http://localhost/' + self.gl = _init_gitlab(url, app_settings['gitlab-private-token']) self._visibility = app_settings['downstream-visibility'] @@ -149,8 +148,11 @@ class GitlabUpstream(hosts.UpstreamHost): def __init__(self, host_info): self._protocol = host_info['protocol'] - self.gl = _init_gitlab(host_info['host'], - host_info['type_params']['private-token']) + if self._protocol == 'ssh': + url = 'https://%(host)s/' % host_info + else: + url = '%(protocol)s://%(host)s/' % host_info + self.gl = _init_gitlab(url, host_info['type_params']['private-token']) def list_repos(self): '''List projects on a GitLab instance.''' 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 |