Hermetic builds inside a container
Adds 'build/docker/Dockerfile' which describes the base container image of
Hafnium compilation environment. This image is built and uploaded to GCP
where users download it from. The feature is always enabled for Kokoro
and can optionally be enabled for local builds too. Once rootless
containers are easier to set up, we might make it the default for local
builds too.
An arbitrary command can be executed inside the container with
'build/run_in_container.sh [-i] <command> ...'. This is done
automatically inside 'Makefile' and 'kokoro/ubuntu/build.sh' which
detect whether they are already running inside the container and respawn
themselves using 'run_in_container.sh' if not.
The feature is guarded with HAFNIUM_HERMETIC_BUILD environment variable,
switched on if the value is "true". All other values switch it off, e.g.
'run_in_container.sh' sets it to 'inside' to avoid recursion.
Bug: 132428451
Test: HAFNIUM_HERMETIC_BUILD=<value> make
Test: HAFNIUM_HERMETIC_BUILD=<value> kokoro/ubuntu/build.sh
Change-Id: I0737a868ab4f67c0fdbf78fa8a97cc91714d2e10
diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md
index 7182544..eae6a16 100644
--- a/docs/GettingStarted.md
+++ b/docs/GettingStarted.md
@@ -35,8 +35,8 @@
make PROJECT=<project_name>
```
-The compiled image can be found under `out/<project>`, for example the QEMU image is at
-at `out/reference/qemu_aarch64_clang/hafnium.bin`.
+The compiled image can be found under `out/<project>`, for example the QEMU
+image is at `out/reference/qemu_aarch64_clang/hafnium.bin`.
## Running on QEMU
diff --git a/docs/HermeticBuild.md b/docs/HermeticBuild.md
new file mode 100644
index 0000000..ca1026e
--- /dev/null
+++ b/docs/HermeticBuild.md
@@ -0,0 +1,87 @@
+# Hermetic build
+
+Hafnium build is not hermetic as it uses some system tools and libraries, e.g.
+`bison` and `libssl`. To ensure consistency and repeatability, the team
+maintains and periodically publishes a container image as the reference build
+environment. The image is hosted on Google Cloud Platform as
+`eu.gcr.io/hafnium-build/hafnium_ci`.
+
+Building inside a container is always enabled only for Kokoro pre-submit tests
+but can be enabled for local builds too. It is disabled by default as it
+requires the use of Docker which currently supports rootless containers only
+in nightly builds. As rootless container tools mature, Hafnium may change the
+default settings. For now, running the hermetic build locally is intended
+primarily to reproduce issues in pre-submit tests.
+
+## Installing Docker
+
+### Stable
+
+If you don't mind running a Docker daemon with root privileges on your system,
+you can follow the [official guide](https://docs.docker.com/install/) to install
+Docker, or [go/installdocker](https://goto.google.com/installdocker) if you are
+a Googler.
+
+Because the daemon runs as root, files generated by the container are owned by
+root as well. To work around this, the build will automatically derive a local
+container image from the base container, adding user `hafnium` with the same
+UID/GID as the local user.
+
+### Nightly with rootless
+
+The latest nightly version of Docker has support for running containers with
+user namespaces, thus eliminating the need for a daemon with root privileges.
+It can be installed into the local user's `bin` directory with a script:
+``` shell
+curl -fsSL https://get.docker.com/rootless -o get-docker.sh
+sh get-docker.sh
+```
+
+The script will also walk you through the installation of dependencies,
+changes to system configuration files and environment variable values needed
+by the client to discover the rootless daemon.
+
+## Enabling for local builds
+
+Hermetic builds are controlled by the `HAFNIUM_HERMETIC_BUILD` environment
+variable. Setting it to `true` instructs the build to run commands inside the
+container. Any other value disables the feature.
+
+To always enable hermetic builds, put this line in your `~/.bashrc`:
+``` shell
+export HAFNIUM_HERMETIC_BUILD=true
+```
+
+When you now run `make`, you should see the following line:
+``` shell
+$ make
+Running in container: make all
+...
+```
+## Running commands inside the container
+
+An arbitrary command can be executed inside the container with
+`build/run_in_container.sh [-i] <command> ...`. This is done
+automatically inside `Makefile` and `kokoro/ubuntu/build.sh` which
+detect whether they are already running inside the container and respawn
+themselves using `run_in_container.sh` if not.
+
+For example, you can spawn a shell with:
+``` shell
+./build/run_in_container.sh -i bash
+```
+
+## Building container image
+
+The container image is defined in `build/docker/Dockerfile` and can be built
+locally:
+``` shell
+./build/docker/build.sh
+```
+
+Owners of the `hafnium-build` GCP repository can publish the new image
+(requires [go/cloud-sdk](https://goto.google.com/cloud-sdk) installed and
+authenticated):
+``` shell
+./build/docker/publish.sh
+```