Bug 1329282 - Build docker images uses QEMU image draft
authorJonas Finnemann Jensen <jopsen@gmail.com>
Wed, 27 Sep 2017 13:31:49 -0700
changeset 671397 7ffcdce24d3bedc8e69f96dba1733d56d6297291
parent 671396 a9f7cee48133266e0f1a19741e8f004195d5ebf0
child 733533 9b07b93b74eb57b2cf4fbebe00bce099c2fce341
push id81953
push userjojensen@mozilla.com
push dateWed, 27 Sep 2017 22:49:28 +0000
bugs1329282
milestone58.0a1
Bug 1329282 - Build docker images uses QEMU image This will build in-tree docker images using the QEMU image 'docker-image-builder' on packet.net using tc-worker. This makes it easier to tweak docker image building without dealing with docker-in-docker hacks used in docker-worker. And allows us to upgrade the docker version used to build docker images in-tree, hence, we can easy upgrade docker and use newer features. MozReview-Commit-ID: LFuAqBMHoT3
taskcluster/taskgraph/transforms/docker_image.py
taskcluster/taskgraph/util/docker.py
--- a/taskcluster/taskgraph/transforms/docker_image.py
+++ b/taskcluster/taskgraph/transforms/docker_image.py
@@ -22,16 +22,18 @@ from taskgraph.util.docker import (
 transforms = TransformSequence()
 
 ROUTE_TEMPLATES = [
     'index.{index_prefix}.level-{level}.{image_name}.latest',
     'index.{index_prefix}.level-{level}.{image_name}.pushdate.{year}.{month}-{day}-{pushtime}',
     'index.{index_prefix}.level-{level}.{image_name}.hash.{context_hash}',
 ]
 
+# Switch between QEMU image builder or docker-worker with dind
+USE_QEMU_IMAGE_BUILDER = True
 
 @transforms.add
 def fill_template(config, tasks):
     for task in tasks:
         image_name = task.pop('name')
         job_symbol = task.pop('symbol')
 
         context_path = os.path.join('taskcluster', 'docker', image_name)
@@ -67,16 +69,59 @@ def fill_template(config, tasks):
 
         # Adjust the zstandard compression level based on the execution level.
         # We use faster compression for level 1 because we care more about
         # end-to-end times. We use slower/better compression for other levels
         # because images are read more often and it is worth the trade-off to
         # burn more CPU once to reduce image size.
         zstd_level = '3' if int(config.params['level']) == 1 else '10'
 
+        taskdesc = {
+            'label': 'build-docker-image-' + image_name,
+            'description': description,
+            'attributes': {'image_name': image_name},
+            'expires-after': '1 year',
+            'routes': routes,
+            'optimization': optimization,
+            'scopes': ['secrets:get:project/taskcluster/gecko/hgfingerprint'],
+            'treeherder': {
+                'symbol': job_symbol,
+                'platform': 'taskcluster-images/opt',
+                'kind': 'other',
+                'tier': 1,
+            },
+            'run-on-projects': [],
+            'worker-type': 'manual-packet/tc-worker-qemu-v1',
+            'worker': {
+                'implementation': 'qemu-engine',
+                'image': {'in-tree': 'docker-image-builder'},
+                'command': ['build-image.sh'],
+                'env': {
+                    'GECKO_BASE_REPOSITORY': config.params['base_repository'],
+                    'GECKO_HEAD_REPOSITORY': config.params['head_repository'],
+                    'GECKO_HEAD_REV': config.params['head_rev'],
+                    'HASH': context_hash,
+                    'PROJECT': config.params['project'],
+                    'IMAGE_NAME': image_name,
+                    'DOCKER_IMAGE_ZSTD_LEVEL': zstd_level,
+                },
+                'artifacts': [{
+                    'type': 'file',
+                    'path': '/home/worker/artifacts/image.tar.zst',
+                    'name': 'public/image.tar.zst',
+                }],
+                'max-run-time': '3 hours',
+            },
+        }
+
+        # Switch between the two tc-worker and docker-worker with dind
+        if USE_QEMU_IMAGE_BUILDER:
+            yield taskdesc
+            continue
+
         # include some information that is useful in reconstructing this task
         # from JSON
         taskdesc = {
             'label': 'build-docker-image-' + image_name,
             'description': description,
             'attributes': {'image_name': image_name},
             'expires-after': '1 year',
             'routes': routes,
--- a/taskcluster/taskgraph/util/docker.py
+++ b/taskcluster/taskgraph/util/docker.py
@@ -13,16 +13,17 @@ import tempfile
 import json
 
 from mozbuild.util import memoize
 from mozpack.archive import (
     create_tar_gz_from_files,
 )
 from .. import GECKO
 from .hash import hash_path
+from ..qemu.imagehash import compute_image_hash
 
 IMAGE_DIR = os.path.join(GECKO, 'taskcluster', 'docker')
 INDEX_PREFIX = 'docker.images.v2'
 
 
 def docker_image(name, by_tag=False):
     '''
         Resolve in-tree prebuilt docker image to ``<registry>/<repository>@sha256:<digest>``,
@@ -130,16 +131,17 @@ def create_context_tar(topsrcdir, contex
             data = fh.read(32768)
             if not data:
                 break
             ctx_hash.update(data)
     # Construct image hash as combination of other hashes
     return hashlib.sha256(json.dumps({
         "version": 1,  # version number for manually bumping
         "context": ctx_hash.hexdigest(),  # hash of context tarball
+        "builder": compute_image_hash('docker-image-builder'),
         "code": hash_path(__file__),  # hash of file that computes hashes
         # hash of file that constructs the image-task
         "task": hash_path(os.path.abspath(os.path.join(
             os.path.dirname(__file__),
             os.path.join(os.path.pardir, 'transforms', 'docker_image.py'),
         ))),
     }, sort_keys=True)).hexdigest()