summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2013-11-28 12:49:41 +0000
committerRichard Maw <richard.maw@codethink.co.uk>2013-11-29 16:11:31 +0000
commit03e724f1fb690e9ef95b082e4f1ad96799ec18c1 (patch)
treedebabe9d6cc1f6d23c497ece8c5f72f363a32500
parentf5c1a50c9f35450801846a0309aa571e9893946a (diff)
downloadmorph-03e724f1fb690e9ef95b082e4f1ad96799ec18c1.tar.gz
validation: Require there be non-bootstrap chunks in systems
Bootstrap chunks don't make it into the final system, so there needs to be an extra check for empty systems after the sources have been collected. This was complicated slightly by the fact that if you try to build a chunk directly you will have no strata in your sources, hence no non-bootstrap chunks, but validation for having been told to build a chunk is best handled later. This amends the old yarns that depended on building a bootstrap chunk and adds a new one that explicitly builds a system with bootstrap chunks.
-rw-r--r--morphlib/buildcommand.py46
-rw-r--r--yarns/implementations.yarn2
-rw-r--r--yarns/regression.yarn46
3 files changed, 86 insertions, 8 deletions
diff --git a/morphlib/buildcommand.py b/morphlib/buildcommand.py
index 8ad893a9..4b3b2108 100644
--- a/morphlib/buildcommand.py
+++ b/morphlib/buildcommand.py
@@ -49,8 +49,8 @@ class BuildCommand(object):
repo_name=repo_name, ref=ref, filename=filename)
self.app.status(msg='Deciding on task order')
srcpool = self.create_source_pool(repo_name, ref, filename)
+ self.validate_sources(srcpool)
root_artifact = self.resolve_artifacts(srcpool)
- self._validate_architecture(root_artifact)
self.build_in_order(root_artifact)
self.app.status(msg='Build ends successfully')
@@ -83,11 +83,27 @@ class BuildCommand(object):
srcpool = self.app.create_source_pool(
self.lrc, self.rrc, (repo_name, ref, filename))
+ return srcpool
+
+ def validate_sources(self, srcpool):
self.app.status(
msg='Validating cross-morphology references', chatty=True)
self._validate_cross_morphology_references(srcpool)
- return srcpool
+ self.app.status(msg='Validating for there being non-bootstrap chunks',
+ chatty=True)
+ self._validate_has_non_bootstrap_chunks(srcpool)
+
+ def _validate_root_artifact(self, root_artifact):
+ self._validate_root_kind(root_artifact)
+ self._validate_architecture(root_artifact)
+
+ @staticmethod
+ def _validate_root_kind(root_artifact):
+ root_kind = root_artifact.source.morphology['kind']
+ if root_kind != 'system':
+ raise morphlib.Error(
+ 'Building a %s directly is not supported' % root_kind)
def _validate_architecture(self, root_artifact):
'''Perform the validation between root and target architectures.'''
@@ -100,6 +116,22 @@ class BuildCommand(object):
'Host architecture is %s but target is %s'
% (host_arch, root_arch))
+ @staticmethod
+ def _validate_has_non_bootstrap_chunks(srcpool):
+ stratum_sources = [src for src in srcpool
+ if src.morphology['kind'] == 'stratum']
+ # any will return true for an empty iterable, which will give
+ # a false positive when there are no strata.
+ # This is an error by itself, but the source of this error can
+ # be better diagnosed later, so we abort validating here.
+ if not stratum_sources:
+ return
+
+ if not any(spec.get('build-mode', 'staging') != 'bootstrap'
+ for src in stratum_sources
+ for spec in src.morphology['chunks']):
+ raise morphlib.Error('No non-bootstrap chunks found.')
+
def resolve_artifacts(self, srcpool):
'''Resolve the artifacts that will be built for a set of sources'''
@@ -112,10 +144,12 @@ class BuildCommand(object):
self.app.status(msg='Computing build order', chatty=True)
root_artifact = self._find_root_artifact(artifacts)
- root_kind = root_artifact.source.morphology['kind']
- if root_kind != 'system':
- raise morphlib.Error(
- 'Building a %s directly is not supported' % root_kind)
+ # Validate the root artifact here, since it's a costly function
+ # to finalise it, so any pre finalisation validation is better
+ # done before that happens, but we also don't want to expose
+ # the root artifact until it's finalised.
+ self.app.status(msg='Validating root artifact', chatty=True)
+ self._validate_root_artifact(root_artifact)
arch = root_artifact.source.morphology['arch']
self.app.status(msg='Creating build environment for %(arch)s',
diff --git a/yarns/implementations.yarn b/yarns/implementations.yarn
index 98955f48..65ac1283 100644
--- a/yarns/implementations.yarn
+++ b/yarns/implementations.yarn
@@ -83,7 +83,7 @@ another to hold a chunk.
repo: test:test-chunk
ref: master
morph: test-chunk
- build-mode: bootstrap
+ build-mode: test
build-depends: []
EOF
diff --git a/yarns/regression.yarn b/yarns/regression.yarn
index 582ebb08..eae01343 100644
--- a/yarns/regression.yarn
+++ b/yarns/regression.yarn
@@ -27,8 +27,52 @@ The branch is checked out correctly, now it should fail if the user executes
WHEN the user attempts to create a system branch called foo
THEN morph failed
- AND the branch error message includes the string "File exists"
+ AND the branch error message includes the string "File exists"
The branch still checked out.
AND the system branch foo is checked out
+
+
+It doesn't make much sense to be able to build a system with only
+bootstrap chunks, since they will have been constructed without a staging
+area, hence their results cannot be trusted.
+
+ SCENARIO building a system with only bootstrap chunks fails
+ GIVEN a workspace
+ AND a git server
+ AND a system containing only bootstrap chunks called bootstrap-system
+ WHEN the user checks out the system branch called master
+ AND the user attempts to build the system bootstrap-system in branch master
+ THEN the build error message includes the string "No non-bootstrap chunks found"
+
+
+Implementations
+---------------
+
+ IMPLEMENTS GIVEN a system containing only bootstrap chunks called (\S+)
+ arch=$(run_morph print-architecture)
+ cat <<EOF >"$DATADIR/gits/morphs/$MATCH_1.morph"
+ name: $MATCH_1
+ kind: system
+ arch: $arch
+ strata:
+ - morph: bootstrap-stratum
+ repo: test:morphs
+ ref: master
+ EOF
+
+ cat << EOF > "$DATADIR/gits/morphs/bootstrap-stratum.morph"
+ name: bootstrap-stratum
+ kind: stratum
+ chunks:
+ - name: bootstrap-chunk
+ repo: test:test-chunk
+ ref: master
+ morph: test-chunk
+ build-mode: bootstrap
+ build-depends: []
+ EOF
+
+ run_in "$DATADIR/gits/morphs" git add .
+ run_in "$DATADIR/gits/morphs" git commit -m "Add bootstrap-system"