Bug 1290531 - Add mach taskcluster-build-image command; r=dustin
authorGregory Szorc <gps@mozilla.com>
Fri, 29 Jul 2016 12:45:25 -0700
changeset 307530 b6eff3784cf2bc9583c5c8476816e4ade138fb46
parent 307529 d645b6c90e9dd518524629edce8b9efbafcba810
child 307531 4509921b0cfd298f27e5164d8ee6361fb2ae2eb2
push id30514
push usercbook@mozilla.com
push dateTue, 02 Aug 2016 15:04:11 +0000
treeherdermozilla-central@ea6e87bbd03e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1290531 - Add mach taskcluster-build-image command; r=dustin Docker image building will soon need to use Python in order to produce the image build context archive. As the first step towards this, we introduce a Python function that calls out to build.sh. We also implement a mach command that calls it so we can test the functionality. I'm not keen about introducing a new mach command. I'd prefer to have a sub-command instead. I'm not sure what all uses `mach taskcluster-load-image`. Perhaps we could make a `taskcluster` top-level command. Or perhaps we could fold these image commands into `mach taskgraph`? Either way, the mach side of this isn't terribly important to the commit series: most of the code will live inside a Python module outside of mach. MozReview-Commit-ID: AI8p6H4psNh
--- a/taskcluster/mach_commands.py
+++ b/taskcluster/mach_commands.py
@@ -223,17 +223,17 @@ class MachCommands(MachCommandBase):
     def show_taskgraph_json(self, taskgraph):
               sort_keys=True, indent=2, separators=(',', ': ')))
-class LoadImage(object):
+class TaskClusterImagesProvider(object):
     @Command('taskcluster-load-image', category="ci",
              description="Load a pre-built Docker image")
                      help="Load the image at public/image.tar in this task,"
                           "rather than searching the index")
     @CommandArgument('image_name', nargs='?',
                      help="Load the image of this name based on the current"
                           "contents of the tree (as built for mozilla-central"
@@ -248,8 +248,21 @@ class LoadImage(object):
                 ok = load_image_by_task_id(task_id)
                 ok = load_image_by_name(image_name)
             if not ok:
         except Exception:
+    @Command('taskcluster-build-image', category='ci',
+             description='Build a Docker image')
+    @CommandArgument('image_name',
+                     help='Name of the image to build')
+    def build_image(self, image_name):
+        from taskgraph.docker import build_image
+        try:
+            build_image(image_name)
+        except Exception:
+            traceback.print_exc()
+            sys.exit(1)
--- a/taskcluster/taskgraph/docker.py
+++ b/taskcluster/taskgraph/docker.py
@@ -10,16 +10,17 @@ import json
 import os
 import subprocess
 import tarfile
 import urllib2
 from taskgraph.util import docker
 GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..'))
+IMAGE_DIR = os.path.join(GECKO, 'testing', 'docker')
 INDEX_URL = 'https://index.taskcluster.net/v1/task/docker.images.v1.{}.{}.hash.{}'
 ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{}/artifacts/{}'
 def load_image_by_name(image_name):
     context_path = os.path.join(GECKO, 'testing', 'docker', image_name)
     context_hash = docker.generate_context_hash(GECKO, context_path, image_name)
@@ -56,8 +57,19 @@ def load_image_by_task_id(task_id):
         print("*** problem and running `docker load < {}`.".format(filename))
     print("Deleting temporary file")
     print("The requested docker image is now available as", name)
     print("Try: docker run -ti --rm {} bash".format(name))
+def build_image(name):
+    """Build a Docker image of specified name.
+    Output from image building process will be printed to stdout.
+    """
+    args = [os.path.join(IMAGE_DIR, 'build.sh'), name]
+    res = subprocess.call(args, cwd=IMAGE_DIR)
+    if res:
+        raise Exception('error building image')