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):
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')