diff options
-rwxr-xr-x | morph | 36 | ||||
-rw-r--r-- | morphlib/builder.py | 37 | ||||
-rw-r--r-- | morphlib/buildworker.py | 6 |
3 files changed, 74 insertions, 5 deletions
@@ -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 |