Virtual machine drivers
If the build environment is defined using a reference free operating system, forcing users to reinstall an entire computer just to reproduce a build is a lot to ask.
Thankfully, nowadays we have virtual machine and containers which can give easy access to a wide range of operating systems for little overhead. Several tools have been designed to help running virtual machines and containers, some with the explicit goal of reproducible builds in mind.
Gitian
Gitian is a secure source-control oriented software distribution method. The Gitian Builder was previously used by Bitcoin Core for deterministic builds for about 10 years.
It either runs in a Linux container using LXC, or in a virtual machine using KVM. Gitian takes descriptors as input which tell which base GNU/Linux distribution to use, which packages to install, which Git remotes to fetch, which other input files to use, and a build script to be run with all of that. As explained earlier, using a virtual machine helps to get rid of several extra variations that can happen from one system to the next. But this is more complicated to setup for users.
rbm
In the Tor Browser build process, rbm is the tool responsible for figuring out the components that need to be (re)built, downloading dependencies, verifying their signatures or checksums, creating container images with selected packages and starting the build of each component inside containers using runc.
Docker
Making containers easy to setup and use is the problem that Docker is trying
to solve. Dockerfiles
are used to describe how to create a container, and
how applications can be run in there.
A tool often used in Docker images, gosu
can be built reproducibly using
Docker. Using the
reference container made available to build Go applications, it then
installs the necessary dependencies, and calls the Go compiler in that
environment which should be pretty much the same all the time.
To be sure that the base compiler is the same, one could use the fact that Docker images can actually be addressed by a hash of their content. Another option is to build the Docker image oneself in a reproducible manner, something that can be done using Bazel.
Vagrant
Vagrant is another tool, written in Ruby, that can run virtual machines with VirtualBox. It can also be used to get a controlled build environment. The upside of Vagrant and VirtualBox is that they work on Mac OS X and Windows, and so this might help more users to actually check that a build has not been tempered with.
Introduction
Achieve deterministic builds
- Commandments of reproducible builds
- Variations in the build environment
- SOURCE_DATE_EPOCH
- Deterministic build systems
- Volatile inputs can disappear
- Stable order for inputs
- Stripping of unreproducible information
- Value initialization
- Version information
- Timestamps
- Timezones
- Locales
- Archive metadata
- Stable order for outputs
- Randomness
- Build path
- System images
- JVM
Define a build environment
- What's in a build environment?
- Recording the build environment
- Definition strategies
- Proprietary operating systems
Distribute the environment
- Building from source
- Virtual machine drivers
- Formal definition