diff options
Diffstat (limited to 'morphlib/morphloader.py')
-rw-r--r-- | morphlib/morphloader.py | 107 |
1 files changed, 87 insertions, 20 deletions
diff --git a/morphlib/morphloader.py b/morphlib/morphloader.py index 702a330c..e7c1d9ff 100644 --- a/morphlib/morphloader.py +++ b/morphlib/morphloader.py @@ -16,6 +16,7 @@ # =*= License: GPL-2 =*= +import collections import logging import yaml @@ -92,6 +93,53 @@ class EmptyStratumError(morphlib.Error): (stratum_name, morphology)) +class DuplicateChunkError(morphlib.Error): + + def __init__(self, stratum_name, chunk_name): + self.stratum_name = stratum_name + self.chunk_name = chunk_name + morphlib.Error.__init__( + self, 'Duplicate chunk %(chunk_name)s '\ + 'in stratum %(stratum_name)s' % locals()) + + +class SystemStrataNotListError(morphlib.Error): + + def __init__(self, system_name, strata_type): + self.system_name = system_name + self.strata_type = strata_type + typename = strata_type.__name__ + morphlib.Error.__init__( + self, 'System %(system_name)s has the wrong type for its strata: '\ + '%(typename)s, expected list' % locals()) + +class DuplicateStratumError(morphlib.Error): + + def __init__(self, system_name, stratum_name): + self.system_name = system_name + self.stratum_name = stratum_name + morphlib.Error.__init__( + self, 'Duplicate stratum %(stratum_name)s '\ + 'in system %(system_name)s' % locals()) + + +class SystemStratumSpecsNotMappingError(morphlib.Error): + + def __init__(self, system_name, strata): + self.system_name = system_name + self.strata = strata + morphlib.Error.__init__( + self, 'System %(system_name)s has stratum specs '\ + 'that are not mappings.' % locals()) + + +class EmptySystemError(morphlib.Error): + + def __init__(self, system_name): + morphlib.Error.__init__( + self, 'System %(system_name)s has no strata.' % locals()) + + class MorphologyLoader(object): '''Load morphologies from disk, or save them back to disk.''' @@ -106,6 +154,7 @@ class MorphologyLoader(object): 'system': [ 'name', 'arch', + 'strata', ], 'cluster': [ 'name', @@ -146,7 +195,6 @@ class MorphologyLoader(object): 'build-depends': [], }, 'system': { - 'strata': [], 'description': '', 'arch': None, 'configuration-extensions': [], @@ -240,22 +288,32 @@ class MorphologyLoader(object): self._deny_obsolete_fields(obsolete, morph) self._deny_unknown_fields(required + allowed, morph) - if kind == 'system': - self._validate_system(morph) - elif kind == 'stratum': - self._validate_stratum(morph) - elif kind == 'chunk': - self._validate_chunk(morph) - else: - assert kind == 'cluster' + getattr(self, '_validate_%s' % kind)(morph) + + def _validate_cluster(self, morph): + pass def _validate_system(self, morph): + # A system must contain at least one stratum + strata = morph['strata'] + if (not isinstance(strata, collections.Iterable) + or isinstance(strata, collections.Mapping)): + + raise SystemStrataNotListError(morph['name'], + type(strata)) + + if not strata: + raise EmptySystemError(morph['name']) + + if not all(isinstance(o, collections.Mapping) for o in strata): + raise SystemStratumSpecsNotMappingError(morph['name'], strata) + # All stratum names should be unique within a system. names = set() - for spec in morph['strata']: + for spec in strata: name = spec.get('alias', spec['morph']) if name in names: - raise ValueError('Duplicate stratum "%s"' % name) + raise DuplicateStratumError(morph['name'], name) names.add(name) # We allow the ARMv7 little-endian architecture to be specified @@ -277,7 +335,7 @@ class MorphologyLoader(object): for spec in morph['chunks']: name = spec.get('alias', spec['name']) if name in names: - raise ValueError('Duplicate chunk "%s"' % name) + raise DuplicateChunkError(morph['name'], name) names.add(name) # Require build-dependencies for the stratum itself, unless @@ -332,12 +390,7 @@ class MorphologyLoader(object): if key not in morphology: morphology[key] = defaults[key] - if kind == 'system': - self._set_system_defaults(morphology) - elif kind == 'stratum': - self._set_stratum_defaults(morphology) - elif kind == 'chunk': - self._set_chunk_defaults(morphology) + getattr(self, '_set_%s_defaults' % kind)(morphology) def unset_defaults(self, morphology): '''If a field is equal to its default, delete it. @@ -352,8 +405,22 @@ class MorphologyLoader(object): if key in morphology and morphology[key] == defaults[key]: del morphology[key] - if kind == 'stratum': - self._unset_stratum_defaults(morphology) + if kind in ('stratum', 'cluster'): + getattr(self, '_unset_%s_defaults' % kind)(morphology) + + def _set_cluster_defaults(self, morph): + for system in morph.get('systems', []): + if 'deploy-defaults' not in system: + system['deploy-defaults'] = {} + if 'deploy' not in system: + system['deploy'] = {} + + def _unset_cluster_defaults(self, morph): + for system in morph.get('systems', []): + if 'deploy-defaults' in system and system['deploy-defaults'] == {}: + del system['deploy-defaults'] + if 'deploy' in system and system['deploy'] == {}: + del system['deploy'] def _set_system_defaults(self, morph): pass |