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
--- 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.