diff options
Diffstat (limited to 'lorrycontroller/gitano.py')
-rw-r--r-- | lorrycontroller/gitano.py | 104 |
1 files changed, 90 insertions, 14 deletions
diff --git a/lorrycontroller/gitano.py b/lorrycontroller/gitano.py index 7d9c436..499bb5d 100644 --- a/lorrycontroller/gitano.py +++ b/lorrycontroller/gitano.py @@ -23,9 +23,10 @@ import cliapp import requests import lorrycontroller +from . import hosts -class GitanoCommandFailure(Exception): +class _GitanoCommandFailure(Exception): def __init__(self, trovehost, command, stderr): Exception.__init__( @@ -34,7 +35,7 @@ class GitanoCommandFailure(Exception): (command, trovehost, stderr)) -class GitanoCommand(object): +class _GitanoCommand(object): '''Run a Gitano command on a Trove.''' @@ -49,7 +50,7 @@ class GitanoCommand(object): elif protocol in ('http', 'https'): self._command = self._http_command else: - raise GitanoCommandFailure( + raise _GitanoCommandFailure( self.trovehost, '__init__', 'unknown protocol %s' % protocol) def whoami(self): @@ -98,7 +99,7 @@ class GitanoCommand(object): logging.error( 'Failed to run "%s" for %s:\n%s', quoted_args, self.trovehost, stdout + stderr) - raise GitanoCommandFailure( + raise _GitanoCommandFailure( self.trovehost, ' '.join(gitano_args), stdout + stderr) @@ -122,13 +123,13 @@ class GitanoCommand(object): else: response = requests.get(url) except (requests.exceptions.RequestException) as e: - raise GitanoCommandFailure( + raise _GitanoCommandFailure( self.trovehost, ' '.join(gitano_args), str(e)) return response.text -class LocalTroveGitanoCommand(GitanoCommand): +class _LocalTroveGitanoCommand(_GitanoCommand): '''Run commands on the local Trove's Gitano. @@ -138,14 +139,89 @@ class LocalTroveGitanoCommand(GitanoCommand): ''' def __init__(self): - GitanoCommand.__init__(self, 'localhost', 'ssh', '', '') + _GitanoCommand.__init__(self, 'localhost', 'ssh', '', '') -def new_gitano_command(statedb, trovehost): - trove_info = statedb.get_trove_info(trovehost) - return lorrycontroller.GitanoCommand( - trovehost, - trove_info['protocol'], - trove_info['username'], - trove_info['password']) +class GitanoDownstream(hosts.DownstreamHost): + def __init__(self, app_settings): + self._gitano = _LocalTroveGitanoCommand() + + def prepare_repo(self, repo_path, metadata): + # Create repository on local Trove. If it fails, assume + # it failed because the repository already existed, and + # ignore the failure (but log message). + + try: + self._gitano.create(repo_path) + except _GitanoCommandFailure as e: + logging.debug( + 'Ignoring error creating %s on local Trove: %s', + repo_path, e) + else: + logging.info('Created %s on local repo', repo_path) + + try: + local_config = self._gitano.get_gitano_config(repo_path) + if 'head' in metadata \ + and metadata['head'] != local_config['project.head']: + self._gitano.set_gitano_config(repo_path, + 'project.head', + metadata['head']) + if 'description' in metadata \ + and metadata['description'] != \ + local_config['project.description']: + self._gitano.set_gitano_config(repo_path, + 'project.description', + metadata['description']) + except _GitanoCommandFailure as e: + logging.error('ERROR: %s' % str(e)) + # FIXME: We need a good way to report these errors to the + # user. However, we probably don't want to fail the + # request, so that's not the way to do this. Needs + # thinking. + + +class TroveUpstream(hosts.UpstreamHost): + def __init__(self, host_info): + self._host_info = host_info + self._gitano = _GitanoCommand(host_info['host'], + host_info['protocol'], + host_info['username'], + host_info['password']) + + def list_repos(self): + ls_output = self._gitano.ls() + repo_paths = [] + for line in ls_output.splitlines(): + words = line.split(None, 1) + if words[0].startswith('R') and len(words) == 2: + repo_paths.append(words[1]) + return repo_paths + + def get_repo_url(self, remote_path): + vars = dict(self._host_info) + vars['remote_path'] = remote_path + + patterns = { + 'ssh': 'ssh://git@{host}/{remote_path}', + 'https':'https://{username}:{password}@{host}/git/{remote_path}', + 'http': 'http://{host}/git/{remote_path}', + } + + return patterns[self._host_info['protocol']].format(**vars) + + def get_repo_metadata(self, repo_path): + try: + remote_config = self._gitano.get_gitano_config(repo_path) + return { + 'head': remote_config['project.head'], + 'description': remote_config['project.description'], + } + except _GitanoCommandFailure as e: + logging.error('ERROR: %s' % str(e)) + # FIXME: We need a good way to report these errors to the + # user. However, we probably don't want to fail the + # request, so that's not the way to do this. Needs + # thinking. + return {} |