summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2016-03-02 17:11:34 +0000
committerSam Thursfield <sam.thursfield@codethink.co.uk>2016-03-14 17:38:16 +0000
commitee67d83a587b3fab1a16ce89e32ac7bfaa834b50 (patch)
tree2b34edcbeba07977e8607d4e5d8d7aa3b9baa437
parent014a029ade9a045a839ca86c35690b218098ea33 (diff)
downloadmorph-ee67d83a587b3fab1a16ce89e32ac7bfaa834b50.tar.gz
WIP: Unify local and remote repo cache classes
One reason that the sourceresolver class is so hopelessly complicated is that it has to use two incompatible interfaces for Git repo caches. Let's move this complexity to a single repocache class. Change-Id: If11954a9a5e0c566d88e49e98dfb5a4b9c948232
-rw-r--r--morphlib/buildcommand.py13
-rw-r--r--morphlib/git.py9
-rw-r--r--morphlib/remoterepocache.py105
-rw-r--r--morphlib/remoterepocache_tests.py137
-rw-r--r--morphlib/repocache.py (renamed from morphlib/localrepocache.py)168
-rw-r--r--morphlib/repocache_tests.py (renamed from morphlib/localrepocache_tests.py)0
-rw-r--r--morphlib/util.py54
7 files changed, 168 insertions, 318 deletions
diff --git a/morphlib/buildcommand.py b/morphlib/buildcommand.py
index a2ad3301..0bd6c6cb 100644
--- a/morphlib/buildcommand.py
+++ b/morphlib/buildcommand.py
@@ -47,7 +47,7 @@ class BuildCommand(object):
def __init__(self, app, build_env = None):
self.app = app
self.lac, self.rac = self.new_artifact_caches()
- self.lrc, self.rrc = self.new_repo_caches()
+ self.repo_cache = morphlib.util.repo_cache(self.app)
def build(self, repo_name, ref, filename, original_ref=None):
'''Build a given system morphology.'''
@@ -76,9 +76,6 @@ class BuildCommand(object):
'''
return morphlib.util.new_artifact_caches(self.app.settings)
- def new_repo_caches(self):
- return morphlib.util.new_repo_caches(self.app)
-
def new_build_env(self, arch):
'''Create a new BuildEnvironment instance.'''
return morphlib.buildenvironment.BuildEnvironment(self.app.settings,
@@ -95,7 +92,7 @@ class BuildCommand(object):
'''
self.app.status(msg='Creating source pool', chatty=True)
srcpool = morphlib.sourceresolver.create_source_pool(
- self.lrc, self.rrc, repo_name, ref, filenames,
+ self.repo_cache, repo_name, ref, filenames,
cachedir=self.app.settings['cachedir'],
original_ref=original_ref,
update_repos=not self.app.settings['no-git-update'],
@@ -394,8 +391,8 @@ class BuildCommand(object):
'''Update the local git repository cache with the sources.'''
repo_name = source.repo_name
- source.repo = self.lrc.get_updated_repo(repo_name, ref=source.sha1)
- self.lrc.ensure_submodules(source.repo, source.sha1)
+ source.repo = self.repo_cache.get_updated_repo(repo_name, ref=source.sha1)
+ self.repo_cache.ensure_submodules(source.repo, source.sha1)
def cache_artifacts_locally(self, artifacts):
'''Get artifacts missing from local cache from remote cache.'''
@@ -540,7 +537,7 @@ class BuildCommand(object):
'%(sha1)s',
name=source.name, sha1=source.sha1[:7])
builder = morphlib.builder.Builder(
- self.app, staging_area, self.lac, self.rac, self.lrc,
+ self.app, staging_area, self.lac, self.rac, self.repo_cache,
self.app.settings['max-jobs'], setup_mounts)
return builder.build_and_cache(source)
diff --git a/morphlib/git.py b/morphlib/git.py
index 190544ac..cab551ef 100644
--- a/morphlib/git.py
+++ b/morphlib/git.py
@@ -58,12 +58,13 @@ class MissingSubmoduleCommitError(cliapp.AppException):
class Submodules(object):
- def __init__(self, app, repo, ref):
- self.app = app
+ def __init__(self, repo, ref, runcmd_cb=cliapp.runcmd):
self.repo = repo
self.ref = ref
self.submodules = []
+ self.runcmd_cb = runcmd_cb
+
def load(self):
content = self._read_gitmodules_file()
@@ -76,7 +77,7 @@ class Submodules(object):
def _read_gitmodules_file(self):
try:
# try to read the .gitmodules file from the repo/ref
- content = gitcmd(self.app.runcmd, 'cat-file', 'blob',
+ content = gitcmd(self.runcmd_cb, 'cat-file', 'blob',
'%s:.gitmodules' % self.ref, cwd=self.repo,
ignore_fail=True)
@@ -100,7 +101,7 @@ class Submodules(object):
try:
# list objects in the parent repo tree to find the commit
# object that corresponds to the submodule
- commit = gitcmd(self.app.runcmd, 'ls-tree', self.ref,
+ commit = gitcmd(self.runcmd_cb, 'ls-tree', self.ref,
submodule.path, cwd=self.repo)
# read the commit hash from the output
diff --git a/morphlib/remoterepocache.py b/morphlib/remoterepocache.py
deleted file mode 100644
index 4a6d9fe9..00000000
--- a/morphlib/remoterepocache.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# Copyright (C) 2012-2015 Codethink Limited
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-import cliapp
-import json
-import logging
-import urllib2
-import urlparse
-import urllib
-
-
-class ResolveRefError(cliapp.AppException):
-
- def __init__(self, repo_name, ref):
- cliapp.AppException.__init__(
- self, 'Failed to resolve ref %s for repo %s' %
- (ref, repo_name))
-
-
-class CatFileError(cliapp.AppException):
-
- def __init__(self, repo_name, ref, filename):
- cliapp.AppException.__init__(
- self, 'Failed to cat file %s in ref %s of repo %s' %
- (filename, ref, repo_name))
-
-class LsTreeError(cliapp.AppException):
-
- def __init__(self, repo_name, ref):
- cliapp.AppException.__init__(
- self, 'Failed to list tree in ref %s of repo %s' %
- (ref, repo_name))
-
-
-class RemoteRepoCache(object):
-
- def __init__(self, server_url, resolver):
- self.server_url = server_url
- self._resolver = resolver
-
- def resolve_ref(self, repo_name, ref):
- repo_url = self._resolver.pull_url(repo_name)
- try:
- return self._resolve_ref_for_repo_url(repo_url, ref)
- except BaseException as e:
- logging.error('Caught exception: %s' % str(e))
- raise ResolveRefError(repo_name, ref)
-
- def cat_file(self, repo_name, ref, filename):
- repo_url = self._resolver.pull_url(repo_name)
- try:
- return self._cat_file_for_repo_url(repo_url, ref, filename)
- except urllib2.HTTPError as e:
- logging.error('Caught exception: %s' % str(e))
- if e.code == 404:
- raise CatFileError(repo_name, ref, filename)
- raise # pragma: no cover
-
- def ls_tree(self, repo_name, ref):
- repo_url = self._resolver.pull_url(repo_name)
- try:
- info = json.loads(self._ls_tree_for_repo_url(repo_url, ref))
- return info['tree'].keys()
- except BaseException as e:
- logging.error('Caught exception: %s' % str(e))
- raise LsTreeError(repo_name, ref)
-
- def _resolve_ref_for_repo_url(self, repo_url, ref): # pragma: no cover
- data = self._make_request(
- 'sha1s?repo=%s&ref=%s' % self._quote_strings(repo_url, ref))
- info = json.loads(data)
- return info['sha1'], info['tree']
-
- def _cat_file_for_repo_url(self, repo_url, ref,
- filename): # pragma: no cover
- return self._make_request(
- 'files?repo=%s&ref=%s&filename=%s'
- % self._quote_strings(repo_url, ref, filename))
-
- def _ls_tree_for_repo_url(self, repo_url, ref): # pragma: no cover
- return self._make_request(
- 'trees?repo=%s&ref=%s' % self._quote_strings(repo_url, ref))
-
- def _quote_strings(self, *args): # pragma: no cover
- return tuple(urllib.quote(string) for string in args)
-
- def _make_request(self, path): # pragma: no cover
- server_url = self.server_url
- if not server_url.endswith('/'):
- server_url += '/'
- url = urlparse.urljoin(server_url, '/1.0/%s' % path)
- handle = urllib2.urlopen(url)
- return handle.read()
diff --git a/morphlib/remoterepocache_tests.py b/morphlib/remoterepocache_tests.py
deleted file mode 100644
index 966e74d5..00000000
--- a/morphlib/remoterepocache_tests.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# Copyright (C) 2012-2015 Codethink Limited
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-import json
-import unittest
-import urllib2
-
-import morphlib
-
-
-class RemoteRepoCacheTests(unittest.TestCase):
-
- def _resolve_ref_for_repo_url(self, repo_url, ref):
- return self.sha1s[repo_url][ref]
-
- def _cat_file_for_repo_url(self, repo_url, sha1, filename):
- try:
- return self.files[repo_url][sha1][filename]
- except KeyError:
- raise urllib2.HTTPError(url='', code=404, msg='Not found',
- hdrs={}, fp=None)
-
- def _ls_tree_for_repo_url(self, repo_url, sha1):
- return json.dumps({
- 'repo': repo_url,
- 'ref': sha1,
- 'tree': self.files[repo_url][sha1]
- })
-
- def setUp(self):
- self.sha1s = {
- 'git://gitorious.org/baserock/morph': {
- 'master': 'e28a23812eadf2fce6583b8819b9c5dbd36b9fb9'
- }
- }
- self.files = {
- 'git://gitorious.org/baserock-morphs/linux': {
- 'e28a23812eadf2fce6583b8819b9c5dbd36b9fb9': {
- 'linux.morph': 'linux morphology'
- }
- }
- }
- self.server_url = 'http://foo.bar'
- aliases = [
- 'upstream=git://gitorious.org/baserock-morphs/#foo',
- 'baserock=git://gitorious.org/baserock/#foo'
- ]
- resolver = morphlib.repoaliasresolver.RepoAliasResolver(aliases)
- self.cache = morphlib.remoterepocache.RemoteRepoCache(
- self.server_url, resolver)
- self.cache._resolve_ref_for_repo_url = self._resolve_ref_for_repo_url
- self.cache._cat_file_for_repo_url = self._cat_file_for_repo_url
- self.cache._ls_tree_for_repo_url = self._ls_tree_for_repo_url
-
- def test_sets_server_url(self):
- self.assertEqual(self.cache.server_url, self.server_url)
-
- def test_resolve_existing_ref_for_existing_repo(self):
- sha1 = self.cache.resolve_ref('baserock:morph', 'master')
- self.assertEqual(
- sha1,
- self.sha1s['git://gitorious.org/baserock/morph']['master'])
-
- def test_fail_resolving_existing_ref_for_non_existent_repo(self):
- self.assertRaises(morphlib.remoterepocache.ResolveRefError,
- self.cache.resolve_ref, 'non-existent-repo',
- 'master')
-
- def test_fail_resolving_non_existent_ref_for_existing_repo(self):
- self.assertRaises(morphlib.remoterepocache.ResolveRefError,
- self.cache.resolve_ref, 'baserock:morph',
- 'non-existent-ref')
-
- def test_fail_resolving_non_existent_ref_for_non_existent_repo(self):
- self.assertRaises(morphlib.remoterepocache.ResolveRefError,
- self.cache.resolve_ref, 'non-existent-repo',
- 'non-existent-ref')
-
- def test_cat_existing_file_in_existing_repo_and_ref(self):
- content = self.cache.cat_file(
- 'upstream:linux', 'e28a23812eadf2fce6583b8819b9c5dbd36b9fb9',
- 'linux.morph')
- self.assertEqual(content, 'linux morphology')
-
- def test_fail_cat_file_using_invalid_sha1(self):
- self.assertRaises(morphlib.remoterepocache.CatFileError,
- self.cache.cat_file, 'upstream:linux', 'blablabla',
- 'linux.morph')
-
- def test_fail_cat_non_existent_file_in_existing_repo_and_ref(self):
- self.assertRaises(morphlib.remoterepocache.CatFileError,
- self.cache.cat_file, 'upstream:linux',
- 'e28a23812eadf2fce6583b8819b9c5dbd36b9fb9',
- 'non-existent-file')
-
- def test_fail_cat_file_in_non_existent_ref_in_existing_repo(self):
- self.assertRaises(morphlib.remoterepocache.CatFileError,
- self.cache.cat_file, 'upstream:linux',
- 'ecd7a325095a0d19b8c3d76f578d85b979461d41',
- 'linux.morph')
-
- def test_fail_cat_file_in_non_existent_repo(self):
- self.assertRaises(morphlib.remoterepocache.CatFileError,
- self.cache.cat_file, 'non-existent-repo',
- 'e28a23812eadf2fce6583b8819b9c5dbd36b9fb9',
- 'some-file')
-
- def test_ls_tree_in_existing_repo_and_ref(self):
- content = self.cache.ls_tree(
- 'upstream:linux', 'e28a23812eadf2fce6583b8819b9c5dbd36b9fb9')
- self.assertEqual(content, ['linux.morph'])
-
- def test_fail_ls_tree_using_invalid_sha1(self):
- self.assertRaises(morphlib.remoterepocache.LsTreeError,
- self.cache.ls_tree, 'upstream:linux', 'blablabla')
-
- def test_fail_ls_file_in_non_existent_ref_in_existing_repo(self):
- self.assertRaises(morphlib.remoterepocache.LsTreeError,
- self.cache.ls_tree, 'upstream:linux',
- 'ecd7a325095a0d19b8c3d76f578d85b979461d41')
-
- def test_fail_ls_tree_in_non_existent_repo(self):
- self.assertRaises(morphlib.remoterepocache.LsTreeError,
- self.cache.ls_tree, 'non-existent-repo',
- 'e28a23812eadf2fce6583b8819b9c5dbd36b9fb9')
diff --git a/morphlib/localrepocache.py b/morphlib/repocache.py
index 3a03fe1d..fc07011f 100644
--- a/morphlib/localrepocache.py
+++ b/morphlib/repocache.py
@@ -13,14 +13,18 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
+import cliapp
+import fs.osfs
+
+import json
+import logging
import os
-import urlparse
import string
import sys
import tempfile
-
-import cliapp
-import fs.osfs
+import urllib2
+import urlparse
+import urllib
import morphlib
from morphlib.util import word_join_list as _word_join_list
@@ -98,9 +102,8 @@ class CachedRepo(morphlib.gitdir.GitDirectory):
return self.url
-class LocalRepoCache(object):
-
- '''Manage locally cached git repositories.
+class RepoCache(object):
+ '''Manage a collection of Git repositories.
When we build stuff, we need a local copy of the git repository.
To avoid having to clone the repositories for every build, we
@@ -118,10 +121,21 @@ class LocalRepoCache(object):
git server, we first try to download a tarball from a url, and
if that works, we unpack the tarball.
+ Certain questions about a repo can be resolved without cloning the whole
+ thing, if an instance of 'morph-cache-server' is available on the remote
+ Git server. This makes calculating the build graph for the first time
+ a whole lot faster, as we avoid cloning every repo locally. The
+ git_resolve_cache_url parameter enables this feature. Baserock 'Trove'
+ systems run 'morph-cache-server' by default.
+
'''
+ def __init__(self, cachedir, resolver, tarball_base_url=None,
+ git_resolve_cache_url=None,
+ update_gits=True,
+ runcmd_cb=cliapp.runcmd, status_cb=lambda **kwargs: None,
+ verbose=False, debug=False):
+ morphlib.utils.ensure_directory_exists(cachedir)
- def __init__(self, app, cachedir, resolver, tarball_base_url=None):
- self._app = app
self.fs = fs.osfs.OSFS('/')
self._cachedir = cachedir
self._resolver = resolver
@@ -129,6 +143,15 @@ class LocalRepoCache(object):
tarball_base_url += '/' # pragma: no cover
self._tarball_base_url = tarball_base_url
self._cached_repo_objects = {}
+ self.git_resolve_cache_url = git_resolve_cache_url
+
+ # Corresponds to the app 'no-git-update' setting
+ self.update_gits = update_gits
+
+ self.runcmd_cb = runcmd_cb
+ self.status_cb = status_cb
+ self.verbose = verbose
+ self.debug = debug
def _git(self, args, **kwargs): # pragma: no cover
'''Execute git command.
@@ -138,7 +161,7 @@ class LocalRepoCache(object):
'''
- morphlib.git.gitcmd(self._app.runcmd, *args, **kwargs)
+ morphlib.git.gitcmd(self.runcmd_cb, *args, **kwargs)
def _fetch(self, url, path): # pragma: no cover
'''Fetch contents of url into a file.
@@ -146,10 +169,10 @@ class LocalRepoCache(object):
This method is meant to be overridden by unit tests.
'''
- self._app.status(msg="Trying to fetch %(tarball)s to seed the cache",
- tarball=url, chatty=True)
+ self.status_cb(msg="Trying to fetch %(tarball)s to seed the cache",
+ tarball=url, chatty=True)
- if self._app.settings['verbose']:
+ if self.verbose:
verbosity_flags = []
kwargs = dict(stderr=sys.stderr)
else:
@@ -159,9 +182,9 @@ class LocalRepoCache(object):
def wget_command():
return ['wget'] + verbosity_flags + ['-O-', url]
- self._app.runcmd(wget_command(),
- ['tar', '--no-same-owner', '-xf', '-'],
- cwd=path, **kwargs)
+ self.runcmd_cb(wget_command(),
+ ['tar', '--no-same-owner', '-xf', '-'],
+ cwd=path, **kwargs)
def _mkdtemp(self, dirname): # pragma: no cover
'''Creates a temporary directory.
@@ -236,14 +259,13 @@ class LocalRepoCache(object):
return repo
else:
errors.append(error)
- self._app.status(
- msg='Using git clone.')
+ self.status_cb(msg='Using git clone.')
target = self._mkdtemp(self._cachedir)
try:
self._git(['clone', '--mirror', '-n', repourl, target],
- echo_stderr=self._app.settings['debug'])
+ echo_stderr=self.debug)
except cliapp.AppException as e:
errors.append('Unable to clone from %s to %s: %s' %
(repourl, target, e))
@@ -289,12 +311,12 @@ class LocalRepoCache(object):
'''
- if self._app.settings['no-git-update']:
- self._app.status(msg='Not updating existing git repository '
- '%(repo_name)s '
- 'because of no-git-update being set',
- chatty=True,
- repo_name=repo_name)
+ if not self.update_gits:
+ self.status_cb(msg='Not updating existing git repository '
+ '%(repo_name)s '
+ 'because of no-git-update being set',
+ chatty=True,
+ repo_name=repo_name)
return self._get_repo(repo_name)
if ref is not None and refs is None:
@@ -315,20 +337,18 @@ class LocalRepoCache(object):
missing_refs.add(required_ref)
if not missing_refs:
- self._app.status(
+ self.status_cb(
msg='Not updating git repository %(repo_name)s '
'because it already contains %(sha1s)s',
chatty=True, repo_name=repo_name,
sha1s=_word_join_list(tuple(required_refs)))
return repo
- self._app.status(msg='Updating %(repo_name)s',
- repo_name=repo_name)
+ self.status_cb(msg='Updating %(repo_name)s', repo_name=repo_name)
self._update_repo(repo)
return repo
else:
- self._app.status(msg='Cloning %(repo_name)s',
- repo_name=repo_name)
+ self.status_cb(msg='Cloning %(repo_name)s', repo_name=repo_name)
return self._cache_repo(repo_name)
def ensure_submodules(self, toplevel_repo,
@@ -337,7 +357,8 @@ class LocalRepoCache(object):
def submodules_for_repo(repo_path, ref):
try:
- submodules = morphlib.git.Submodules(self._app, repo_path, ref)
+ submodules = morphlib.git.Submodules(repo_path, ref,
+ runcmd_cb=self.runcmd_cb)
submodules.load()
return [(submod.url, submod.commit) for submod in submodules]
except morphlib.git.NoModulesFileError:
@@ -355,3 +376,88 @@ class LocalRepoCache(object):
for submod in submodules_for_repo(cached_repo.dirname, ref):
if submod not in done:
subs_to_process.append(submod)
+
+
+class ResolveRefError(cliapp.AppException):
+
+ def __init__(self, repo_name, ref):
+ cliapp.AppException.__init__(
+ self, 'Failed to resolve ref %s for repo %s' %
+ (ref, repo_name))
+
+
+class CatFileError(cliapp.AppException):
+
+ def __init__(self, repo_name, ref, filename):
+ cliapp.AppException.__init__(
+ self, 'Failed to cat file %s in ref %s of repo %s' %
+ (filename, ref, repo_name))
+
+
+class LsTreeError(cliapp.AppException):
+
+ def __init__(self, repo_name, ref):
+ cliapp.AppException.__init__(
+ self, 'Failed to list tree in ref %s of repo %s' %
+ (ref, repo_name))
+
+
+class RemoteRepoCache(object):
+
+ def __init__(self, server_url, resolver):
+ self.server_url = server_url
+ self._resolver = resolver
+
+ def resolve_ref(self, repo_name, ref):
+ repo_url = self._resolver.pull_url(repo_name)
+ try:
+ return self._resolve_ref_for_repo_url(repo_url, ref)
+ except BaseException as e:
+ logging.error('Caught exception: %s' % str(e))
+ raise ResolveRefError(repo_name, ref)
+
+ def cat_file(self, repo_name, ref, filename):
+ repo_url = self._resolver.pull_url(repo_name)
+ try:
+ return self._cat_file_for_repo_url(repo_url, ref, filename)
+ except urllib2.HTTPError as e:
+ logging.error('Caught exception: %s' % str(e))
+ if e.code == 404:
+ raise CatFileError(repo_name, ref, filename)
+ raise # pragma: no cover
+
+ def ls_tree(self, repo_name, ref):
+ repo_url = self._resolver.pull_url(repo_name)
+ try:
+ info = json.loads(self._ls_tree_for_repo_url(repo_url, ref))
+ return info['tree'].keys()
+ except BaseException as e:
+ logging.error('Caught exception: %s' % str(e))
+ raise LsTreeError(repo_name, ref)
+
+ def _resolve_ref_for_repo_url(self, repo_url, ref): # pragma: no cover
+ data = self._make_request(
+ 'sha1s?repo=%s&ref=%s' % self._quote_strings(repo_url, ref))
+ info = json.loads(data)
+ return info['sha1'], info['tree']
+
+ def _cat_file_for_repo_url(self, repo_url, ref,
+ filename): # pragma: no cover
+ return self._make_request(
+ 'files?repo=%s&ref=%s&filename=%s'
+ % self._quote_strings(repo_url, ref, filename))
+
+ def _ls_tree_for_repo_url(self, repo_url, ref): # pragma: no cover
+ return self._make_request(
+ 'trees?repo=%s&ref=%s' % self._quote_strings(repo_url, ref))
+
+ def _quote_strings(self, *args): # pragma: no cover
+ return tuple(urllib.quote(string) for string in args)
+
+ def _make_request(self, path): # pragma: no cover
+ server_url = self.server_url
+ if not server_url.endswith('/'):
+ server_url += '/'
+ url = urlparse.urljoin(server_url, '/1.0/%s' % path)
+ handle = urllib2.urlopen(url)
+ return handle.read()
diff --git a/morphlib/localrepocache_tests.py b/morphlib/repocache_tests.py
index 91fdb216..91fdb216 100644
--- a/morphlib/localrepocache_tests.py
+++ b/morphlib/repocache_tests.py
diff --git a/morphlib/util.py b/morphlib/util.py
index 3b3e4d2b..eaea0c66 100644
--- a/morphlib/util.py
+++ b/morphlib/util.py
@@ -102,21 +102,16 @@ def make_concurrency(cores=None):
return min(n, 20)
-def create_cachedir(settings): # pragma: no cover
- '''Return cache directory, creating it if necessary.'''
-
- cachedir = settings['cachedir']
+def ensure_directory_exists(path): # pragma: no cover
# Don't check the folder exists and handle the exception that happens in
# this case to avoid errors if the folder is created by something else
# just after the check.
try:
- os.mkdir(cachedir)
+ os.makedirs(path)
except OSError as e:
if e.errno != errno.EEXIST:
raise
- return cachedir
-
def get_artifact_cache_server(settings): # pragma: no cover
if settings['artifact-cache-server']:
@@ -141,17 +136,8 @@ def new_artifact_caches(settings): # pragma: no cover
'''
- cachedir = create_cachedir(settings)
- artifact_cachedir = os.path.join(cachedir, 'artifacts')
- # Don't check the folder exists and handle the exception that happens in
- # this case to avoid errors if the folder is created by something else
- # just after the check.
- try:
- os.mkdir(artifact_cachedir)
- except OSError as e:
- if e.errno != errno.EEXIST:
- raise
-
+ artifact_cachedir = os.path.join(settings['cachedir'], 'artifacts')
+ ensure_directory_exists(artifact_cachedir)
lac = morphlib.localartifactcache.LocalArtifactCache(
fs.osfs.OSFS(artifact_cachedir))
@@ -222,24 +208,26 @@ def combine_aliases(app): # pragma: no cover
return alias_map.values()
-def new_repo_caches(app): # pragma: no cover
- '''Create new objects for local, remote git repository caches.'''
- aliases = app.settings['repo-alias']
- cachedir = create_cachedir(app.settings)
- gits_dir = os.path.join(cachedir, 'gits')
- tarball_base_url = app.settings['tarball-server']
- repo_resolver = morphlib.repoaliasresolver.RepoAliasResolver(aliases)
- lrc = morphlib.localrepocache.LocalRepoCache(
- app, gits_dir, repo_resolver, tarball_base_url=tarball_base_url)
+def repo_cache(app): # pragma: no cover
+ '''Create a RepoCache instance using settings from app.settings.'''
- url = get_git_resolve_cache_server(app.settings)
- if url:
- rrc = morphlib.remoterepocache.RemoteRepoCache(url, repo_resolver)
- else:
- rrc = None
+ gits_dir = os.path.join(settings['cachedir'], 'gits')
+ tarball_base_url = app.settings['tarball-server']
+ git_resolve_cache_url = get_git_resolve_cache_server(app.settings)
+ aliases = app.settings['repo-alias']
+ repo_alias_resolver = morphlib.repoaliasresolver.RepoAliasResolver(aliases)
+
+ return morphlib.repocache.RepoCache(
+ gits_dir, repo_alias_resolver,
+ tarball_base_url=tarball_base_url,
+ git_resolve_cache_url=git_resolve_cache_url,
+ update_gits=(not app.settings['no-git-update']),
+ runcmd_cb=app.runcmd,
+ status_cb=app.status,
+ verbose=app.settings['verbose'],
+ debug=app.settings['debug'])
- return lrc, rrc
def env_variable_is_password(key): # pragma: no cover
return 'PASSWORD' in key