summaryrefslogtreecommitdiffstats
path: root/taskcluster/docs/docker-images.rst
diff options
context:
space:
mode:
Diffstat (limited to 'taskcluster/docs/docker-images.rst')
-rw-r--r--taskcluster/docs/docker-images.rst210
1 files changed, 210 insertions, 0 deletions
diff --git a/taskcluster/docs/docker-images.rst b/taskcluster/docs/docker-images.rst
new file mode 100644
index 0000000000..8facce6afe
--- /dev/null
+++ b/taskcluster/docs/docker-images.rst
@@ -0,0 +1,210 @@
+.. taskcluster_dockerimages:
+
+=============
+Docker Images
+=============
+
+TaskCluster Docker images are defined in the source directory under
+``taskcluster/docker``. Each directory therein contains the name of an
+image used as part of the task graph.
+
+Organization
+------------
+
+Each folder describes a single docker image. We have two types of images that can be defined:
+
+1. Task Images (build-on-push)
+2. Docker Images (prebuilt)
+
+These images depend on one another, as described in the `FROM
+<https://docs.docker.com/v1.8/reference/builder/#from>`_ line at the top of the
+Dockerfile in each folder.
+
+Images could either be an image intended for pushing to a docker registry, or
+one that is meant either for local testing or being built as an artifact when
+pushed to vcs.
+
+Task Images (build-on-push)
+:::::::::::::::::::::::::::
+
+Images can be uploaded as a task artifact, :ref:`indexed <task-image-index-namespace>` under
+a given namespace, and used in other tasks by referencing the task ID.
+
+Important to note, these images do not require building and pushing to a docker registry, and are
+built per push (if necessary) and uploaded as task artifacts.
+
+The decision task that is run per push will :ref:`determine <context-directory-hashing>`
+if the image needs to be built based on the hash of the context directory and if the image
+exists under the namespace for a given branch.
+
+As an additional convenience, and a precaution to loading images per branch, if an image
+has been indexed with a given context hash for mozilla-central, any tasks requiring that image
+will use that indexed task. This is to ensure there are not multiple images built/used
+that were built from the same context. In summary, if the image has been built for mozilla-central,
+pushes to any branch will use that already built image.
+
+To use within an in-tree task definition, the format is:
+
+.. code-block:: yaml
+
+ image:
+ type: 'task-image'
+ path: 'public/image.tar.zst'
+ taskId: '<task_id_for_image_builder>'
+
+.. _context-directory-hashing:
+
+Context Directory Hashing
+.........................
+
+Decision tasks will calculate the sha256 hash of the contents of the image
+directory and will determine if the image already exists for a given branch and hash
+or if a new image must be built and indexed.
+
+Note: this is the contents of *only* the context directory, not the
+image contents.
+
+The decision task will:
+
+1. Recursively collect the paths of all files within the context directory
+2. Sort the filenames alphabetically to ensure the hash is consistently calculated
+3. Generate a sha256 hash of the contents of each file
+4. All file hashes will then be combined with their path and used to update the
+ hash of the context directory
+
+This ensures that the hash is consistently calculated and path changes will result
+in different hashes being generated.
+
+.. _task-image-index-namespace:
+
+Task Image Index Namespace
+..........................
+
+Images that are built on push and uploaded as an artifact of a task will be indexed under the
+following namespaces.
+
+* gecko.cache.level-{level}.docker.v2.{name}.hash.{digest}
+* gecko.cache.level-{level}.docker.v2.{name}.latest
+* gecko.cache.level-{level}.docker.v2.{name}.pushdate.{year}.{month}-{day}-{pushtime}
+
+Not only can images be browsed by the pushdate and context hash, but the 'latest' namespace
+is meant to view the latest built image. This functions similarly to the 'latest' tag
+for docker images that are pushed to a registry.
+
+Docker Registry Images (prebuilt)
+:::::::::::::::::::::::::::::::::
+
+***Warning: Registry images are only used for ``decision`` and
+``image_builder`` images.***
+
+These are images that are intended to be pushed to a docker registry and used
+by specifying the docker image name in task definitions. They are generally
+referred to by a ``<repo>@<repodigest>`` string:
+
+Example:
+
+.. code-block:: none
+
+ image: taskcluster/decision:0.1.10@sha256:c5451ee6c655b3d97d4baa3b0e29a5115f23e0991d4f7f36d2a8f793076d6854
+
+Such images must always be referred to with both a version and a repo digest.
+For the decision image, the repo digest is stored in the ``HASH`` file in the
+image directory and used to refer to the image as above. The version for both
+images is in ``VERSION``.
+
+The version file serves to help users identify which image is being used, and makes old
+versions easy to discover in the registry.
+
+The file ``taskcluster/docker/REGISTRY`` specifies the image registry to which
+the completed image should be uploaded.
+
+Docker Hashes and Digests
+.........................
+
+There are several hashes involved in this process:
+
+ * Image Hash -- the long version of the image ID; can be seen with
+ ``docker images --no-trunc`` or in the ``Id`` field in ``docker inspect``.
+
+ * Repo Digest -- hash of the image manifest; seen when running ``docker
+ push`` or ``docker pull``.
+
+ * Context Directory Hash -- see above (not a Docker concept at all)
+
+The use of hashes allows older tasks which were designed to run on an older
+version of the image to be executed in Taskcluster while new tasks use the new
+version. Furthermore, this mitigates attacks against the registry as docker
+will verify the image hash when loading the image.
+
+(Re)-Building images
+--------------------
+
+Generally, images can be pulled from the Docker registry rather than built
+locally, however, for developing new images it's often helpful to hack on them
+locally.
+
+To build an image, invoke ``mach taskcluster-build-image`` with the name of the
+folder (without a trailing slash):
+
+.. code-block:: none
+
+ ./mach taskcluster-build-image <image-name>
+
+This is a wrapper around ``docker build -t $REGISTRY/$FOLDER:$VERSION``.
+
+It's a good idea to bump the ``VERSION`` early in this process, to avoid
+``docker push``-ing over any old tags.
+
+For task images, test your image locally or push to try. This is all that is
+required.
+
+Docker Registry Images
+::::::::::::::::::::::
+
+Landing docker registry images takes a little more care.
+
+Begin by bumping the ``VERSION``. Once the new version of the image has been
+built and tested locally, push it to the docker registry and make note of the
+resulting repo digest. Put this value in the ``HASH`` file for the
+``decision`` image and in ``taskcluster/taskgraph/transforms/docker_image.py``
+for the ``image_builder`` image.
+
+The change is now safe to use in Try pushes.
+
+Note that ``image_builder`` change can be tested directly in try pushes without
+using a registry, as the in-registry ``image_builder`` image is used to build a
+task image which is then used to build other images. It is referenced by hash
+in ``taskcluster/taskgraph/transforms/docker_image.py``.
+
+Special Dockerfile Syntax
+-------------------------
+
+Dockerfile syntax has been extended to allow *any* file from the
+source checkout to be added to the image build *context*. (Traditionally
+you can only ``ADD`` files from the same directory as the Dockerfile.)
+
+Simply add the following syntax as a comment in a Dockerfile::
+
+ # %include <path>
+
+e.g.
+
+ # %include mach
+ # %include testing/mozharness
+
+The argument to ``# %include`` is a relative path from the root level of
+the source directory. It can be a file or a directory. If a file, only that
+file will be added. If a directory, every file under that directory will be
+added (even files that are untracked or ignored by version control).
+
+Files added using ``# %include`` syntax are available inside the build
+context under the ``topsrcdir/`` path.
+
+Files are added as they exist on disk. e.g. executable flags should be
+preserved. However, the file owner/group is changed to ``root`` and the
+``mtime`` of the file is normalized.
+
+Here is an example Dockerfile snippet::
+
+ # %include mach
+ ADD topsrcdir/mach /builds/worker/mach