summaryrefslogtreecommitdiff
path: root/morphlib/morphloader.py
diff options
context:
space:
mode:
Diffstat (limited to 'morphlib/morphloader.py')
-rw-r--r--morphlib/morphloader.py107
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