2016-10-16 18:50:37 -07:00
Zcash deterministic builds
==========================
This is a deterministic build environment for [Zcash ](https://github.com/zcash/zcash/ ) that uses [Gitian ](https://gitian.org/ ).
Gitian provides a way to be reasonably certain that the Zcash executables are really built from the exact source on GitHub and have not been tampered with. It also makes sure that the same, tested dependencies are used and statically built into the executable.
2018-04-02 11:08:26 -07:00
Multiple developers build from source code by following a specific descriptor ("recipe"), cryptographically sign the result, and upload the resulting signature. These results are compared and only if they match is the build accepted.
2016-10-16 18:50:37 -07:00
More independent Gitian builders are needed, which is why this guide exists.
Requirements
------------
2019-02-14 12:10:14 -08:00
6GB of RAM, four cores.
2016-10-16 18:50:37 -07:00
2018-04-23 12:56:06 -07:00
Install Dependencies
--------------------
2016-10-16 18:50:37 -07:00
2019-02-14 12:18:25 -08:00
If you're using one of the following platforms, see the linked instructions for that platform:
- [Debian 9.x ](dependency_install_steps_by_platform/Debian_9.x.md )
2018-05-07 10:37:42 -07:00
- [Ubuntu 18.04.x ](dependency_install_steps_by_platform/Ubuntu_18.04.x.md )
2019-02-14 12:18:25 -08:00
- [macOS 10.13.x ](dependency_install_steps_by_platform/macOS_10.13.x.md )
If you're not using one of the platforms that we have specific instructions for, this is the list of
dependencies we want. Please document the steps involved and we can add another platform to the list
above!
2016-10-18 20:41:43 -07:00
2018-04-23 12:56:06 -07:00
- [Git ](https://git-scm.com/ )
- [VirtualBox ](https://www.virtualbox.org/ )
2018-05-07 09:11:58 -07:00
- [Vagrant ](https://www.vagrantup.com/ ) 2.0.3 or higher
2018-04-23 12:56:06 -07:00
- [Ansible ](https://www.ansible.com/ ) 2.4.x or higher
- [GnuPG ](https://www.gnupg.org/ ) 2.x (2.11.18 or greater) and make sure it is callable via `gpg2`
2016-10-18 20:41:43 -07:00
2018-04-23 12:56:06 -07:00
## Install the `vagrant-disksize` plugin to support resize of the start up disk:
2016-10-18 20:41:43 -07:00
2018-04-23 12:56:06 -07:00
```
$ vagrant plugin install vagrant-disksize
```
2018-03-22 08:38:15 -07:00
2019-02-13 16:00:54 -08:00
Most recently tested 2019-02-13 with the following vagrant-disksize release:
2018-03-22 08:38:15 -07:00
2018-03-31 16:38:05 -07:00
```
2018-04-23 12:56:06 -07:00
$ vagrant plugin list
2019-02-13 16:00:54 -08:00
vagrant-disksize (0.1.3)
2018-03-31 07:18:36 -07:00
```
2018-03-22 08:38:15 -07:00
2018-04-02 14:50:14 -07:00
2018-04-23 12:56:06 -07:00
Configuration
-------------
2018-04-02 14:50:14 -07:00
2018-04-23 12:56:06 -07:00
## Configure git
2018-04-02 14:50:14 -07:00
2018-04-23 12:56:06 -07:00
We want a configuration file in the home directory of the account you'll be working in. This will
determine how you are identified on the projects you contribute to. These settings can be overridden
on a per-project basis.
2018-03-22 08:38:15 -07:00
2018-04-23 12:56:06 -07:00
Git provides some convenient command options for setting this up:
2018-03-22 08:38:15 -07:00
2018-03-31 07:18:36 -07:00
```
2018-04-23 12:56:06 -07:00
$ git config --global user.name "Harry Potter"
$ git config --global user.email "hpotter@hogwarts.wiz"
2018-03-31 07:18:36 -07:00
```
2018-03-22 08:38:15 -07:00
2018-04-23 12:56:06 -07:00
Checking that this worked:
2018-03-22 08:38:15 -07:00
2018-03-31 07:21:09 -07:00
```
2018-04-23 12:56:06 -07:00
$ git config user.name
Harry Potter
$ git config user.email
hpotter@hogwarts.wiz
2018-03-31 07:21:09 -07:00
```
2018-03-22 08:38:15 -07:00
2018-04-23 12:56:06 -07:00
This is all the configuration needed for the steps below, but here is a good reference for further
reading on configuring git:
https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration
2018-03-22 08:38:44 -07:00
2018-04-23 12:56:06 -07:00
## Decide on an ssh keypair for gitian to use when connecting to github
You can generate a keypair specifically for connecting to github like this:
2018-03-22 08:38:44 -07:00
2018-03-31 07:18:36 -07:00
```
2018-04-23 12:56:06 -07:00
$ ssh-keygen -t rsa -C "hpotter@hogwarts.wiz" -f ~/.ssh/github_id_rsa -N ''
2018-03-22 08:38:44 -07:00
Generating public/private rsa key pair.
2018-04-23 12:56:06 -07:00
Your identification has been saved in /Users/hpotter/.ssh/github_id_rsa.
Your public key has been saved in /Users/hpotter/.ssh/github_id_rsa.pub.
2018-03-22 08:38:44 -07:00
The key fingerprint is:
SHA256:w1ZAgf+Ge+R662PU18ASqx8sZYfg9OxKhE/ZFf9zwvE hpotter@hogwarts.wiz
The key's randomart image is:
+---[RSA 2048]----+
| o+. .. |
| . .o . .. |
| . +.* *. .|
| .o.= X.+o.|
| S* B oo+E|
| ...X = ..+|
| B + o |
| . B . |
| .*oo |
+----[SHA256]-----+
2018-04-02 15:14:28 -07:00
```
2018-03-22 08:38:44 -07:00
Some explanation of the arguments used in the above example:
2018-04-02 15:14:28 -07:00
2018-04-23 12:56:06 -07:00
```
2018-04-02 15:14:28 -07:00
-t rsa Use a key type of RSA
-C "hpotter@hogwarts.wiz" Provide an identity to associate with the key (default is
user@host in the local environment)
2018-04-23 12:56:06 -07:00
-f ~/.ssh/github_id_rsa Path to the private key to generate. The corresponding public key
will be saved at ~/.ssh/github_id_rsa.pub
2018-04-02 15:14:28 -07:00
-N '' Passphrase for the generated key. An empty string as shown here
means save the private key unencrypted.
2018-04-23 12:56:06 -07:00
```
2018-03-22 08:38:44 -07:00
2016-10-16 18:50:37 -07:00
2018-04-23 12:56:06 -07:00
# Set up your ssh keypair for use with github
2016-10-16 18:50:37 -07:00
2018-04-23 12:56:06 -07:00
[Add the new key to your github account. ](https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/ )
2016-10-16 18:50:37 -07:00
2018-04-23 12:56:06 -07:00
Add an entry to ~/.ssh/config (create this file if necessary) telling ssh to use the keypair you
2019-02-13 15:02:37 -08:00
generated above when connecting to github.com.
2016-10-16 18:50:37 -07:00
2018-04-23 12:56:06 -07:00
For instance:
2016-10-16 18:50:37 -07:00
2018-04-23 12:56:06 -07:00
```
Host github.com
User harrypotter
PreferredAuthentications publickey
IdentityFile /home/hpotter/.ssh/github_id_rsa
AddKeysToAgent yes
```
2016-10-16 18:50:37 -07:00
2018-04-23 12:56:06 -07:00
The 'User' entry should match your github username.
2016-10-16 18:50:37 -07:00
2018-04-23 12:56:06 -07:00
[Test that ssh will successfully use your new key to connect to github. ](https://help.github.com/articles/testing-your-ssh-connection/ )
## Clone this git project on your machine
```
$ git clone git@github.com:zcash/zcash-gitian.git
2016-10-16 18:50:37 -07:00
```
2018-03-20 08:41:41 -07:00
2018-04-23 12:56:06 -07:00
## Add git and ssh config values to gitian.yml
2016-10-16 18:50:37 -07:00
2019-02-13 15:02:21 -08:00
The `gitian.yml` file in the root of the project has some blank values that need to be updated or
filled in:
2016-10-16 18:50:37 -07:00
2019-02-13 15:02:21 -08:00
- `zcash_version` : The git tag name of the version of zcash you want to build
2018-04-23 12:56:06 -07:00
- `git_name` : You probably want the output from `git config user.name`
- `git_email` : You probably want the output from `git config user.email`
- `ssh_key_name` : The filename of your private key. In the steps above we used the name
`github_id_rsa` .
## Decide on a gpg keypair to use for gitian
You can generate a keypair specifically for zcash gitian builds with a command like the one below.
```
$ gpg2 --quick-gen-key --batch --passphrase '' "Harry Potter (zcash gitian) < hpotter @ hogwarts . wiz > "
gpg: key 3F0C2117D53A4A49 marked as ultimately trusted
gpg: directory '/home/hpotter/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/hpotter/.gnupg/openpgp-revocs.d/3F14A629C06FA31D59C64FE93F0C2117D53A4A49.rev'
```
Some explanation of the arguments used in the above example:
--quick-generate-key --batch This combination of options allows options to be given on the
command line. Other key generation options use interative
prompts.
--passphrase '' Passphrase for the generated key. An empty string as shown here
means save the private key unencrypted.
"Name (Comment) < Email > " The user id (also called uid) to associate with the generated
keys. Concatenating a name, an optional comment, and an email
address using this format is a gpg convention.
You can check that the key was generated and added to your local gpg key database, and see its
fingerprint value, like this:
```
$ gpg2 --list-keys
/home/hpotter/.gnupg/pubring.kbx
----------------------------------
pub rsa2048 2018-04-23 [SC] [expires: 2020-04-22]
3F14A629C06FA31D59C64FE93F0C2117D53A4A49
uid [ultimate] Harry Potter (zcash gitian) < hpotter @ hogwarts . wiz >
sub rsa2048 2018-04-23 [E]
```
Update the `gpg_key_id` and `gpg_key_name` entries in `gitian.yml` as follows:
- `gpg_key_id` : In the example output shown here, this is the 40 character string
`3F14A629C06FA31D59C64FE93F0C2117D53A4A49` . Some versions of gpg may truncate this value, e.g. to 8
or 16 characters. You should be able to use the truncated value.
- `gpg_key_name` : the the part before the @ symbol of the associated email address. In our example
this is `hpotter` .
## Provision a virtual machine
From the project root directory, run:
```
$ vagrant up --provision zcash-build
```
This will provision a Gitian host virtual machine that uses a Linux container (LXC) guest to perform
the actual builds.
2016-10-16 18:50:37 -07:00
2016-10-18 20:41:43 -07:00
Use `git stash` to save one's local customizations to `gitian.yml` .
2018-04-23 12:56:06 -07:00
2016-10-16 18:50:37 -07:00
Building Zcash
--------------
2018-04-23 12:56:06 -07:00
```
# on your host machine
$ vagrant ssh zcash-build
[...]
# on the virtualbox vm
$ ./gitian-build.sh
```
2016-10-16 18:50:37 -07:00
2016-10-16 23:08:43 -07:00
The output from `gbuild` is informative. There are some common warnings which can be ignored, e.g. if you get an intermittent privileges error related to LXC then just execute the script again. The most important thing is that one reaches the step which says `Running build script (log in var/build.log)` . If not, then something else is wrong and you should let us know.
2016-10-16 18:50:37 -07:00
2016-10-18 20:41:43 -07:00
Take a look at the variables near the top of `~/gitian-build.sh` and get familiar with its functioning, as it can handle most tasks.
2016-10-18 00:57:58 -07:00
2016-10-18 20:41:43 -07:00
It's also a good idea to regularly `git pull` on this repository to obtain updates and re-run the entire VM provisioning for each release, to ensure current and consistent state for your builder.
2016-10-16 18:50:37 -07:00
Generating and uploading signatures
-----------------------------------
After the build successfully completes, `gsign` will be called. Commit and push your signatures (both the .assert and .assert.sig files) to the [zcash/gitian.sigs ](https://github.com/zcash/gitian.sigs ) repository, or if that's not possible then create a pull request.
2016-10-22 16:44:26 -07:00
Signatures can be verified by running `gitian-build.sh --verify` , but set `build=false` in the script to skip building. Run a `git pull` beforehand on `gitian.sigs` so you have the latest. The provisioning includes a task which imports Zcash developer public keys to the Vagrant user's keyring and sets them to ultimately trusted, but they can also be found at `contrib/gitian-downloader` within the Zcash source repository.
2016-10-16 18:50:37 -07:00
Working with GPG and SSH
--------------------------
2017-04-27 14:36:07 -07:00
We provide two options for automatically importing keys into the VM, or you may choose to copy them manually. Keys are needed A) to sign the manifests which get pushed to [gitian.sigs ](https://github.com/zcash/gitian.sigs ) and B) to interact with GitHub, if you choose to use an SSH instead of HTTPS remote. The latter would entail always providing your GitHub login and [access token ](https://github.com/settings/tokens ) in order to push from within the VM.
2016-10-16 18:50:37 -07:00
Your local SSH agent is automatically forwarded into the VM via a configuration option. If you run ssh-agent, your keys should already be available.
GPG is trickier, especially if you use a smartcard and can't copy the secret key. We have a script intended to forward the gpg-agent socket into the VM, `forward_gpg_agent.sh` , but it is not currently working. If you want your full keyring to be available, you can use the following workaround involving `sshfs` and synced folders:
vagrant plugin install vagrant-sshfs
Uncomment the line beginning with `gitian.vm.synced_folder "~/.gnupg"` in `Vagrantfile` . Ensure the destination mount point is empty. Then run:
vagrant sshfs --mount zcash-build
Vagrant synced folders may also work natively with `vboxfs` if you install VirtualBox Guest Additions into the VM from `contrib` , but that's not as easy to setup.
Copying files
-------------
2016-10-22 16:44:26 -07:00
The easiest way to do it is with a plugin.
2016-10-16 18:50:37 -07:00
vagrant plugin install vagrant-scp
To copy files to the VM: `vagrant scp file_on_host.txt :file_on_vm.txt`
To copy files from the VM: `vagrant scp :file_on_vm.txt file_on_host.txt`
Other notes
-----------
Port 2200 on the host machine should be forwarded to port 22 on the guest virtual machine.
The automation and configuration management assumes that VirtualBox will assign the IP address `10.0.2.15` to the Gitian host Vagrant VM.