summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--morphlib/builder2.py86
1 files changed, 53 insertions, 33 deletions
diff --git a/morphlib/builder2.py b/morphlib/builder2.py
index caf0d8e1..56834902 100644
--- a/morphlib/builder2.py
+++ b/morphlib/builder2.py
@@ -23,6 +23,7 @@ from collections import defaultdict
import tarfile
import morphlib
+from morphlib.artifactcachereference import ArtifactCacheReference
def ldconfig(runcmd, rootdir): # pragma: no cover
@@ -60,17 +61,40 @@ def ldconfig(runcmd, rootdir): # pragma: no cover
else:
logging.debug('No %s, not running ldconfig' % conf)
+def download_depends(constituents, lac, rac):
+ for constituent in constituents:
+ if not lac.has(constituent):
+ source = rac.get(constituent)
+ target = lac.put(constituent)
+ shutil.copyfileobj(source, target)
+ target.close()
+ source.close()
+
+def get_chunk_files(f):
+ tar = tarfile.open(fileobj=f)
+ for member in tar.getmembers():
+ if member.type is not tarfile.DIRTYPE:
+ yield member.name
+ tar.close()
+
+def get_stratum_files(f, lac):
+ for ca in ((ArtifactCacheReference(a) for a in json.load(f)):
+ cf = lac.get(ca)
+ for filename in get_chunk_files(cf):
+ yield filename
+ cf.close()
def check_overlap(artifact, constituents, lac): #pragma: no cover
# check whether strata overlap
installed = defaultdict(set)
for dep in constituents:
handle = lac.get(dep)
- tar = tarfile.open(fileobj=handle)
- for member in tar.getmembers():
- if member.type is not tarfile.DIRTYPE:
- installed[member.name].add(dep)
- tar.close()
+ if artifact.source.morphology['kind'] == 'stratum':
+ for filename in get_chunk_files(handle):
+ installed[filename].add(dep)
+ elif artifact.source.morphology['kind'] == 'system':
+ for filename in get_stratum_files(handle, lac):
+ installed[filename].add(dep)
handle.close()
overlaps = defaultdict(set)
for filename, artifacts in installed.iteritems():
@@ -344,35 +368,23 @@ class StratumBuilder(BuilderBase):
constituents = [dependency
for dependency in self.artifact.dependencies
if dependency.source.morphology['kind'] == 'chunk']
- with self.build_watch('unpack-chunks'):
+ # the only reason the StratumBuilder has to download chunks is to check
+ # for overlap now that strata are lists of chunks
+ with self.build_watch('check-chunks'):
# download the chunk artifact if necessary
- for chunk_artifact in constituents:
- if not self.local_artifact_cache.has(chunk_artifact):
- source = self.remote_artifact_cache.get(chunk_artifact)
- target = self.local_artifact_cache.put(chunk_artifact)
- shutil.copyfileobj(source, target)
- target.close()
- source.close()
-
+ download_depends(constituents,
+ self.local_artifact_cache,
+ self.remote_artifact_cache)
# check for chunk overlaps
check_overlap(self.artifact, constituents,
self.local_artifact_cache)
- # unpack it from the local artifact cache
- for chunk_artifact in constituents:
- logging.debug('unpacking chunk %s into stratum %s' %
- (chunk_artifact.basename(),
- self.artifact.basename()))
- f = self.local_artifact_cache.get(chunk_artifact)
- morphlib.bins.unpack_binary_from_file(f, destdir)
- f.close()
-
- with self.build_watch('create-binary'):
+ with self.build_watch('create-chunk-list'):
artifact_name = self.artifact.source.morphology['name']
self.write_metadata(destdir, artifact_name)
artifact = self.new_artifact(artifact_name)
with self.local_artifact_cache.put(artifact) as f:
- morphlib.bins.create_stratum(destdir, f)
+ json.dump([c.basename() for c in constituents], f)
self.save_build_times()
@@ -481,14 +493,19 @@ class SystemBuilder(BuilderBase): # pragma: no cover
def _unpack_strata(self, path):
logging.debug('Unpacking strata to %s' % path)
with self.build_watch('unpack-strata'):
- # download the stratum artifact if necessary
+ # download the stratum artifacts if necessary
+ download_depends(self.artifact.dependencies,
+ self.local_artifact_cache,
+ self.remote_artifact_cache)
+
+ # download the chunk artifacts if necessary
for stratum_artifact in self.artifact.dependencies:
- if not self.local_artifact_cache.has(stratum_artifact):
- source = self.remote_artifact_cache.get(stratum_artifact)
- target = self.local_artifact_cache.put(stratum_artifact)
- shutil.copyfileobj(source, target)
- target.close()
- source.close()
+ f = self.local_artifact_cache.get(stratum_artifact)
+ chunks = [ArtifactCacheReference(a) for a in json.load(f)]
+ download_depends(chunks,
+ self.local_artifact_cache,
+ self.remote_artifact_cache)
+ f.close()
# check whether the strata overlap
check_overlap(self.artifact, self.artifact.dependencies,
@@ -497,7 +514,10 @@ class SystemBuilder(BuilderBase): # pragma: no cover
# unpack it from the local artifact cache
for stratum_artifact in self.artifact.dependencies:
f = self.local_artifact_cache.get(stratum_artifact)
- morphlib.bins.unpack_binary_from_file(f, path)
+ for chunk in (ArtifactCacheReference(a) for a in json.load(f)):
+ chunk_handle = self.local_artifact_cache.get(chunk)
+ morphlib.bins.unpack_binary_from_file(chunk_handle, path)
+ chunk_handle.close()
f.close()
ldconfig(self.app.runcmd, path)