Bug 1329282 - Cover docker.py and docker_image.py in image-hash draft
authorJonas Finnemann Jensen <jopsen@gmail.com>
Mon, 25 Sep 2017 13:17:33 -0700
changeset 671396 a9f7cee48133266e0f1a19741e8f004195d5ebf0
parent 671395 033876cfe3e7833f2beb48604b3fd0079225cf13
child 671397 7ffcdce24d3bedc8e69f96dba1733d56d6297291
push id81953
push userjojensen@mozilla.com
push dateWed, 27 Sep 2017 22:49:28 +0000
bugs1329282
milestone58.0a1
Bug 1329282 - Cover docker.py and docker_image.py in image-hash When computing the image_hash of an in-tree docker image to determine if the image should be rebuilt we should always cover: * `taskcluster/taskgraph/util/docker.py`, and, * `taskcluster/taskgraph/transforms/docker_image.py` This ensures that images are rebuilt if we change the code or tasks used to built the images. We rarely change this and overhead of rebuilding docker images is relatively small, compared to debugging some weird bug like not being able to rebuild an image due to some change with the image building logic. MozReview-Commit-ID: 4AsdW3pV3Ft
taskcluster/taskgraph/util/docker.py
--- a/taskcluster/taskgraph/util/docker.py
+++ b/taskcluster/taskgraph/util/docker.py
@@ -5,23 +5,24 @@
 from __future__ import absolute_import, print_function, unicode_literals
 
 import hashlib
 import os
 import shutil
 import subprocess
 import tarfile
 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
 
 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>``,
@@ -117,24 +118,35 @@ def create_context_tar(topsrcdir, contex
                         archive_files[archive_path] = source_path
             else:
                 archive_path = os.path.join(prefix, 'topsrcdir', p)
                 archive_files[archive_path] = fs_path
 
     with open(out_path, 'wb') as fh:
         create_tar_gz_from_files(fh, archive_files, '%s.tar.gz' % prefix)
 
-    h = hashlib.sha256()
+    # Compute hash of context tarball
+    ctx_hash = hashlib.sha256()
     with open(out_path, 'rb') as fh:
         while True:
             data = fh.read(32768)
             if not data:
                 break
-            h.update(data)
-    return h.hexdigest()
+            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
+        "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()
 
 
 def build_from_context(docker_bin, context_path, prefix, tag=None):
     """Build a Docker image from a context archive.
 
     Given the path to a `docker` binary, a image build tar.gz (produced with
     ``create_context_tar()``, a prefix in that context containing files, and
     an optional ``tag`` for the produced image, build that Docker image.