From aaa39e09bd5a48a575f0f92e323ec5266ca96edc Mon Sep 17 00:00:00 2001 From: Richard Ipsum Date: Fri, 3 Apr 2015 13:25:12 +0100 Subject: Fix: check that path to chunk morph exists This fixes a bug that allows stratum definitions to carry paths to non-existent chunk morphs. This fix changes the interpretation of definitions so necessarily introduces a new definitions version (version 2) Assuming a morph field defined in a stratum: "morph: strata/cats/xattr.morph" and assuming "strata/cats/xattr.morph" does not exist, this patch will not alter current behaviour for definitions versions 0 and 1, besides producing a warning message like this: "Warning! `strata/cats/xattr.morph' referenced in `strata/swift.morph' does not exist" for definitions version 2 and greater the following error will be raised: "ERROR: Couldn't find morphology: strata/cats/xattr.morph referenced in strata/swift.morph" Change-Id: I4def5e92741cce25168f1038136503022ab27ffd --- morphlib/sourceresolver.py | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/morphlib/sourceresolver.py b/morphlib/sourceresolver.py index 7e0124b4..7be104d2 100644 --- a/morphlib/sourceresolver.py +++ b/morphlib/sourceresolver.py @@ -31,7 +31,7 @@ tree_cache_filename = 'trees.cache.pickle' buildsystem_cache_size = 10000 buildsystem_cache_filename = 'detected-chunk-buildsystems.cache.pickle' -supported_versions = [0, 1] +supported_versions = [0, 1, 2] class PickleCacheManager(object): # pragma: no cover '''Cache manager for PyLRU that reads and writes to Pickle files. @@ -90,6 +90,15 @@ class MorphologyNotFoundError(SourceResolverError): # pragma: no cover SourceResolverError.__init__( self, "Couldn't find morphology: %s" % filename) + +class MorphologyReferenceNotFoundError(SourceResolverError): # pragma: no cover + def __init__(self, filename, reference_file): + SourceResolverError.__init__(self, + "Couldn't find morphology: %s " + "referenced in %s" + % (filename, reference_file)) + + class UnknownVersionError(SourceResolverError): # pragma: no cover def __init__(self, version): SourceResolverError.__init__( @@ -376,8 +385,8 @@ class SourceResolver(object): def _check_version_file(self, definitions_repo, definitions_absref): # pragma: no cover - version_file = self._get_file_contents( - definitions_repo, definitions_absref, 'VERSION') + version_file = self._get_file_contents(definitions_repo, + definitions_absref, 'VERSION') if version_file == None: return 0 # Assume version 0 if no version file @@ -401,7 +410,8 @@ class SourceResolver(object): definitions_queue = collections.deque(system_filenames) chunk_queue = set() - self._check_version_file(definitions_repo, definitions_absref) + definitions_version = self._check_version_file(definitions_repo, + definitions_absref) while definitions_queue: filename = definitions_queue.popleft() @@ -440,9 +450,27 @@ class SourceResolver(object): # code path should be removed. path = morphlib.util.sanitise_morphology_path( c.get('morph', c['name'])) + chunk_queue.add((c['repo'], c['ref'], path)) else: - chunk_queue.add((c['repo'], c['ref'], c['morph'])) + # Now, does this path actually exist? + path = c['morph'] + + morphology = self._get_morphology(definitions_repo, + definitions_absref, + path) + if morphology is None: + if definitions_version > 1: + raise MorphologyReferenceNotFoundError( + path, filename) + else: + self.status( + msg="Warning! `%(path)s' referenced in " + "`%(stratum)s' does not exist", + path=path, + stratum=filename) + + chunk_queue.add((c['repo'], c['ref'], path)) return chunk_queue -- cgit v1.2.1