summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xmorph36
-rw-r--r--morphlib/builder.py37
-rw-r--r--morphlib/buildworker.py6
3 files changed, 74 insertions, 5 deletions
diff --git a/morph b/morph
index cbebc46d..3e78fb18 100755
--- a/morph
+++ b/morph
@@ -222,6 +222,42 @@ class Morph(cliapp.Application):
source_manager)
builder.get_cache_id(blob)
+ def cmd_build_single(self, args):
+ tempdir = morphlib.tempdir.Tempdir()
+ morph_loader = MorphologyLoader(self.settings)
+ source_manager = morphlib.sourcemanager.SourceManager(self,
+ update=False)
+ builder = morphlib.builder.Builder(tempdir, self, morph_loader,
+ source_manager)
+
+ if not os.path.exists(self.settings['cachedir']):
+ os.mkdir(self.settings['cachedir'])
+
+ ret = []
+ while len(args) >= 3:
+ repo, ref, filename = args[:3]
+ args = args[3:]
+
+ # derive a build order from the dependency graph
+ graph = BuildDependencyGraph(source_manager, morph_loader,
+ repo, ref, filename)
+ blob = graph.resolve()
+ blobs, order = graph.build_order()
+
+ self.msg('Building %s' % blob)
+
+ # build things in this order
+ ret.append(builder.build_single(blob, blobs, order))
+
+ # we may not have permission to tempdir.remove()
+ ex = morphlib.execute.Execute('.', lambda msg: None)
+ ex.runv(["rm", "-rf", tempdir.dirname])
+
+ if args:
+ raise cliapp.AppException('Extra args on command line: %s' % args)
+
+ return ret
+
def cmd_build_distributed(self, args):
tempdir = morphlib.tempdir.Tempdir()
morph_loader = MorphologyLoader(self.settings)
diff --git a/morphlib/builder.py b/morphlib/builder.py
index 038ec564..53127223 100644
--- a/morphlib/builder.py
+++ b/morphlib/builder.py
@@ -546,8 +546,8 @@ class Builder(object):
for parent in blob.parents:
for item, filename in built_items:
- self.msg('Marking %s to be staged for %s'
- % (item, parent))
+ self.msg('Marking %s to be staged for %s' %
+ (item, parent))
parent_builder = builders[parent]
parent_builder.stage_items += built_items
@@ -558,6 +558,39 @@ class Builder(object):
return ret
+ def build_single(self, blob, blobs, build_order):
+ self.indent_more()
+
+ # first pass: create builders for all blobs
+ builders = {}
+ for group in build_order:
+ for blob in group:
+ builder = self.create_blob_builder(blob)
+ builders[blob] = builder
+
+ # second pass: walk the build order blob by blob, mark blobs
+ # to be staged for their parents, but do not build them
+ ret = []
+ for group in build_order:
+ for blob in group:
+ built_items = builders[blob].builds()
+ for parent in blob.parents:
+ stage_items = []
+ for name, filename in built_items.items():
+ self.msg('Marking %s to be staged for %s' %
+ (name, parent))
+ stage_items.append((name, filename))
+
+ parent_builder = builders[parent]
+ parent_builder.stage_items.extend(stage_items)
+
+ # build the single blob now
+ ret.append(builders[blob].build())
+
+ self.indent_less()
+
+ return ret
+
def create_blob_builder(self, blob):
if isinstance(blob, morphlib.blobs.Stratum):
builder = StratumBuilder(blob)
diff --git a/morphlib/buildworker.py b/morphlib/buildworker.py
index 6ab43179..994ea52a 100644
--- a/morphlib/buildworker.py
+++ b/morphlib/buildworker.py
@@ -149,7 +149,7 @@ class LocalBuildWorker(BuildWorker):
cmdline = []
if sudo:
cmdline.extend(['sudo'])
- cmdline.extend(['morph', 'build', repo, ref, filename])
+ cmdline.extend(['morph', 'build-single', repo, ref, filename])
cmdline.extend(args)
# run morph locally in a child process
@@ -191,12 +191,12 @@ class RemoteBuildWorker(BuildWorker):
if sudo:
cmdline.extend(['sudo', '-S', 'bash', '--login', '-c'])
cmdline.extend(['"'])
- cmdline.extend(['morph', 'build', repo, ref, filename])
+ cmdline.extend(['morph', 'build-single', repo, ref, filename])
cmdline.extend(args)
cmdline.extend(['"'])
else:
cmdline.extend(['fakeroot'])
- cmdline.extend(['morph', 'build', repo, ref, filename])
+ cmdline.extend(['morph', 'build-single', repo, ref, filename])
cmdline.extend(args)
# run morph on the other machine