1# Hermetic build
2
3Hafnium build is not hermetic as it uses some system tools and libraries, e.g.
4`bison` and `libssl`. To ensure consistency and repeatability, the team
5maintains and periodically publishes a container image as the reference build
6environment. The image is hosted on Google Cloud Platform as
7`eu.gcr.io/hafnium-build/hafnium_ci`.
8
9Building inside a container is always enabled only for Kokoro pre-submit tests
10but can be enabled for local builds too. It is disabled by default as it
11requires the use of Docker which currently supports rootless containers only in
12nightly builds. As rootless container tools mature, Hafnium may change the
13default settings. For now, running the hermetic build locally is intended
14primarily to reproduce issues in pre-submit tests.
15
16## Installing Docker
17
18### Stable
19
20If you don't mind running a Docker daemon with root privileges on your system,
21you can follow the [official guide](https://docs.docker.com/install/) to install
22Docker, or [go/installdocker](https://goto.google.com/installdocker) if you are
23a Googler.
24
25Because the daemon runs as root, files generated by the container are owned by
26root as well. To work around this, the build will automatically derive a local
27container image from the base container, adding user `hafnium` with the same
28UID/GID as the local user.
29
30### Nightly with rootless
31
32The latest nightly version of Docker has support for running containers with
33user namespaces, thus eliminating the need for a daemon with root privileges. It
34can be installed into the local user's `bin` directory with a script:
35
36```shell
37curl -fsSL https://get.docker.com/rootless -o get-docker.sh
38sh get-docker.sh
39```
40
41The script will also walk you through the installation of dependencies, changes
42to system configuration files and environment variable values needed by the
43client to discover the rootless daemon.
44
45## Enabling for local builds
46
47Hermetic builds are controlled by the `HAFNIUM_HERMETIC_BUILD` environment
48variable. Setting it to `true` instructs the build to run commands inside the
49container. Any other value disables the feature.
50
51To always enable hermetic builds, put this line in your `~/.bashrc`:
52
53```shell
54export HAFNIUM_HERMETIC_BUILD=true
55```
56
57When you now run `make`, you should see the following line:
58
59```shell
60$ make
61Running in container: make all
62...
63```
64
65## Running commands inside the container
66
67An arbitrary command can be executed inside the container with
68`build/run_in_container.sh [-i] <command> ...`. This is done automatically
69inside `Makefile` and `kokoro/build.sh` which detect whether they are already
70running inside the container and respawn themselves using `run_in_container.sh`
71if not.
72
73For example, you can spawn a shell with:
74
75```shell
76./build/run_in_container.sh -i bash
77```
78
79## Building container image
80
81The container image is defined in `build/docker/Dockerfile` and can be built
82locally:
83
84```shell
85./build/docker/build.sh
86```
87
88Owners of the `hafnium-build` GCP repository can publish the new image (requires
89[go/cloud-sdk](https://goto.google.com/cloud-sdk) installed and authenticated):
90
91```shell
92./build/docker/publish.sh
93```
94