Files
tubestation/taskcluster/taskgraph/docker.py
Gregory Szorc f1364a2a25 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
2016-07-29 12:45:25 -07:00

76 lines
2.6 KiB
Python

# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import, print_function, unicode_literals
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)
image_index_url = INDEX_URL.format('mozilla-central', image_name, context_hash)
print("Fetching", image_index_url)
task = json.load(urllib2.urlopen(image_index_url))
return load_image_by_task_id(task['taskId'])
def load_image_by_task_id(task_id):
# because we need to read this file twice (and one read is not all the way
# through), it is difficult to stream it. So we download to disk and then
# read it back.
filename = 'temp-docker-image.tar'
artifact_url = ARTIFACT_URL.format(task_id, 'public/image.tar')
print("Downloading", artifact_url)
subprocess.check_call(['curl', '-#', '-L', '-o', filename, artifact_url])
print("Determining image name")
tf = tarfile.open(filename)
repositories = json.load(tf.extractfile('repositories'))
name = repositories.keys()[0]
tag = repositories[name].keys()[0]
name = '{}:{}'.format(name, tag)
print("Image name:", name)
print("Loading image into docker")
try:
subprocess.check_call(['docker', 'load', '-i', filename])
except subprocess.CalledProcessError:
print("*** `docker load` failed. You may avoid re-downloading that tarball by fixing the")
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')