Bug 1290531 - Add mach taskcluster-build-image command; r?dustin draft
authorGregory Szorc <gps@mozilla.com>
Fri, 29 Jul 2016 12:45:25 -0700
changeset 395031 8222520106b6a933c2bbb4164213fee4100f205b
parent 395030 d645b6c90e9dd518524629edce8b9efbafcba810
child 395032 ec5be7ea360563e940edbfe919986c83712164bd
push id24705
push userbmo:gps@mozilla.com
push dateMon, 01 Aug 2016 18:26:57 +0000
reviewersdustin
bugs1290531
milestone50.0a1
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
taskcluster/mach_commands.py
taskcluster/taskgraph/docker.py
--- a/taskcluster/mach_commands.py
+++ b/taskcluster/mach_commands.py
@@ -223,17 +223,17 @@ class MachCommands(MachCommandBase):
             print(label)
 
     def show_taskgraph_json(self, taskgraph):
         print(json.dumps(taskgraph.to_json(),
               sort_keys=True, indent=2, separators=(',', ': ')))
 
 
 @CommandProvider
-class LoadImage(object):
+class TaskClusterImagesProvider(object):
     @Command('taskcluster-load-image', category="ci",
              description="Load a pre-built Docker image")
     @CommandArgument('--task-id',
                      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)
             else:
                 ok = load_image_by_name(image_name)
             if not ok:
                 sys.exit(1)
         except Exception:
             traceback.print_exc()
             sys.exit(1)
+
+    @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))
         raise
 
     print("Deleting temporary file")
     os.unlink(filename)
 
     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')