├── .env.example
├── .envrc.example
├── .gitignore
├── README.md
├── Vagrantfile
├── ansible.cfg
├── doc
├── Debian_9.x.md
├── Ubuntu_18.04.x.md
└── macOS.md
├── docs
└── gpg_keys.md
├── forward_gpg_agent.sh
├── gitian.yml
├── local
└── README.md
├── requirements-pip.lock
└── roles
├── common
├── defaults
│ └── main.yml
├── files
│ ├── 02periodic
│ └── 50unattended-upgrades
├── handlers
│ └── main.yml
├── tasks
│ ├── add_github_ssh_hostkey.yml
│ ├── auto_upgrades.yml
│ ├── hostname.yml
│ ├── main.yml
│ ├── make_swap.yml
│ ├── motd.yml
│ ├── packages.yml
│ ├── repartition.yml
│ ├── update_everything.yml
│ └── vim.yml
└── templates
│ ├── log-core-dump.j2
│ └── motd.j2
└── gitian
├── defaults
└── main.yml
├── files
└── explode_yaml_file.py
├── meta
└── main.yml
├── tasks
├── gpg.yml
├── keys.yml
└── main.yml
└── templates
├── gitian-build.py
├── gitian-lxc
├── gpg.conf
├── lxc-net
├── profile
└── rc.local
/.env.example:
--------------------------------------------------------------------------------
1 | GPG_KEY_ID=3F14A629C06FA31D59C64FE93F0C2117D53A4A49
2 | GPG_KEY_NAME=hpotter
3 | AXE_GIT_REPO_URL=https://github.com/axerunners/axe
4 | AXE_VERSION=v1.5.0.1
5 |
--------------------------------------------------------------------------------
/.envrc.example:
--------------------------------------------------------------------------------
1 | source_up
2 | dotenv
3 |
4 | export GIT_NAME=`git config user.name`
5 | export GIT_EMAIL=`git config user.email`
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .env
2 | .envrc
3 | .vagrant/*
4 | *.swp
5 | gitian.sigs/*
6 | local/*
7 | !local/README.md
8 | axecore-binaries/*
9 | *.log
10 | .DS_Store
11 | *.sdk.tar.gz
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | AXE deterministic builds
2 | ==========================
3 |
4 |
5 |
6 | This is a deterministic build environment for [AXE](https://github.com/AXErunners/axe) that uses [Gitian](https://gitian.org/).
7 |
8 | Gitian provides a way to be reasonably certain that the AXE 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.
9 |
10 | 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.
11 |
12 | More independent Gitian builders are needed, which is why this guide exists.
13 |
14 | Requirements
15 | ------------
16 |
17 | 6GB of RAM, four cores.
18 |
19 | Note: This project uses VirtualBox to run a virtual machine. If you are running this inside a
20 | virtual machine, you'll likely need to enable a feature such as “nested virtualization”, “VT-x”, or
21 | similar in your virtualization software's settings for that virtual machine.
22 |
23 |
24 | Install Dependencies
25 | --------------------
26 |
27 | If you're using one of the following platforms, see the linked instructions for that platform:
28 |
29 | - [Debian 9.x](doc/Debian_9.x.md)
30 | - [Ubuntu 18.04.x](doc/Ubuntu_18.04.x.md)
31 | - [macOS](doc/macOS.md)
32 |
33 |
34 | If you're not using one of the platforms that we have specific instructions for, this is the list of
35 | dependencies we want. Please document the steps involved and we can add another platform to the list
36 | above!
37 |
38 | - [Git](https://git-scm.com/)
39 | - [VirtualBox](https://www.virtualbox.org/)
40 | - [Vagrant](https://www.vagrantup.com/) 2.0.3 or higher
41 | - [GnuPG](https://www.gnupg.org/) 2.x (2.11.18 or greater)
42 | - [Python](https://www.python.org/) 3.x (with `venv` support in case that is packaged separately)
43 | - [direnv](https://direnv.net/) (Optional/Recommended)
44 |
45 |
46 | Download Apple SDK
47 | ------------------
48 | [Apple SDK](https://github.com/AXErunners/axe/blob/master/doc/README_osx.md) required for macOS builds. Place this tarball (`MacOSX10.11.sdk.tar.gz`) into _axe-gitian_ folder and _Ansible_ will copy it during the run.
49 |
50 |
51 | ## Configure git
52 |
53 | We want a configuration file in the home directory of the account you'll be working in. This will
54 | determine how you are identified on the projects you contribute to. These settings can be overridden
55 | on a per-project basis.
56 |
57 | Git provides some convenient command options for setting this up:
58 |
59 | ```
60 | $ git config --global user.name "Harry Potter"
61 | $ git config --global user.email "hpotter@hogwarts.wiz"
62 | ```
63 |
64 | Checking that this worked:
65 |
66 | ```
67 | $ git config user.name
68 | Harry Potter
69 | $ git config user.email
70 | hpotter@hogwarts.wiz
71 | ```
72 |
73 | This is all the git configuration needed for the steps below, but here is a good reference for
74 | further reading on configuring git:
75 |
76 | https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration
77 |
78 |
79 |
80 | ## Decide on an ssh keypair to use when uploading build signatures to github
81 |
82 | You can generate a keypair specifically for connecting to github like this:
83 |
84 | ```
85 | $ ssh-keygen -t ed25519 -C "hpotter@hogwarts.wiz" -f ~/.ssh/github_id_rsa -N ''
86 | Generating public/private ed25519 key pair.
87 | Your identification has been saved in /Users/hpotter/.ssh/github_id_rsa.
88 | Your public key has been saved in /Users/hpotter/.ssh/github_id_rsa.pub.
89 | The key fingerprint is:
90 | SHA256:qBCOybcJkgs1xdNoocYlsZz3jNQhGgOymreQAQRyh0c hpotter@hogwarts.wiz
91 | The key's randomart image is:
92 | +--[ED25519 256]--+
93 | |Oo*=E+. |
94 | |+=.%*o.. |
95 | |o %oo.. |
96 | |o@ = + . |
97 | |@o+.. + S |
98 | |o+ooo. |
99 | |. .o. |
100 | | |
101 | | |
102 | +----[SHA256]-----+
103 | ```
104 |
105 | Some explanation of the arguments used in the above example:
106 |
107 | ```
108 | -t ed25519 Use a key type of ed25519
109 |
110 | -C "hpotter@hogwarts.wiz" Provide an identity to associate with the key (default is
111 | user@host in the local environment)
112 |
113 | -f ~/.ssh/github_id_rsa Path to the private key to generate. The corresponding public key
114 | will be saved at ~/.ssh/github_id_rsa.pub
115 |
116 | -N '' Passphrase for the generated key. An empty string as shown here
117 | means save the private key unencrypted.
118 | ```
119 |
120 |
121 |
122 | # Set up your ssh keypair for use with github
123 |
124 | [Add the new key to your github account.](https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/)
125 |
126 | Add an entry to `~/.ssh/config` (create this file if necessary) telling ssh to use the keypair you
127 | generated above when connecting to github.com.
128 |
129 |
130 | For instance:
131 |
132 | ```
133 | Host github.com
134 | User harrypotter
135 | PreferredAuthentications publickey
136 | IdentityFile /home/hpotter/.ssh/github_id_rsa
137 | AddKeysToAgent yes
138 | ```
139 |
140 | The 'User' entry should match your github username.
141 |
142 | If using macOS, the IdentityFile path will be:
143 |
144 | ```
145 | /Users/yourusername/.ssh/github_id_rsa
146 | ```
147 |
148 | If you do generate a new ssh config file you'll need to set its permission bits appropriately. On
149 | a Unix system you may do so with a command like this:
150 |
151 | ```
152 | chmod 400 ~/.ssh/config
153 | ```
154 |
155 | Test that ssh will successfully use your new key to connect to github.
156 |
157 | ```
158 | $ ssh -T git@github.com
159 | The authenticity of host 'github.com (192.30.253.112)' can't be established.
160 | RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
161 | Are you sure you want to continue connecting (yes/no)? yes
162 | Warning: Permanently added 'github.com,192.30.253.112' (RSA) to the list of known hosts.
163 | Hi harrypotter! You've successfully authenticated, but GitHub does not provide shell access.
164 | $
165 | ```
166 |
167 |
168 |
169 | ## Clone this git project on your machine
170 |
171 | From a location where you want to place your local clone of this repository (e.g. `~/Projects`). If
172 | there's a possibility you'll want to make and contribute changes, consider forking the repository
173 | and cloning from your fork. For example:
174 |
175 | ```
176 | git clone git@github.com:harrypotter/axe-gitian.git
177 | ```
178 |
179 | cd into the project repo
180 |
181 | ```
182 | $ cd axe-gitian
183 | axe-gitian
184 | ```
185 |
186 |
187 | ## Copy example environment configuration files
188 |
189 | The files `.env.example` and `.envrc.example` are tracked in the repo as example configurations you
190 | should be able to use to get started. The filenames `.env` and `.envrc` are `.gitignore`'d to allow
191 | you to easily make local customizations that don't show up as untracked changes.
192 |
193 | Note that `.envrc` is probably only useful if you are using `direnv`. If you're not, you can ignore
194 | that file and the places below that talk about it, and use your preferred way of managing
195 | environment variables instead.
196 |
197 | ```
198 | axe-gitian$ cp .env.example .env
199 | axe-gitian$ cp .envrc.example .envrc
200 | direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
201 | axe-gitian$
202 | ```
203 |
204 | More on that above message in the following section...
205 |
206 |
207 |
208 | ## Enable auto-execution of .envrc
209 |
210 | If you installed and activated `direnv`, it will detect when `.envrc` is created in your current
211 | directory, as shown above. As a security precaution, it won't automatically run it without your
212 | approval (to prevent untrusted code from doing something malicious). Let's take a look at what's in
213 | the file:
214 |
215 | ```
216 | axe-gitian$ cat .envrc
217 | source_up
218 | dotenv
219 |
220 | export GIT_NAME=`git config user.name`
221 | export GIT_EMAIL=`git config user.email`
222 | direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
223 | axe-gitian$
224 | ```
225 |
226 | Some explanation of the lines in the above `.envrc` file:
227 |
228 | ```
229 | `source_up` Load any .envrc higher up in the folder structure. So if for
230 | example you place an `.envrc` in your home directory, variables
231 | set there will still be available within this project, rather
232 | than being overridden by this project's `.envrc`.
233 |
234 | `dotenv` Set the environment variables defined in `.env`. Think of
235 | `.envrc` as code (it runs in a bash interpreter with some extra
236 | functions added) and `.env` as data (you can basically just set
237 | literal values, and each update to it doesn't require approval).
238 |
239 |
240 | export GIT_NAME=`git config user.name`
241 | export GIT_EMAIL=`git config user.email`
242 |
243 | Use your local git configuration values for the name and email
244 | that will be used to add build signatures inside the virtual
245 | environment.
246 | ```
247 |
248 |
249 | If you're ok with running `.envrc`, follow the directions in the prompt to allow it.
250 |
251 | ```
252 | axe-gitian$ echo $AXE_GIT_REPO_URL
253 |
254 | direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
255 | axe-gitian$ direnv allow
256 | direnv: loading .envrc
257 | direnv: export +GIT_EMAIL +GIT_NAME +GPG_KEY_ID +GPG_KEY_NAME +AXE_GIT_REPO_URL +AXE_VERSION
258 | axe-gitian$ echo $AXE_GIT_REPO_URL
259 | https://github.com/axerunners/axe
260 | axe-gitian$
261 | ```
262 |
263 | A variable defined in `.env` is now active in our environment. If we leave this project, it is
264 | unloaded. When we return, it is reloaded:
265 |
266 | ```
267 | axe-gitian$ cd ..
268 | direnv: unloading
269 | $ echo $AXE_GIT_REPO_URL
270 |
271 | $ cd axe-gitian/
272 | direnv: loading .envrc
273 | direnv: export +GIT_EMAIL +GIT_NAME +GPG_KEY_ID +GPG_KEY_NAME +AXE_GIT_REPO_URL +AXE_VERSION
274 | axe-gitian$ echo $AXE_GIT_REPO_URL
275 | https://github.com/axerunners/axe
276 | axe-gitian$
277 | ```
278 |
279 | Project-specific environment settings will come in handy in the next step, when we'll create an
280 | isolated python virtual environment specifically for use with this project.
281 |
282 |
283 |
284 | ## Create a python virtual environment for this project
285 |
286 | Note: The main purpose of this part is to get a current version of ansible, and keep it locally
287 | within this project. If you already installed ansible (e.g. from an OS package manager like apt),
288 | you can skip this part and the following parts about pip and pip packages.
289 |
290 | When creating a virtual environment, call the python executable you want the virtual environment to
291 | use. The location and version will depend on your specific setup -- your OS may provide a suitably
292 | current python interpreter, or you may have built and installed one yourself. If it's in your PATH,
293 | a command like `type python3` should tell you where it is installed on your system. For example:
294 |
295 | ```
296 | axe-gitian$ type python3
297 | python3 is /usr/local/bin/python3
298 | axe-gitian$ /usr/local/python3 --version
299 | Python 3.7.4
300 | ```
301 |
302 | You may also want to check if the `python3` in `PATH` is a symlink to a versioned location, if you
303 | are using a system (like `brew`) that can manage multiple installed versions. This way, our virtual
304 | environment will remain pinned to a specific python version even after a newer python version is
305 | installed later.
306 |
307 | ```
308 | $ ls -n /usr/local/bin/python3
309 | lrwxr-xr-x 1 501 20 34 Mar 30 09:35 /usr/local/bin/python3 -> ../Cellar/python/3.7.4/bin/python3
310 | ```
311 |
312 | We can use python's built-in `venv` module to create a virtual environment:
313 |
314 | ```
315 | axe-gitian$ /usr/local/Cellar/python/3.7.4/bin/python3 -m venv local/python_v3.7.4_venv
316 | ```
317 |
318 | Translation: "Create a virtual environment at ./local/python_v3.7.4_venv".
319 |
320 | The project subdirectory `local` is `.gitignored` to provide a convenient location for files we
321 | don't want to commit and track in version control.
322 |
323 | You should now have a tree of directories and files in `local/python_v3.7.4_venv`:
324 |
325 | ```
326 | axe-gitian$ ls -F local/python_v3.7.4_venv/
327 | bin/ include/ lib/ pyvenv.cfg
328 | ```
329 |
330 | Inside the `bin` directory, among other things, are the entries `python` and `python3`, which are
331 | symlinks that point back to the `python3` executable we used to create this environment:
332 |
333 | ```
334 | axe-gitian$ ls -F local/python_v3.7.4_venv/bin/
335 | activate activate.fish easy_install-3.7* pip3* python@
336 | activate.csh easy_install* pip* pip3.7* python3@
337 | ```
338 |
339 | A python virtual environment is 'active' if the python interpreter being executed is run from its
340 | path inside the environment's `bin` directory. Even though the file being executed is the same
341 | whether run directly or via a symlink, it pays attention to the path of the command that was used to
342 | run it.
343 |
344 | An `activate` script is provided, and you can use that, but if you're using `direnv` you can set up
345 | a simple automatic activation for the project directory by adding the following line to `.envrc`:
346 |
347 | ```
348 | load_prefix local/python_v3.7.4_venv
349 | ```
350 |
351 | The command `load_prefix` is provided by `direnv` to modify a whole set of common "path" variables
352 | (including PATH) according to a common unix pattern.
353 |
354 | Let's add that line now:
355 |
356 | ```
357 | axe-gitian$ echo "load_prefix local/python_v3.7.4_venv" >> .envrc
358 | direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
359 | axe-gitian$ direnv allow
360 | direnv: loading .envrc
361 | direnv: export +CPATH +GIT_EMAIL +GIT_NAME +GPG_KEY_ID +GPG_KEY_NAME +LD_LIBRARY_PATH +LIBRARY_PATH +MANPATH +PKG_CONFIG_PATH +AXE_GIT_REPO_URL +AXE_VERSION ~PATH
362 | axe-gitian$
363 | ```
364 |
365 | When the content of `.envrc` is changed, it needs to be approved again (another security
366 | precaution). Then, several variables were set or updated to add paths within our virtual environment
367 | directory at the front (left side) of the list. Let's look at PATH and its effect on which `python`
368 | locations we default to:
369 |
370 | ```
371 | axe-gitian$ echo $PATH
372 | /Users/harrypotter/Projects/axe-gitian/local/python_v3.7.4_venv/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
373 | axe-gitian$ type python
374 | python is /Users/harrypotter/Projects/axe-gitian/local/python_v3.7.4_venv/bin/python
375 | axe-gitian$ type python3
376 | python3 is /Users/harrypotter/Projects/axe-gitian/local/python_v3.7.4_venv/bin/python3
377 | ```
378 |
379 | Since the `python` and `python3` commands will now run from the locations we've installed into our
380 | project's virtual environment while we are in the project directory, we can consider the virtual
381 | environment active when using a shell at (or below) that location.
382 |
383 |
384 |
385 | ## Upgrade pip
386 |
387 | `pip3` has a command to upgrade itself. Let's go ahead and run that:
388 |
389 | ```
390 | axe-gitian % pip3 install --upgrade pip
391 | Collecting pip
392 | [...]
393 | Successfully uninstalled pip-20.1.1
394 | Successfully installed pip-20.2.4
395 | ```
396 |
397 |
398 |
399 | ## Install pip packages
400 |
401 | We have some dependencies to install as python packages, using the pip package manager installed
402 | above. The set we need, with version numbers managed via git, is in `requirements-pip.lock`; we can
403 | run `pip3 install` with that file as input:
404 |
405 | ```
406 | axe-gitian$ pip3 install --requirement requirements-pip.lock
407 | ```
408 |
409 | Check that you can run `ansible` from the command line:
410 |
411 | ```
412 | axe-gitian % ansible --version
413 | ansible 2.10.2
414 | [...]
415 | axe-gitian %
416 | ```
417 |
418 |
419 |
420 | ## Decide on a gpg keypair to use for gitian
421 |
422 | You can generate a keypair specifically for axe gitian builds with a command like the one below.
423 |
424 |
425 | ```
426 | axe-gitian$ gpg --quick-generate-key --batch --passphrase '' "Harry Potter (axe gitian) "
427 | gpg: key 3F0C2117D53A4A49 marked as ultimately trusted
428 | gpg: directory '/home/hpotter/.gnupg/openpgp-revocs.d' created
429 | gpg: revocation certificate stored as '/home/hpotter/.gnupg/openpgp-revocs.d/3F14A629C06FA31D59C64FE93F0C2117D53A4A49.rev'
430 | ```
431 |
432 | Some explanation of the arguments used in the above example:
433 |
434 | --quick-generate-key --batch This combination of options allows options to be given on the
435 | command line. Other key generation options use interative
436 | prompts.
437 |
438 | --passphrase '' Passphrase for the generated key. An empty string as shown here
439 | means save the private key unencrypted.
440 |
441 | "Name (Comment) " The user id (also called uid) to associate with the generated
442 | keys. Concatenating a name, an optional comment, and an email
443 | address using this format is a gpg convention.
444 |
445 |
446 | You can check that the key was generated and added to your local gpg key database, and see its
447 | fingerprint value, like this:
448 | ```
449 | axe-gitian$ gpg --list-keys
450 | /home/hpotter/.gnupg/pubring.kbx
451 | ----------------------------------
452 | pub rsa2048 2018-04-23 [SC] [expires: 2020-04-22]
453 | 3F14A629C06FA31D59C64FE93F0C2117D53A4A49
454 | uid [ultimate] Harry Potter (axe gitian)
455 | sub rsa2048 2018-04-23 [E]
456 | ```
457 |
458 | Update your `GPG_KEY_ID` and `GPG_KEY_NAME` variables in `.env` as follows:
459 |
460 | - `GPG_KEY_ID`: In the example output shown here, this is the 40 character string
461 | `3F14A629C06FA31D59C64FE93F0C2117D53A4A49`. Some versions of gpg may truncate this value, e.g. to 8
462 | or 16 characters. You should be able to use the truncated value.
463 |
464 | - `GPG_KEY_NAME`: This is passed as the '--signer' argument to Gitian, and used as the name of a
465 | directory for your signatures in our `gitian.sigs` repository. We suggest using the username portion
466 | of the email address associated with your GPG key. In our example this is `hpotter`.
467 |
468 | For more info about updating or revoking gpg keys, see [Notes on updating or revoking GPG keys](docs/gpg_keys.md)
469 |
470 |
471 | ## Install Vagrant plugins
472 |
473 | This project uses some 3rd party Vagrant plugins. These dependencies are specified in `Vagrantfile`.
474 | We can install them locally in the `.vagrant` directory with the following command:
475 |
476 | ```
477 | axe-gitian$ vagrant plugin install --local
478 | ```
479 |
480 |
481 |
482 | ## Configure the version of axe you want to build and sign
483 |
484 | Set the value of the `AXE_VERSION` variable in `.env` to point to the axe commit you want to
485 | create a signature for. Likely you want the name of a
486 | [git-tagged axe version](https://github.com/axerunners/axe/tags), usually the most recent released
487 | version.
488 |
489 | ## Provision a virtual machine
490 |
491 | From the project root directory, run:
492 |
493 | ```
494 | axe-gitian$ vagrant up axe-build
495 | ```
496 |
497 | This will provision a Gitian host virtual machine that uses a Linux container (LXC/Docker) guest to perform
498 | the actual builds.
499 |
500 |
501 | Load your ssh key into ssh-agent
502 | --------------------------------
503 |
504 | Load your ssh key (for pushing signatures to github) into ssh-agent. The approach here is to allow
505 | programs in the axe-build VM to connect to ssh-agent to perform operations with the private key.
506 | This way, we don't need to copy ssh keys into the VM.
507 |
508 | If you don't already have an ssh-agent running you may need to start one. For example, you might be
509 | able to start one like this:
510 |
511 | ```
512 | eval `ssh-agent -s`
513 | ```
514 |
515 | You can verify that the key is loaded by
516 | running `ssh-add -l`.
517 |
518 | ```
519 | axe-gitian$ ssh-add -l
520 | The agent has no identities.
521 |
522 | axe-gitian$ ssh-add ~/.ssh/github_id_rsa
523 | Identity added: /home/hpotter/.ssh/github_id_rsa (/home/hpotter/.ssh/github_id_rsa)
524 |
525 | axe-gitian$ ssh-add -l
526 | 4096 SHA256:4fFdwJ71VIpF5cW0dqrsU7jxjctaFcAKmdQZPEqR0Y4 /home/hpotter/.ssh/github_id_rsa (RSA)
527 | ```
528 |
529 |
530 | SSH into the VM
531 | ---------------
532 |
533 | Vagrant should now show that the new VM is in the 'running' state:
534 |
535 | ```
536 | axe-gitian$ vagrant status
537 | Current machine states:
538 |
539 | axe-build running (virtualbox)
540 |
541 | The VM is running. To stop this VM, you can run `vagrant halt` to
542 | shut it down forcefully, or you can run `vagrant suspend` to simply
543 | suspend the virtual machine. In either case, to restart it again,
544 | simply run `vagrant up`.
545 | ```
546 |
547 | Use the `vagrant ssh` command to start a shell session in the VM. Once in that session, you can use
548 | ssh-add again to see that your forwarded key is available, and check that you can use that key to
549 | authenticate to github.
550 |
551 | ```
552 | axe-gitian$ vagrant ssh axe-build
553 | [...]
554 |
555 | # on the virtualbox vm
556 | vagrant@axe-build:~$ ssh-add -l
557 | 4096 d1:43:75:a7:95:65:9e:d4:8e:57:d8:98:58:7d:92:4c /home/hpotter/.ssh/github_id_rsa (RSA)
558 |
559 | vagrant@axe-build:~$ ssh -T git@github.com
560 | Warning: Permanently added the RSA host key for IP address '192.30.253.112' to the list of known hosts.
561 | Hi harrypotter! You've successfully authenticated, but GitHub does not provide shell access.
562 | ```
563 |
564 |
565 | Building AXE
566 | --------------
567 |
568 | Once in a shell session in the VM, we're ready to run the gitian build.
569 |
570 | ```
571 | # on the virtualbox vm
572 | # replace $SIGNER and $VERSION with your key and target version/branch/commit
573 | vagrant@axe-build:~$ ./gitian-build.py --setup $SIGNER $VERSION
574 | vagrant@axe-build:~$ ./gitian-build.py -b $SIGNER $VERSION # will start the build with unsigned output
575 | ```
576 |
577 | 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.
578 |
579 | Take a look at the variables of `~/gitian-build.py` and get familiar with its functioning, as it can handle most tasks.
580 |
581 | 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.
582 |
583 | Generating and uploading signatures
584 | -----------------------------------
585 |
586 | Signatures can be verified by running `gitian-build.py --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 Axe 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 AXE source repository.
587 |
588 | After the build successfully completes, the gitian command `gsign` will be called, which will
589 | generate signatures, and a commit will be added.
590 |
591 | Fork the [axerunners/gitian.sigs](https://github.com/axerunners/gitian.sigs) repository by following the link
592 | and clicking "fork".
593 |
594 | Now you can cd into the gitian.sigs directory, set the repository to point to your fork of
595 | [axerunners/gitian.sigs](https://github.com/axerunners/gitian.sigs), push
596 | your updates to a branch, and then make a pull request on github.
597 |
598 | ```
599 | cd gitian.sigs
600 | git remote rename origin upstream
601 | git remote add origin git@github.com:harrypotter/gitian.sigs.git
602 | git checkout -b v1.5.0.0
603 | git push origin v1.5.0.0
604 | ```
605 |
606 |
607 | Working with GPG
608 | ----------------
609 |
610 | We provide two options for automatically importing keys into the VM, or you may choose to copy them manually. GPG keys are needed to sign the manifests which get pushed to [gitian.sigs](https://github.com/axerunners/gitian.sigs).
611 |
612 | GPG is tricky, 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:
613 |
614 | vagrant plugin install vagrant-sshfs
615 |
616 | Uncomment the line beginning with `gitian.vm.synced_folder "~/.gnupg"` in `Vagrantfile`. Ensure the destination mount point is empty. Then run:
617 |
618 | vagrant sshfs --mount axe-build
619 |
620 | 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.
621 |
622 |
623 | Copying files
624 | -------------
625 |
626 | To copy files to the VM: `vagrant scp file_on_host.txt :file_on_vm.txt`
627 |
628 | To copy files from the VM: `vagrant scp :file_on_vm.txt file_on_host.txt`
629 |
630 | Other notes
631 | -----------
632 |
633 | Port 2200 on the host machine should be forwarded to port 22 on the guest virtual machine.
634 |
635 | The automation and configuration management assumes that VirtualBox will assign the IP address `10.0.2.15` to the Gitian host Vagrant VM.
636 |
--------------------------------------------------------------------------------
/Vagrantfile:
--------------------------------------------------------------------------------
1 | # -*- mode: ruby -*-
2 | # vi: set ft=ruby :
3 | Vagrant.configure(2) do |config|
4 |
5 | config.vagrant.plugins = {
6 | "vagrant-disksize" => {"version" => "0.1.3"},
7 | "vagrant-scp" => {"version" => "0.5.7"}
8 | }
9 |
10 | config.ssh.forward_agent = true
11 | config.disksize.size = '24GB'
12 | config.vm.define 'axe-build', autostart: false do |gitian|
13 | gitian.vm.box = "debian/stretch64"
14 | gitian.vm.box_version = "9.12.0"
15 | gitian.vm.network "forwarded_port", guest: 22, host: 2200, auto_correct: true
16 | gitian.vm.provision "ansible" do |ansible|
17 | ansible.playbook = "gitian.yml"
18 | ansible.verbose = 'vvv'
19 | ansible.raw_arguments = Shellwords.shellsplit(ENV['ANSIBLE_ARGS']) if ENV['ANSIBLE_ARGS']
20 | end
21 | gitian.vm.provider "virtualbox" do |v|
22 | v.name = "axe-build"
23 | v.memory = 4096
24 | v.cpus = 2
25 | end
26 | # gitian.vm.synced_folder "~/.gnupg", "/home/vagrant/.gnupg", type: "sshfs"
27 | # gitian.vm.synced_folder "./gitian.sigs", "/home/vagrant/gitian.sigs", create: true
28 | # gitian.vm.synced_folder "./axecore-binaries", "/home/vagrant/axecore-binaries", create: true
29 | gitian.vm.post_up_message = "AXE deterministic build environment started."
30 | end
31 |
32 | end
33 |
--------------------------------------------------------------------------------
/ansible.cfg:
--------------------------------------------------------------------------------
1 | [defaults]
2 | inventory = inventory
3 | retry_files_enabled = False
4 | roles_path = roles
5 | host_key_checking = False
6 | timeout = 60
7 |
8 | [ssh_connection]
9 | ssh_args = -o ControlMaster=auto -o ControlPersist=300s -o ConnectTimeout=60 -o IdentitiesOnly=yes
10 | pipelining = True
11 | scp_if_ssh = True
12 |
--------------------------------------------------------------------------------
/doc/Debian_9.x.md:
--------------------------------------------------------------------------------
1 | # Dependency installation steps for Debian GNU/Linux 9.x (stretch)
2 |
3 | This document assumes you are starting from a fresh install of Debian in the 9.x series.
4 |
5 | Most recently tested 2019-03-21 with the following debian release:
6 |
7 | ```
8 | $ lsb_release --description
9 | Description: Debian GNU/Linux 9.8 (stretch)
10 | ```
11 |
12 |
13 |
14 | # Install VirtualBox
15 |
16 | Virtualbox is the configured VM provider in this project's Vagrantfile.
17 |
18 | First, check whether virtualbox is installed. Some systems may have it already:
19 |
20 | ```
21 | $ virtualbox --help
22 | Oracle VM VirtualBox VM Selector v6.0.4
23 | [...]
24 | ```
25 |
26 | (If it is installed, you can probably skip this step. Note that virtualbox installs linux kernel
27 | modules which need to be kept in sync with the virtualbox apt package, so if you decide to change to
28 | a different version, be sure to uninstall completely (including the kernel modules) before
29 | reinstalling.)
30 |
31 | Add Oracle's VirtualBox apt repository to your system's apt sources:
32 |
33 | ```
34 | sudo apt-add-repository "deb http://download.virtualbox.org/virtualbox/debian $(lsb_release -sc) contrib"
35 | ```
36 |
37 | Verify that the source was added:
38 |
39 | ```
40 | $ grep -iR virtualbox /etc/apt/sources.list*
41 | /etc/apt/sources.list:deb http://download.virtualbox.org/virtualbox/debian stretch contrib
42 | /etc/apt/sources.list:# deb-src http://download.virtualbox.org/virtualbox/debian stretch contrib
43 | ```
44 |
45 | Download and register the public gpg key used by Oracle to secure the above
46 | repository:
47 |
48 | ```
49 | $ wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add -
50 | OK
51 | ```
52 |
53 | Verify that the key was added
54 |
55 | ```
56 | $ apt-key list "B9F8 D658 297A F3EF C18D 5CDF A2F6 83C5 2980 AECF"
57 | pub rsa4096 2016-04-22 [SC]
58 | B9F8 D658 297A F3EF C18D 5CDF A2F6 83C5 2980 AECF
59 | uid [ unknown] Oracle Corporation (VirtualBox archive signing key)
60 | sub rsa4096 2016-04-22 [E]
61 | ```
62 |
63 | Update your local apt package metadata
64 |
65 | ```
66 | $ sudo apt update
67 | [...]
68 | ```
69 |
70 | This command will show the available versions of virtualbox from the apt
71 | repository:
72 |
73 | ```
74 | $ sudo apt install virtualbox
75 | Reading package lists... Done
76 | Building dependency tree
77 | Reading state information... Done
78 | Package virtualbox is a virtual package provided by:
79 | virtualbox-6.0 6.0.4-128413~Debian~stretch
80 | virtualbox-5.2 5.2.26-128414~Debian~stretch
81 | virtualbox-5.1 5.1.38-122592~Debian~stretch
82 | virtualbox-5.0 5.0.40-115130~Debian~stretch
83 | You should explicitly select one to install.
84 |
85 | E: Package 'virtualbox' has no installation candidate
86 | ```
87 |
88 | Decide on the version you want and specify the version number to install it:
89 |
90 | ```
91 | $ sudo apt install virtualbox-6.0 -y
92 | [...]
93 | ```
94 |
95 | Source: https://www.virtualbox.org/wiki/Linux_Downloads#Debian-basedLinuxdistributions
96 |
97 | Most recently tested 2019-03-21 with the following virtualbox release:
98 |
99 | ```
100 | $ virtualbox --help
101 | Oracle VM VirtualBox VM Selector v6.0.4
102 | [...]
103 | ```
104 |
105 |
106 |
107 | ## Install git
108 |
109 | ```
110 | $ sudo apt install git
111 | ```
112 |
113 | Most recently tested 2019-03-21 with the following git release:
114 |
115 | ```
116 | $ git --version
117 | git version 2.11.0
118 | ```
119 |
120 |
121 |
122 | # Install Vagrant 2.0.3 or higher
123 |
124 | As of this writing, the Vagrant version that Debian uses in its "stretch" release is 1.9.x so we
125 | suggest getting a package from Vagrant's web site:
126 |
127 | ```
128 | wget -c https://releases.hashicorp.com/vagrant/2.2.4/vagrant_2.2.4_x86_64.deb
129 | sudo dpkg -i vagrant_2.2.4_x86_64.deb
130 | rm vagrant_2.2.4_x86_64.deb
131 | ```
132 |
133 | Most recently tested 2019-03-21 with the following vagrant release:
134 |
135 | ```
136 | $ vagrant --version
137 | Vagrant 2.2.4
138 | ```
139 |
140 |
141 |
142 | # Install venv support
143 |
144 | `venv` is a python module used to create isolated project-specific environments, so that projects on
145 | the same computer can each use their own version of the python executable and their own set of
146 | installed python modules.
147 |
148 | `python3-venv` is an `apt` package that includes support for using the `venv` python module.
149 |
150 | ```
151 | sudo apt install python3-venv
152 | ```
153 |
154 | Most recently tested 2019-03-05 with the following python3-venv release:
155 |
156 | ```
157 | $ dpkg --status python3-venv | grep Version
158 | Version: 3.5.3-1
159 | ```
160 |
161 |
162 |
163 | # Install direnv (Optional/Recommended)
164 |
165 | This tool sets and unsets environment variables as you change directories in a shell session,
166 | providing a convenient facility for setting up project-specific configuration.
167 |
168 | ```
169 | sudo apt install direnv
170 | ```
171 |
172 | To activate direnv when starting bash (the default shell on Debian 9), add the following line to the
173 | end of `~/.bashrc`:
174 |
175 | ```
176 | eval "$(direnv hook bash)"
177 | ```
178 |
179 | direnv works by incorporating a call to `_direnv_hook` in the `PROMPT_COMMAND` shell variable. You
180 | can check that this was done by starting a new bash session and checking whether that value is
181 | present:
182 |
183 | ```
184 | $ echo $PROMPT_COMMAND
185 | _direnv_hook;
186 | ```
187 |
188 | direnv also supports several other shells -- zsh, fish, tcsh, and elvish as of this writing. Its
189 | website includes instructions for enabling each of the shells it supports.
190 |
191 | Most recently tested 2019-03-21 with the following direnv release:
192 |
193 | ```
194 | $ direnv --help
195 | direnv v2.10.0
196 | [...]
197 | ```
198 |
--------------------------------------------------------------------------------
/doc/Ubuntu_18.04.x.md:
--------------------------------------------------------------------------------
1 | # Dependency installation steps for Ubuntu 18.04.x LTS (Bionic Beaver)
2 |
3 | This document assumes you are starting from a fresh install of Ubuntu in the 18.04.x series.
4 |
5 |
6 | ## Install Git, VirtualBox, and rng-tools
7 |
8 | ```
9 | $ sudo apt install git virtualbox rng-tools
10 | ```
11 |
12 |
13 |
14 | # Install Vagrant 2.0.3 or higher
15 |
16 | As of this writing, the vagrant version that Ubuntu 18.04 uses is 2.0.2 so we suggest a later
17 | release in the 2.0.x series.
18 |
19 | ```
20 | wget -c https://releases.hashicorp.com/vagrant/2.2.4/vagrant_2.2.4_x86_64.deb
21 | sudo dpkg -i vagrant_2.2.4_x86_64.deb
22 | rm vagrant_2.2.4_x86_64.deb
23 | ```
24 |
25 | Most recently tested 2019-03-26 with the following vagrant release:
26 |
27 | ```
28 | $ vagrant --version
29 | Vagrant 2.2.4
30 | ```
31 |
32 |
33 |
34 | ## Choice: Install Ansible via apt now or pip later
35 |
36 | You can install ansible to a system-wide location using Ubuntu's apt tool, which will be a less
37 | current version, with infrequent updates, or choose another method described later to install it via
38 | a python package in a project-local virtual environment. The apt method is a bit easier, while the
39 | python method is ansible's native distribution channel and will be more current and more frequently
40 | updated.
41 |
42 | If you choose the apt option, run this command:
43 |
44 | ```
45 | $ sudo apt install ansible
46 | ```
47 |
48 | If you choose the python/pip option, run this command:
49 |
50 | ```
51 | $ sudo apt install python3-venv
52 | ```
53 |
54 |
55 |
56 | # Install direnv (Optional/Recommended)
57 |
58 | This tool sets and unsets environment variables as you change directories in a shell session,
59 | providing a convenient facility for setting up project-specific configuration.
60 |
61 | ```
62 | sudo apt install direnv
63 | ```
64 |
65 | To activate direnv when starting bash (the default shell on Ubuntu 18.04), add the following line to
66 | the end of `~/.bashrc`:
67 |
68 | ```
69 | eval "$(direnv hook bash)"
70 | ```
71 |
72 | direnv works by incorporating a call to `_direnv_hook` in the `PROMPT_COMMAND` shell variable. You
73 | can check that this was done by starting a new bash session and checking whether that value is
74 | present:
75 |
76 | ```
77 | $ echo $PROMPT_COMMAND
78 | _direnv_hook;
79 | ```
80 |
81 | direnv also supports several other shells -- zsh, fish, tcsh, and elvish as of this writing. Its
82 | website includes instructions for enabling each of the shells it supports.
83 |
84 |
85 |
86 | ## Headless notes
87 |
88 | Server instances should force GPG client to use TTY by adding following line in `~/.bashrc`:
89 |
90 | ```
91 | export GPG_TTY=$(tty)
92 | ```
93 |
94 |
95 |
96 | ## Versions
97 |
98 | Most recently tested 2018-03-26 with the following versions:
99 |
100 |
101 | ### Ubuntu
102 |
103 | ```
104 | $ lsb_release --description
105 | Description: Ubuntu 18.04 LTS
106 | ```
107 |
108 |
109 | ### Git
110 |
111 | ```
112 | $ git --version
113 | git version 2.17.1
114 | ```
115 |
116 |
117 | ### VirtualBox
118 |
119 | ```
120 | $ virtualbox --help
121 | Oracle VM VirtualBox Manager 5.2.18_Ubuntu
122 | ...
123 | ```
124 |
125 |
126 | ### Ansible
127 |
128 | ```
129 | $ ansible --version
130 | ansible 2.5.1
131 | [...]
132 | ```
133 |
134 |
135 | ### direnv
136 |
137 | ```
138 | $ direnv --help
139 | direnv v2.15.0
140 | [...]
141 | ```
142 |
--------------------------------------------------------------------------------
/doc/macOS.md:
--------------------------------------------------------------------------------
1 | # Dependency installation steps for macOS
2 |
3 | This document assumes you are starting from a fresh install of macOS.
4 |
5 | Most recently tested 2020-10-28 with the following macOS release:
6 |
7 | ```
8 | % sw_vers
9 | ProductName: Mac OS X
10 | ProductVersion: 10.15.7
11 | BuildVersion: 19H2
12 | ```
13 |
14 |
15 |
16 | ## Make sure Git is installed
17 |
18 | macOS includes git, so you should already have that. It may prompt you to set up developer tools if
19 | you're using it for the first time.
20 |
21 | Most recently tested 2020-10-28 with the following git release:
22 |
23 | ```
24 | % git --version
25 | git version 2.21.0 (Apple Git-122)
26 | ```
27 |
28 |
29 |
30 | ## Install Homebrew
31 |
32 | Homebrew's site gives a shell command to download and install it
33 | https://brew.sh/
34 |
35 | To update both the installed homebrew version and its list of formulae:
36 |
37 | ```
38 | % brew update
39 | ```
40 |
41 | To upgrade software installed via brew:
42 |
43 | ```
44 | $ brew upgrade
45 | ```
46 |
47 | Homebrew has a search page you can use to look up formula names: http://formulae.brew.sh/
48 |
49 | Most recently tested 2020-10-28 with the following Homebrew release:
50 |
51 | ```
52 | % brew --version
53 | Homebrew 2.5.7
54 | Homebrew/homebrew-core (git revision 8a3edd; last commit 2020-10-28)
55 | Homebrew/homebrew-cask (git revision 98c84; last commit 2020-10-28)
56 | ```
57 |
58 | That last line about "homebrew-cask" refers to a subcommand 'cask' that can manage the types of
59 | installs mac users ordinarily do manually - the "drag to the applications folder" type and the "run
60 | an installer" type.
61 |
62 | We'll use both "brew" and "brew cask" install methods in the steps below.
63 |
64 |
65 |
66 | ## Install Virtualbox
67 |
68 | This one may fail on the first attempt with a prompt to allow software signed by Oracle. After doing
69 | that, the second attempt should succeed.
70 |
71 | ```
72 | $ brew cask install virtualbox
73 | ```
74 |
75 | Most recently tested 2020-10-28 with the following Virtualbox release:
76 |
77 | ```
78 | % VBoxManage --version
79 | 6.0.15r135660
80 | ```
81 |
82 |
83 |
84 | ## Install Vagrant
85 |
86 | ```
87 | $ brew cask install vagrant
88 | ```
89 |
90 | Most recently tested 2020-10-28 with the following Vagrant release:
91 |
92 | ```
93 | % vagrant --version
94 | Vagrant 2.2.7
95 | ```
96 |
97 |
98 |
99 | ## Install GnuPG 2.x (2.11.18 or greater)
100 |
101 | ```
102 | $ brew install gnupg
103 | ```
104 |
105 | Most recently tested 2020-10-28 with the following GnuPG release:
106 |
107 | ```
108 | % gpg --version
109 | gpg (GnuPG) 2.2.20
110 | libgcrypt 1.8.5
111 | [...]
112 | ```
113 |
114 |
115 |
116 | ## Install Python 3.x
117 |
118 | As of this writing, python 3.7.3 is installed by default in macOS, which should work fine. You can
119 | optionally install the 'python' homebrew package to get a later version.
120 |
121 | ```
122 | $ brew install python
123 | ```
124 |
125 | Note that to run python 3.x you need to use the name `python3`; running `python` will run python
126 | 2.x.
127 |
128 | Most recently tested 2020-10-28 with the following Python release:
129 |
130 | ```
131 | % python3 --version
132 | Python 3.8.2
133 | ```
134 |
135 |
136 |
137 | # Install direnv (Optional/Recommended)
138 |
139 | This tool sets and unsets environment variables as you change directories in a shell session,
140 | providing a convenient facility for setting up project-specific configuration.
141 |
142 | ```
143 | brew install direnv
144 | ```
145 |
146 | To activate direnv when starting bash (the default shell on macOS), add the following line to the
147 | end of `~/.profile`:
148 |
149 | ```
150 | eval "$(direnv hook bash)"
151 | ```
152 |
153 | direnv works by incorporating a call to `_direnv_hook` in the `PROMPT_COMMAND` shell variable. You
154 | can check that this was done by starting a new bash session and checking whether that value is
155 | present:
156 |
157 | ```
158 | $ echo $PROMPT_COMMAND
159 | _direnv_hook;[...]
160 | ```
161 |
162 | direnv also supports several other shells -- zsh, fish, tcsh, and elvish as of this writing. Its
163 | website includes instructions for enabling each of the shells it supports.
164 |
165 | Most recently tested 2020-10-28 with the following direnv release:
166 |
167 | ```
168 | % direnv --version
169 | 2.23.1
170 | ```
171 |
--------------------------------------------------------------------------------
/docs/gpg_keys.md:
--------------------------------------------------------------------------------
1 | Notes on updating or revoking GPG keys
2 |
3 | First a note about terminology. A potentially confusing thing with GPG is the overloaded meanings of terms. It is probably helpful to state up front that this system operates on collections of associated identities and credentials. Often an entire such collection is referred to as a 'key' or a 'keypair', while keys inside the collection are also called keys and keypairs. Here I'll try and say "key bundle" when referring to the whole collection, but you probably won't see that term used elsewhere in the worlds of GPG and PGP.
4 |
5 | A key bundle consists of:
6 | - A 'master' or 'primary' keypair (private + public key)
7 | - Zero or more 'subordinate keypairs', often shortened to 'subordinate keys' or 'subkeys'.
8 | - Zero or more 'user ids' (strings of the form "FirstName LastName (comment) ")
9 | - Zero or more key signatures
10 | - For example, a signature by the private primary key of the public primary key
11 | ...or cross-signatures in both directions between the primary keypair and subordinate keypairs
12 | ...or signatures on the user ids by the primary private key
13 | - Zero or more 'revocation certificates', revoking any of the signatures mentioned above
14 |
15 | When publishing or retrieving something to or from the key server network, these key bundles are the units you are working with. Publishing a key bundle is a create/update operation. In the 'update' case the key bundle gets merged with older copies of that key bundle. A merge operation will combine fields from the key bundles being merged.
16 |
17 | It is possible to delete pieces from a key bundle, but that is probably not what you want, since they might well reappear after the updated key is published and merged throughout the key server network. Instead, add a revocation for the thing you might have wanted to remove.
18 |
19 |
20 | - Publish a key bundle to the key server network
21 | gpg --send-keys (fingerprint)
22 | - Then we want clients to get the updated key bundle
23 | - For clients using gpg directly that might be done with:
24 | gpg --refresh-keys
25 | - For clients using gpg via apt that might be done with:
26 | sudo apt-key adv --refresh-keys
27 |
28 | - If a subkey expires
29 | - Use master key to generate a new subkey
30 | gpg --edit-key (fingerprint) gives a prompt; then use 'addkey' subcommand at prompt
31 | - subkey is added to key bundle
32 | - See 'Publish a key bundle to the key server network' above
33 |
34 | - If a subkey is compromised
35 | - Use master key to generate a revocation certificate for that subkey
36 | gpg --edit-key (fingerprint) gives a prompt; then use 'revkey' subcommand at prompt
37 | - revocation certificate is added to key bundle
38 | - See 'Publish a key bundle to the key server network' above
39 |
40 | - Before master/primary key expires
41 | - Although GPG key bundles have expiration times, these can be extended using the private master key
42 | - It is probably helpful to know something about what's happening under the covers. The expiration time is associated with the 'self-signature' (of the public primary key by the private primary key). By adding a new self-signature to the key bundle with a later expiration date, clients with the updated bundle should honor the date on the newer self-signature rather than the older one.
43 | - This update can be performed with the following command:
44 | gpg --quick-set-expire (fingerprint) (new_expiration_time)
45 | - This should add that new self-signature described above to the bundle
46 | - See 'Publish a key bundle to the key server network' above
47 |
48 | - If master/primary key expires
49 | - Clients will now get validation errors since the expiration date is in the past. But the update process should be the same as 'before master/primary key expires'. Follow the same steps described there.
50 |
51 | - If master/primary key is compromised
52 | - Use master/primary key to generate a revocation certificate for itself
53 | gpg --generate-revocation (fingerprint) > revocation.cert
54 | - The revocation certificate is detached from the key bundle, in its own file. This step can be done ahead of time if desired, and the revocation certificate file kept in a safe place.
55 | - To add the revocation certificate to the key bundle:
56 | gpg --import revocation.cert
57 | - Your local gpg instance now considers the primary key revoked
58 | - See 'Publish a key bundle to the key server network' above to propagate the revocation to the rest of the world
59 |
--------------------------------------------------------------------------------
/forward_gpg_agent.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | GPG_SOCK=$(echo "$GPG_AGENT_INFO" | cut -d: -f1)
4 | if [ -z "$GPG_SOCK" ] ; then
5 | echo "No GPG agent configured - this won't work out." >&2
6 | exit 1
7 | fi
8 |
9 | vagrant ssh axe-build -- rm -f /home/vagrant/.gnupg/S.gpg-agent
10 | vagrant ssh axe-build -- -t \
11 | -R /home/vagrant/.gnupg/S.gpg-agent:$GPG_SOCK \
12 | -o StreamLocalBindUnlink=yes \
13 | -o ExitOnForwardFailure=yes
14 |
--------------------------------------------------------------------------------
/gitian.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Apply the AXE Gitian builder role.
3 | become: yes
4 | hosts: localhost:axe-build
5 | vars:
6 | axe_git_repo_url: "{{ lookup('env','AXE_GIT_REPO_URL') }}"
7 | axe_version: "{{ lookup('env','AXE_VERSION') }}"
8 | git_name: "{{ lookup('env','GIT_NAME') }}"
9 | git_email: "{{ lookup('env','GIT_EMAIL') }}"
10 | gpg_key_name: "{{ lookup('env','GPG_KEY_NAME') }}"
11 | gpg_key_id: "{{ lookup('env','GPG_KEY_ID') }}"
12 | roles:
13 | - role: common
14 | tags: common
15 | - role: gitian
16 | tags: gitian
17 |
--------------------------------------------------------------------------------
/local/README.md:
--------------------------------------------------------------------------------
1 | local/
2 | ======
3 |
4 | This directory is intended for content that is local to your work area, and
5 | not intended to be tracked by version control.
6 |
7 | This file is here to make git track the existence of this directory (git doesn't
8 | track empty directories).
9 |
--------------------------------------------------------------------------------
/requirements-pip.lock:
--------------------------------------------------------------------------------
1 | # Primary Dependencies
2 | # (Packages we actually decided to include)
3 | ansible==2.10.1
4 | # Secondary Dependencies
5 | # (pulled in by one or more of the above dependencies)
6 | ansible-base==2.10.2
7 | cffi==1.14.3
8 | cryptography==3.2.1
9 | Jinja2==2.11.2
10 | MarkupSafe==1.1.1
11 | packaging==20.4
12 | pycparser==2.20
13 | pyparsing==2.4.7
14 | PyYAML==5.3.1
15 | six==1.15.0
--------------------------------------------------------------------------------
/roles/common/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | axe_swapfile_size: 2G
3 | axe_vm_swappiness: 1
4 | axe_common_packages:
5 | - apt-show-versions
6 | - apt-transport-https
7 | - curl
8 | - git-core
9 | - haveged
10 | - htop
11 | - ntp
12 | - ntpdate
13 | - python-pip
14 | - rsync
15 | - screen
16 | - sudo
17 | - tmux
18 | - tree
19 | - vim
20 |
--------------------------------------------------------------------------------
/roles/common/files/02periodic:
--------------------------------------------------------------------------------
1 | APT::Periodic::Enable "1";
2 | APT::Periodic::Update-Package-Lists "1";
3 | APT::Periodic::Download-Upgradeable-Packages "1";
4 | APT::Periodic::Unattended-Upgrade "1";
5 | APT::Periodic::AutocleanInterval "7";
6 |
--------------------------------------------------------------------------------
/roles/common/files/50unattended-upgrades:
--------------------------------------------------------------------------------
1 | Unattended-Upgrade::Origins-Pattern {
2 | "o=Debian,n=stretch-updates";
3 | "o=Debian,n=stretch,l=Debian-Security";
4 | };
5 | Unattended-Upgrade::Remove-Unused-Dependencies "true";
6 | Unattended-Upgrade::Automatic-Reboot "false";
7 |
--------------------------------------------------------------------------------
/roles/common/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: update timezone
3 | command: dpkg-reconfigure --frontend noninteractive tzdata
4 |
--------------------------------------------------------------------------------
/roles/common/tasks/add_github_ssh_hostkey.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Look up GitHub SSH host key.
3 | local_action: command ssh-keyscan -t rsa github.com
4 | register: github_ssh_keyscan_result
5 | changed_when: false
6 | check_mode: no
7 | run_once: yes
8 | become: no
9 |
10 | - name: Ensure github.com is a known host.
11 | known_hosts:
12 | path: /etc/ssh/ssh_known_hosts
13 | name: github.com
14 | key: "{{ github_ssh_keyscan_result.stdout }}"
15 |
--------------------------------------------------------------------------------
/roles/common/tasks/auto_upgrades.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Copy unattended-upgrades configuration.
3 | copy:
4 | dest: /etc/apt/apt.conf.d/
5 | src: "{{ item }}"
6 | mode: "0640"
7 | owner: root
8 | group: root
9 | with_items:
10 | - 02periodic
11 | - 50unattended-upgrades
12 |
13 | - name: Enable automatic updates in unattended-upgrades package config.
14 | shell: echo unattended-upgrades unattended-upgrades/enable_auto_updates boolean true | debconf-set-selections
15 |
--------------------------------------------------------------------------------
/roles/common/tasks/hostname.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Set hostname.
3 | hostname:
4 | name: "axe-build"
5 |
6 | - name: Build /etc/hosts file.
7 | lineinfile:
8 | dest: /etc/hosts
9 | regexp: '^127.0.1.1'
10 | line: "127.0.1.1 axe-build"
11 | state: present
12 |
--------------------------------------------------------------------------------
/roles/common/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - include_tasks: repartition.yml
3 | - include_tasks: update_everything.yml
4 | - include_tasks: packages.yml
5 | - include_tasks: make_swap.yml
6 | - include_tasks: add_github_ssh_hostkey.yml
7 | - include_tasks: hostname.yml
8 | - include_tasks: motd.yml
9 | - include_tasks: vim.yml
10 | - include_tasks: auto_upgrades.yml
11 |
--------------------------------------------------------------------------------
/roles/common/tasks/make_swap.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Check whether swap file already exists.
3 | stat:
4 | path: /swapfile
5 | register: existing_swapfile_result
6 |
7 | - name: Allocate swapfile.
8 | command: "fallocate -l {{ axe_swapfile_size }} /swapfile"
9 | when: not existing_swapfile_result.stat.exists
10 |
11 | - name: Set permissions of swapfile.
12 | file:
13 | path: /swapfile
14 | owner: root
15 | group: root
16 | mode: "0600"
17 | state: touch
18 |
19 | - name: Set up the swapfile.
20 | command: mkswap /swapfile
21 | when: not existing_swapfile_result.stat.exists
22 |
23 | - name: Enable the swapfile.
24 | command: swapon /swapfile
25 | when: not existing_swapfile_result.stat.exists
26 |
27 | - name: Make the swapfile persistent.
28 | lineinfile:
29 | dest: /etc/fstab
30 | regexp: "^/swapfile"
31 | line: "/swapfile none swap sw 0 0"
32 |
33 | - name: Set vm.swappiness in sysctl.
34 | sysctl:
35 | name: vm.swappiness
36 | value: "{{ axe_vm_swappiness }}"
37 | state: present
38 |
--------------------------------------------------------------------------------
/roles/common/tasks/motd.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Get the current kernel version string.
3 | command: uname -a
4 | register: kernel_version_string
5 |
6 | - name: Install motd (message of the day).
7 | template:
8 | src: motd.j2
9 | dest: /etc/motd
10 | owner: root
11 | group: root
12 | mode: "0644"
13 |
--------------------------------------------------------------------------------
/roles/common/tasks/packages.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install some common packages.
3 | apt:
4 | name: '{{ axe_common_packages }}'
5 | state: present
6 | update_cache: yes
7 | cache_valid_time: 3600
8 |
--------------------------------------------------------------------------------
/roles/common/tasks/repartition.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Make sure parted is installed
3 | apt:
4 | name: parted
5 | state: present
6 | update_cache: yes
7 |
8 | - name: Turn off all swap areas
9 | command: swapoff -a
10 | become: yes
11 |
12 | - name: Remove swap partition from /etc/fstab
13 | mount:
14 | path: none
15 | fstype: swap
16 | opts: sw
17 | state: absent
18 |
19 | - name: Remove partition number 5
20 | parted:
21 | device: /dev/sda
22 | number: 5
23 | state: absent
24 |
25 | - name: Remove partition number 2
26 | parted:
27 | device: /dev/sda
28 | number: 2
29 | state: absent
30 | register: rm_part_2_sda_info
31 |
32 | - name: Resize partition 1 to reach end of disk if it does not already
33 | command: parted ---pretend-input-tty /dev/sda unit % resizepart 1 yes 100
34 | become: yes
35 | when: rm_part_2_sda_info['disk']['size'] != rm_part_2_sda_info['partitions'][0]['end']
36 | register: parted_resize
37 |
38 | - name: Resize filesystem on /dev/sda1 to fill the available space on the partition
39 | filesystem:
40 | dev: /dev/sda1
41 | fstype: ext4
42 | resizefs: true
43 |
--------------------------------------------------------------------------------
/roles/common/tasks/update_everything.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Check if sudo is installed.
3 | command: dpkg-query -l sudo
4 | register: sudo_installed_result
5 | # dpkg returns 1 if package not found,
6 | # so disable the scary red text by setting no-fail mode.
7 | # The output from the command is checked in the next task.
8 | failed_when: false
9 | changed_when: false
10 | # Necessary to support --check mode
11 | check_mode: no
12 |
13 | - name: Install sudo.
14 | apt:
15 | name: sudo
16 | state: present
17 | update_cache: yes
18 | cache_valid_time: 3600
19 | when: "'no packages found' in sudo_installed_result.stderr"
20 |
21 | - name: Update apt cache.
22 | apt:
23 | update_cache: yes
24 | cache_valid_time: 3600
25 |
26 | - name: Install aptitude.
27 | apt:
28 | name: aptitude
29 | state: present
30 | update_cache: yes
31 | cache_valid_time: 3600
32 |
33 | - name: Perform aptitude safe-upgrade.
34 | apt:
35 | upgrade: safe
36 | update_cache: yes
37 | cache_valid_time: 3600
38 | tags: apt
39 |
40 | - name: Remove unneeded packages.
41 | apt:
42 | autoremove: yes
43 | tags: apt
44 |
--------------------------------------------------------------------------------
/roles/common/tasks/vim.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Set default EDITOR to vim.
3 | command: update-alternatives --set editor /usr/bin/vim.basic
4 |
5 | - name: Enable syntax highlighting.
6 | lineinfile:
7 | dest: /etc/vim/vimrc
8 | regexp: "^\"syntax on"
9 | line: "syntax on"
10 |
11 | - name: Enable filetype detection.
12 | lineinfile:
13 | dest: /etc/vim/vimrc
14 | regexp: "^\"filetype on"
15 | line: "filetype on"
16 |
17 | - name: Disable swap files.
18 | lineinfile:
19 | dest: /etc/vim/vimrc
20 | regexp: "^\"set noswapfile"
21 | line: "set noswapfile"
22 |
--------------------------------------------------------------------------------
/roles/common/templates/log-core-dump.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Handler for processing coredumps. Should be invoked only by system
3 | # via the `kernel.core_pattern` in pipe mode, not run interactively.
4 | # It assumes that filename, executable, and uid will be passed as args.
5 |
6 |
7 | coredump_filename=$1
8 | coredump_executable=$2
9 | coredump_uid=$3
10 |
11 | # Ensure we're running as root.
12 | if [ $EUID -ne 0 ]; then
13 | echo "Only root may run this script." 1>&2
14 | exit 1
15 | fi
16 |
17 | # Ensure script is running as part of pipe, receiving stdin.
18 | # If script is run from an interactive terminal, exit.
19 | if [ -t 0 ]; then
20 | echo "No stdin pipe detected, exiting." 1>&2
21 | exit 1
22 | fi
23 |
24 | # Check for required arguments for logging and dumping core.
25 | if [ -z $coredump_filename ] || [ -z $coredump_executable ] || [ -z $coredump_uid ]; then
26 | echo "Missing required arguments for handling core dump." 1>&2
27 | exit 1
28 | fi
29 |
30 | # Log coredump event to syslog.
31 | /usr/bin/logger "Core dump detected: ${coredump_executable} owned by uid ${coredump_uid}"
32 |
33 | # Ensure files are 0600 root:root.
34 | umask 277
35 |
36 | # Redirect core dump content from stdin to target file.
37 | cat - > "{{ coredumps_directory }}/${coredump_filename}"
38 |
--------------------------------------------------------------------------------
/roles/common/templates/motd.j2:
--------------------------------------------------------------------------------
1 | {{ kernel_version_string.stdout }}
2 |
3 | █████╗ ██╗ ██╗ ███████╗
4 | ██╔══██╗ ╚██╗██╔╝ ██╔════╝
5 | ███████║ ╚███╔╝ █████╗
6 | ██╔══██║ ██╔██╗ ██╔══╝
7 | ██║ ██║ ██╔╝ ██╗ ███████╗
8 | ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝
9 |
10 | Hostname: {{ ansible_fqdn }}
11 | IP address: {{ ansible_default_ipv4.address }}
12 |
--------------------------------------------------------------------------------
/roles/gitian/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | gitian_user: vagrant
3 | download_directory: /tmp/gitian
4 | vm_builder_name: 'vm-builder-0.12.4+bzr494'
5 | vm_builder_url: 'http://archive.ubuntu.com/ubuntu/pool/universe/v/vm-builder/vm-builder_0.12.4+bzr494.orig.tar.gz'
6 | gitian_builder_url: https://github.com/devrandom/gitian-builder
7 | gitian_builder_version: master
8 | axe_git_repo_url: https://github.com/AXErunners/axe
9 | axe_gitian_sigs_repo: https://github.com/AXErunners/gitian.sigs
10 | axe_version: master
11 | gitian_host_ip: 10.0.2.15
12 | lxc_guest_ip: 10.0.3.5
13 | axe_developer_pubkeys:
14 | - name: charlesrocket
15 | id: 5AC27140
16 | - name: ddude1
17 | id: B306325A
18 | - name: sparkuss
19 | id: 4033F6D8
20 |
--------------------------------------------------------------------------------
/roles/gitian/files/explode_yaml_file.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | import argparse
5 | import os
6 | import ruamel.yaml
7 |
8 | from ruamel.yaml.scalarstring import DoubleQuotedScalarString
9 |
10 | # For a command like this...
11 | #
12 | # explode_yaml_file.py axe/contrib/gitian-descriptors/gitian-linux.yml suites output_dir
13 | #
14 | # ...with a gitian-linux.yml file like this...
15 | #
16 | # ---
17 | # distro: "debian"
18 | # suites:
19 | # - "jessie"
20 | # - "stretch"
21 | # architectures:
22 | # - "amd64"
23 | #
24 | # ...will write out a structure like this:
25 | #
26 | # output_dir/
27 | # ├─ jessie/
28 | # │ └─ gitian-linux.yml content:
29 | # │ ---
30 | # │ distro: "debian"
31 | # │ suites:
32 | # │ - "jessie"
33 | # │ architectures:
34 | # │ - "amd64"
35 | # │
36 | # └─ stretch
37 | # └─ gitian-linux.yml content:
38 | # ---
39 | # distro: "debian"
40 | # suites:
41 | # - "stretch"
42 | # architectures:
43 | # - "amd64"
44 | #
45 | # This approach is working around a limitation of gitian-builder: when
46 | # passed a descriptor file with more than one entry in 'suites', it
47 | # overwrites products of earlier builds with products of later builds.
48 | # We 'explode' our descriptor file into potentially many single-suite
49 | # descriptor files which we then pass to gitian-builder one at a time.
50 |
51 |
52 | parser = argparse.ArgumentParser(description='YAML file exploder')
53 |
54 | parser.add_argument('input_file_path',
55 | type=str,
56 | help='Path to the input file')
57 |
58 | parser.add_argument('key_to_explode',
59 | type=str,
60 | help='The key in the input file to explode (should be a sequence)')
61 |
62 | parser.add_argument('output_dir_path',
63 | type=str,
64 | help='Path to the output directory')
65 |
66 | args = parser.parse_args()
67 |
68 | yaml = ruamel.yaml.YAML()
69 | yaml.preserve_quotes = True
70 |
71 | input_file_path = args.input_file_path
72 | output_dir_path = args.output_dir_path
73 |
74 | file_name = os.path.basename(input_file_path)
75 |
76 |
77 | with open(input_file_path) as fp:
78 | data = yaml.load(fp)
79 |
80 | sequence = data[args.key_to_explode]
81 |
82 | for item in sequence:
83 | print item
84 | item_dir_path = os.path.join(output_dir_path, item)
85 |
86 | if not os.path.exists(item_dir_path):
87 | os.makedirs(item_dir_path)
88 |
89 | data[args.key_to_explode] = [DoubleQuotedScalarString(item)]
90 |
91 | output_file_path = os.path.join(item_dir_path, file_name)
92 | with open(output_file_path, 'w') as fp:
93 | yaml.dump(data, fp)
94 |
--------------------------------------------------------------------------------
/roles/gitian/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | author: Kevin Gallagher (@ageis) Kent Sommer (@kentsommer) Kirill Orlov (@charlesrocket) and Jonathan Leto (@leto)
4 | description: Sets up a deterministic Gitian builder VM for AXE.
5 | company: AXE
6 | galaxy_tags: []
7 | license: GPLv2
8 | min_ansible_version: 2.1.2
9 | platforms:
10 | - name: Debian
11 | versions:
12 | - jessie
13 | categories:
14 | - system
15 | dependencies: []
16 |
--------------------------------------------------------------------------------
/roles/gitian/tasks/gpg.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Check that the secret key exists.
3 | local_action: "shell gpg --list-secret-keys --with-colons | grep {{ gpg_key_id }}"
4 | become: no
5 | ignore_errors: true
6 | register: gpg_list_keys_result
7 |
8 | - name: Export the GPG private key from the local keyring.
9 | local_action: "command gpg --armor --export-secret-key {{ gpg_key_id }}"
10 | become: no
11 | register: gpg_private_key
12 | changed_when: false
13 | when: gpg_list_keys_result.stdout != ''
14 | no_log: True
15 |
16 | - name: Write the private key to a temp file.
17 | copy:
18 | dest: "/tmp/{{ gpg_key_id }}.sec"
19 | content: "{{ gpg_private_key.stdout }}"
20 | owner: "{{ gitian_user }}"
21 | group: "{{ gitian_user }}"
22 | mode: "0400"
23 | when: gpg_list_keys_result.stdout != ''
24 | no_log: True
25 |
26 | - name: Make GnuPG home directory.
27 | file:
28 | path: "/home/{{ gitian_user }}/.gnupg"
29 | state: directory
30 | mode: "0700"
31 | owner: "{{ gitian_user }}"
32 | group: "{{ gitian_user }}"
33 |
34 | - name: Write GnuPG configuration.
35 | template:
36 | src: gpg.conf
37 | dest: "/home/{{ gitian_user }}/.gnupg/gpg.conf"
38 | mode: "0600"
39 | owner: "{{ gitian_user }}"
40 | group: "{{ gitian_user }}"
41 |
42 | - name: Import the GPG private key to the Vagrant user.
43 | command: "gpg --batch --import /tmp/{{ gpg_key_id }}.sec"
44 | become_user: "{{ gitian_user }}"
45 | when: gpg_list_keys_result.stdout != '' and gpg_private_key.stdout is defined
46 | no_log: True
47 | register: gpg_output
48 | changed_when: "'secret key imported' in gpg_output.stderr"
49 | failed_when: gpg_output.rc != 0 and 'already in secret keyring' not in gpg_output.stderr
50 |
51 | - name: Clean up secret key file in /tmp.
52 | file:
53 | path: "/tmp/{{ gpg_key_id }}.sec"
54 | state: absent
55 |
--------------------------------------------------------------------------------
/roles/gitian/tasks/keys.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Download AXE developer public keys from website.
3 | become: yes
4 | get_url:
5 | url: "https://raw.githubusercontent.com/AXErunners/gitian.sigs/master/{{ item.name }}.asc"
6 | dest: "/tmp/{{ item.id }}.asc"
7 | owner: "{{ gitian_user }}"
8 | group: "{{ gitian_user }}"
9 | mode: "0644"
10 | with_items: "{{ axe_developer_pubkeys }}"
11 |
12 | - name: Import AXE developer public keys.
13 | command: "gpg --import /tmp/{{ item.id }}.asc"
14 | become_user: "{{ gitian_user }}"
15 | with_items: "{{ axe_developer_pubkeys }}"
16 |
17 | - name: Set AXE developer public keys to ultimately trusted.
18 | shell: >
19 | gpg --list-keys --with-colons --with-fingerprint `gpg --list-keys
20 | --with-colons | grep "pub:f:.*:-:" |
21 | sed -r -e 's/pub:f:[0-9]+:[0-9]+:([A-F0-9]+):.*/0x\1/'` | grep "^fpr:" |
22 | sed -r -e 's/fpr:::::::::([0-9A-F]+):/\1:6:/' | gpg --import-ownertrust
23 | become_user: "{{ gitian_user }}"
24 | args:
25 | executable: /bin/bash
26 |
--------------------------------------------------------------------------------
/roles/gitian/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Check that custom git variables are defined.
3 | assert:
4 | that:
5 | - "gpg_key_name is defined"
6 | - "gpg_key_name != ''"
7 | - "git_name is defined"
8 | - "git_name != ''"
9 | - "git_email is defined"
10 | - "git_email != ''"
11 | msg: Please set your gpg_key_name, git_name and git_email in gitian.yml.
12 |
13 | - name: Install Gitian dependencies.
14 | apt:
15 | name:
16 | - apt-cacher-ng
17 | - bridge-utils
18 | - ca-certificates
19 | - curl
20 | - debootstrap
21 | - git-core
22 | - gnupg2
23 | - kpartx
24 | - lintian
25 | - lxc
26 | - make
27 | - python-cheetah
28 | - qemu-utils
29 | - ruby
30 | - sudo
31 | state: present
32 | update_cache: yes
33 |
34 | - name: Add Docker GPG apt Key
35 | apt_key:
36 | url: https://download.docker.com/linux/debian/gpg
37 | state: present
38 |
39 | - name: Add Docker Repository
40 | apt_repository:
41 | repo: deb https://download.docker.com/linux/debian stretch stable
42 | state: present
43 | update_cache: yes
44 |
45 | - name: Install ruamel.yaml
46 | pip:
47 | name: "ruamel.yaml"
48 |
49 | - name: Set up the Gitian build user with sudo.
50 | user:
51 | name: "{{ gitian_user }}"
52 | shell: /bin/bash
53 | groups: sudo
54 | state: present
55 |
56 | - name: Install /etc/rc.local.
57 | template:
58 | src: rc.local
59 | dest: /etc/rc.local
60 | owner: root
61 | group: root
62 | mode: "0755"
63 |
64 | - name: Enable IP forwarding, etc.
65 | sysctl:
66 | name: "{{ item }}"
67 | value: 1
68 | sysctl_set: yes
69 | state: present
70 | reload: yes
71 | with_items:
72 | - net.ipv4.ip_forward
73 | - kernel.unprivileged_userns_clone
74 |
75 | - name: Enable cgroup clone_children.
76 | command: "echo 1 > /sys/fs/cgroup/cpuset/cgroup.clone_children"
77 |
78 | - name: Add cgroup fs for LXC.
79 | lineinfile:
80 | dest: /etc/fstab
81 | regexp: '^cgroup'
82 | line: 'cgroup /sys/fs/cgroup cgroup defaults 0 0'
83 | state: present
84 |
85 | - name: Install profile with environment variables.
86 | template:
87 | src: profile
88 | dest: "/home/{{ gitian_user }}/.profile"
89 | owner: "{{ gitian_user }}"
90 | group: "{{ gitian_user }}"
91 | mode: "0644"
92 |
93 | - name: Install sudoers file for LXC.
94 | template:
95 | src: gitian-lxc
96 | dest: /etc/sudoers.d/gitian-lxc
97 | owner: root
98 | group: root
99 | mode: "0644"
100 |
101 | - name: Create directory for downloaded files.
102 | file:
103 | state: directory
104 | dest: "{{ download_directory }}"
105 | mode: "0755"
106 |
107 | - name: Download and extract VM builder source code.
108 | unarchive:
109 | src: "{{ vm_builder_url }}"
110 | dest: "{{ download_directory }}"
111 | remote_src: yes
112 |
113 | - name: Install VM builder Python module.
114 | command: "python setup.py install"
115 | args:
116 | chdir: "/tmp/gitian/{{ vm_builder_name }}"
117 |
118 | - name: Install lxc-net configuration.
119 | template:
120 | src: lxc-net
121 | dest: /etc/default/lxc-net
122 | owner: root
123 | group: root
124 | mode: "0644"
125 |
126 | - name: Clone git repository for Gitian builder.
127 | git:
128 | repo: "{{ gitian_builder_url }}"
129 | dest: "/home/{{ gitian_user }}/gitian-builder"
130 | version: "{{ gitian_builder_version }}"
131 | force: yes
132 | become_user: "{{ gitian_user }}"
133 |
134 | - include_tasks: keys.yml
135 | tags: keys
136 |
137 | - name: Clone git repository for AXE.
138 | git:
139 | repo: "{{ axe_git_repo_url }}"
140 | dest: "/home/{{ gitian_user }}/axe"
141 | version: "{{ axe_version }}"
142 | force: yes
143 | become_user: "{{ gitian_user }}"
144 |
145 | - name: Clone git repository for Gitian signatures.
146 | git:
147 | repo: "{{ axe_gitian_sigs_repo }}"
148 | dest: "/home/{{ gitian_user }}/gitian.sigs"
149 | version: master
150 | force: yes
151 | become_user: "{{ gitian_user }}"
152 |
153 | - name: Reboot.
154 | shell: sleep 3 && shutdown -r now "Rebooting..."
155 | async: 1
156 | poll: 0
157 | ignore_errors: true
158 | become: yes
159 |
160 | - name: Figure out the Vagrant VM's SSH port number.
161 | local_action: "shell vagrant ssh-config axe-build | grep Port | awk {'print $2'}"
162 | register: vagrant_ssh_port
163 | become: no
164 |
165 | - name: Wait for virtual machine to come back.
166 | local_action: wait_for
167 | host={{ ansible_host | default('localhost') }}
168 | port={{ vagrant_ssh_port.stdout | int }}
169 | delay=30
170 | state=started
171 | become: no
172 |
173 | - name: Wait extra time for VM to come back up.
174 | pause:
175 | seconds: 10
176 |
177 | - name: Set Git username.
178 | command: "git config --global user.name \"{{ git_name }}\""
179 | become_user: "{{ gitian_user }}"
180 |
181 | - name: Set Git email address.
182 | command: "git config --global user.email '{{ git_email }}'"
183 | become_user: "{{ gitian_user }}"
184 |
185 | - name: Create bin directory under gitian_user home directory
186 | file:
187 | state: directory
188 | dest: "/home/{{ gitian_user }}/bin"
189 | mode: "0755"
190 |
191 | - name: Copy explode_yaml_file.py
192 | copy:
193 | src: explode_yaml_file.py
194 | dest: "/home/{{ gitian_user }}/bin/explode_yaml_file.py"
195 | owner: "{{ gitian_user }}"
196 | group: "{{ gitian_user }}"
197 | mode: "0755"
198 |
199 | - name: Copy Gitian build script.
200 | template:
201 | src: gitian-build.py
202 | dest: "/home/{{ gitian_user }}/gitian-build.py"
203 | owner: "{{ gitian_user }}"
204 | group: "{{ gitian_user }}"
205 | mode: "0755"
206 | tags: script
207 |
208 | - name: Clean the apt cache to free up space.
209 | apt:
210 | autoclean: yes
211 |
212 | - include_tasks: gpg.yml
213 | tags: gpg
214 | when: gpg_key_id is defined and gpg_key_id != ''
215 |
216 | - name: Ensure group "docker" exists
217 | group:
218 | name: docker
219 | state: present
220 | system: yes
221 |
222 | - name: Execute Docker without sudo
223 | shell: sh -c "sudo usermod -aG docker vagrant"
224 | become: yes
225 | become_user: vagrant
226 | become_method: sudo
227 |
228 | - name: Prepare input directory for Apple SDK
229 | file:
230 | path: "gitian-builder/inputs"
231 | state: directory
232 | recurse: yes
233 | owner: vagrant
234 |
235 | - name: Copy Apple SDK
236 | copy:
237 | src: MacOSX10.11.sdk.tar.gz
238 | dest: gitian-builder/inputs/MacOSX10.11.sdk.tar.gz
239 | owner: vagrant
240 | ignore_errors: yes
241 |
242 | - name: Display help message.
243 | debug:
244 | msg: >-
245 | Finished bootstrapping the Gitian host VM!
246 | To enter the environment, run `vagrant ssh axe-build`
247 | and then use `./gitian-build.py` to kick off a build.
248 |
--------------------------------------------------------------------------------
/roles/gitian/templates/gitian-build.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import argparse
4 | import os
5 | import subprocess
6 | import sys
7 |
8 | def setup():
9 | global args, workdir
10 | programs = ['ruby', 'git', 'make', 'wget']
11 | if args.lxc:
12 | programs += ['apt-cacher-ng', 'lxc', 'debootstrap']
13 | elif args.kvm:
14 | programs += ['apt-cacher-ng', 'python-vm-builder', 'qemu-kvm', 'qemu-utils']
15 | elif args.docker and not os.path.isfile('/lib/systemd/system/docker.service'):
16 | dockers = ['docker.io', 'docker-ce']
17 | for i in dockers:
18 | return_code = subprocess.call(['sudo', 'apt-get', 'install', '-qq', i])
19 | if return_code == 0:
20 | break
21 | if return_code != 0:
22 | print('Cannot find any way to install Docker', file=sys.stderr)
23 | exit(1)
24 | subprocess.check_call(['sudo', 'apt-get', 'install', '-qq'] + programs)
25 | if not os.path.isdir('gitian.sigs'):
26 | subprocess.check_call(['git', 'clone', 'https://github.com/axerunners/gitian.sigs.git'])
27 | if not os.path.isdir('axe-detached-sigs'):
28 | subprocess.check_call(['git', 'clone', 'https://github.com/axerunners/axe-detached-sigs.git'])
29 | if not os.path.isdir('gitian-builder'):
30 | subprocess.check_call(['git', 'clone', 'https://github.com/devrandom/gitian-builder.git'])
31 | if not os.path.isdir('axe'):
32 | subprocess.check_call(['git', 'clone', 'https://github.com/axerunners/axe.git'])
33 | os.chdir('gitian-builder')
34 | make_image_prog = ['bin/make-base-vm', '--suite', 'bionic', '--arch', 'amd64']
35 | if args.docker:
36 | make_image_prog += ['--docker']
37 | elif args.lxc:
38 | make_image_prog += ['--lxc']
39 | subprocess.check_call(make_image_prog)
40 | os.chdir(workdir)
41 | if args.is_bionic and not args.kvm and not args.docker:
42 | subprocess.check_call(['sudo', 'sed', '-i', 's/lxcbr0/br0/', '/etc/default/lxc-net'])
43 | print('Reboot is required')
44 | exit(0)
45 |
46 | def build():
47 | global args, workdir
48 |
49 | os.makedirs('axecore-binaries/' + args.version, exist_ok=True)
50 | print('\nBuilding Dependencies\n')
51 | os.chdir('gitian-builder')
52 | os.makedirs('inputs', exist_ok=True)
53 |
54 | subprocess.check_call(['wget', '-O', 'inputs/osslsigncode-2.0.tar.gz', 'https://github.com/mtrojnar/osslsigncode/archive/2.0.tar.gz'])
55 | subprocess.check_call(["echo '5a60e0a4b3e0b4d655317b2f12a810211c50242138322b16e7e01c6fbb89d92f inputs/osslsigncode-2.0.tar.gz' | sha256sum -c"], shell=True)
56 | subprocess.check_call(['make', '-C', '../axe/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common'])
57 |
58 | if args.linux:
59 | print('\nCompiling ' + args.version + ' Linux')
60 | subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'axe='+args.commit, '--url', 'axe='+args.url, '../axe/contrib/gitian-descriptors/gitian-linux.yml'])
61 | print('\a')
62 | subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-linux', '--destination', '../gitian.sigs/', '../axe/contrib/gitian-descriptors/gitian-linux.yml'])
63 | subprocess.check_call('mv build/out/axecore-*.tar.gz build/out/src/axecore-*.tar.gz ../axecore-binaries/'+args.version, shell=True)
64 |
65 | if args.windows:
66 | print('\nCompiling ' + args.version + ' Windows')
67 | subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'axe='+args.commit, '--url', 'axe='+args.url, '../axe/contrib/gitian-descriptors/gitian-win.yml'])
68 | print('\a')
69 | subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-win-unsigned', '--destination', '../gitian.sigs/', '../axe/contrib/gitian-descriptors/gitian-win.yml'])
70 | subprocess.check_call('mv build/out/axecore-*-win-unsigned.tar.gz inputs/axecore-win-unsigned.tar.gz', shell=True)
71 | subprocess.check_call('mv build/out/axecore-*.zip build/out/axecore-*.exe ../axecore-binaries/'+args.version, shell=True)
72 |
73 | if args.macos:
74 | print('\nCompiling ' + args.version + ' MacOS')
75 | subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'axe='+args.commit, '--url', 'axe='+args.url, '../axe/contrib/gitian-descriptors/gitian-osx.yml'])
76 | print('\a')
77 | subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-osx-unsigned', '--destination', '../gitian.sigs/', '../axe/contrib/gitian-descriptors/gitian-osx.yml'])
78 | subprocess.check_call('mv build/out/axecore-*-osx-unsigned.tar.gz inputs/axecore-osx-unsigned.tar.gz', shell=True)
79 | subprocess.check_call('mv build/out/axecore-*.tar.gz build/out/axecore-*.dmg ../axecore-binaries/'+args.version, shell=True)
80 |
81 | os.chdir(workdir)
82 |
83 | if args.commit_files:
84 | print('\nCommitting '+args.version+' Unsigned Sigs\n')
85 | os.chdir('gitian.sigs')
86 | subprocess.check_call(['git', 'add', args.version+'-linux/'+args.signer])
87 | subprocess.check_call(['git', 'add', args.version+'-win-unsigned/'+args.signer])
88 | subprocess.check_call(['git', 'add', args.version+'-osx-unsigned/'+args.signer])
89 | subprocess.check_call(['git', 'commit', '-m', 'Add '+args.version+' unsigned sigs for '+args.signer])
90 | os.chdir(workdir)
91 |
92 | def sign():
93 | global args, workdir
94 | os.chdir('gitian-builder')
95 |
96 | if args.windows:
97 | print('\nSigning ' + args.version + ' Windows')
98 | subprocess.check_call(['bin/gbuild', '-i', '--commit', 'signature='+args.commit, '../axe/contrib/gitian-descriptors/gitian-win-signer.yml'])
99 | print('\a')
100 | subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-win-signed', '--destination', '../gitian.sigs/', '../axe/contrib/gitian-descriptors/gitian-win-signer.yml'])
101 | subprocess.check_call('mv build/out/axecore-*win64-setup.exe ../axecore-binaries/'+args.version, shell=True)
102 | subprocess.check_call('mv build/out/axecore-*win32-setup.exe ../axecore-binaries/'+args.version, shell=True)
103 |
104 | if args.macos:
105 | print('\nSigning ' + args.version + ' MacOS')
106 | subprocess.check_call(['bin/gbuild', '-i', '--commit', 'signature='+args.commit, '../axe/contrib/gitian-descriptors/gitian-osx-signer.yml'])
107 | print('\a')
108 | subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-osx-signed', '--destination', '../gitian.sigs/', '../axe/contrib/gitian-descriptors/gitian-osx-signer.yml'])
109 | subprocess.check_call('mv build/out/axecore-osx-signed.dmg ../axecore-binaries/'+args.version+'/axecore-'+args.version+'-osx.dmg', shell=True)
110 |
111 | os.chdir(workdir)
112 |
113 | if args.commit_files:
114 | print('\nCommitting '+args.version+' Signed Sigs\n')
115 | os.chdir('gitian.sigs')
116 | subprocess.check_call(['git', 'add', args.version+'-win-signed/'+args.signer])
117 | subprocess.check_call(['git', 'add', args.version+'-osx-signed/'+args.signer])
118 | subprocess.check_call(['git', 'commit', '-a', '-m', 'Add '+args.version+' signed binary sigs for '+args.signer])
119 | os.chdir(workdir)
120 |
121 | def verify():
122 | global args, workdir
123 | os.chdir('gitian-builder')
124 |
125 | print('\nVerifying v'+args.version+' Linux\n')
126 | subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-linux', '../axe/contrib/gitian-descriptors/gitian-linux.yml'])
127 | print('\nVerifying v'+args.version+' Windows\n')
128 | subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-win-unsigned', '../axe/contrib/gitian-descriptors/gitian-win.yml'])
129 | print('\nVerifying v'+args.version+' MacOS\n')
130 | subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-osx-unsigned', '../axe/contrib/gitian-descriptors/gitian-osx.yml'])
131 | print('\nVerifying v'+args.version+' Signed Windows\n')
132 | subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-win-signed', '../axe/contrib/gitian-descriptors/gitian-win-signer.yml'])
133 | print('\nVerifying v'+args.version+' Signed MacOS\n')
134 | subprocess.call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-osx-signed', '../axe/contrib/gitian-descriptors/gitian-osx-signer.yml'])
135 |
136 | os.chdir(workdir)
137 |
138 | def main():
139 | global args, workdir
140 |
141 | parser = argparse.ArgumentParser(usage='%(prog)s [options] signer version')
142 | parser.add_argument('-c', '--commit', action='store_true', dest='commit', help='Indicate that the version argument is for a commit or branch')
143 | parser.add_argument('-p', '--pull', action='store_true', dest='pull', help='Indicate that the version argument is the number of a github repository pull request')
144 | parser.add_argument('-u', '--url', dest='url', default='https://github.com/axerunners/axe', help='Specify the URL of the repository. Default is %(default)s')
145 | parser.add_argument('-v', '--verify', action='store_true', dest='verify', help='Verify the Gitian build')
146 | parser.add_argument('-b', '--build', action='store_true', dest='build', help='Do a Gitian build')
147 | parser.add_argument('-s', '--sign', action='store_true', dest='sign', help='Make signed binaries for Windows and MacOS')
148 | parser.add_argument('-B', '--buildsign', action='store_true', dest='buildsign', help='Build both signed and unsigned binaries')
149 | parser.add_argument('-o', '--os', dest='os', default='lwm', help='Specify which Operating Systems the build is for. Default is %(default)s. l for Linux, w for Windows, m for MacOS')
150 | parser.add_argument('-j', '--jobs', dest='jobs', default='2', help='Number of processes to use. Default %(default)s')
151 | parser.add_argument('-m', '--memory', dest='memory', default='2000', help='Memory to allocate in MiB. Default %(default)s')
152 | parser.add_argument('-V', '--virtualization', dest='virtualization', default='docker', help='Specify virtualization technology to use: lxc for LXC, kvm for KVM, docker for Docker. Default is %(default)s')
153 | parser.add_argument('-S', '--setup', action='store_true', dest='setup', help='Set up the Gitian building environment. Only works on Debian-based systems (Ubuntu, Debian)')
154 | parser.add_argument('-D', '--detach-sign', action='store_true', dest='detach_sign', help='Create the assert file for detached signing. Will not commit anything.')
155 | parser.add_argument('-n', '--no-commit', action='store_false', dest='commit_files', help='Do not commit anything to git')
156 | parser.add_argument('signer', help='GPG signer to sign each build assert file')
157 | parser.add_argument('version', help='Version number, commit, or branch to build. If building a commit or branch, the -c option must be specified')
158 |
159 | args = parser.parse_args()
160 | workdir = os.getcwd()
161 |
162 | args.linux = 'l' in args.os
163 | args.windows = 'w' in args.os
164 | args.macos = 'm' in args.os
165 |
166 | args.is_bionic = b'bionic' in subprocess.check_output(['lsb_release', '-cs'])
167 |
168 | if args.buildsign:
169 | args.build = True
170 | args.sign = True
171 |
172 | args.sign_prog = 'true' if args.detach_sign else 'gpg --detach-sign'
173 |
174 | args.lxc = (args.virtualization == 'lxc')
175 | args.kvm = (args.virtualization == 'kvm')
176 | args.docker = (args.virtualization == 'docker')
177 |
178 | script_name = os.path.basename(sys.argv[0])
179 | # Set all USE_* environment variables for gitian-builder: USE_LXC, USE_DOCKER and USE_VBOX
180 | os.environ['USE_VBOX'] = ''
181 | if args.lxc:
182 | os.environ['USE_LXC'] = '1'
183 | os.environ['USE_DOCKER'] = ''
184 | if 'GITIAN_HOST_IP' not in os.environ.keys():
185 | os.environ['GITIAN_HOST_IP'] = '10.0.3.1'
186 | if 'LXC_GUEST_IP' not in os.environ.keys():
187 | os.environ['LXC_GUEST_IP'] = '10.0.3.5'
188 | elif args.kvm:
189 | os.environ['USE_LXC'] = ''
190 | os.environ['USE_DOCKER'] = ''
191 | elif args.docker:
192 | os.environ['USE_LXC'] = ''
193 | os.environ['USE_DOCKER'] = '1'
194 | else:
195 | print(script_name+': Wrong virtualization option.')
196 | print('Try '+script_name+' --help for more information')
197 | exit(1)
198 |
199 | # Signer and version shouldn't be empty
200 | if args.signer == '':
201 | print(script_name+': Missing signer.')
202 | print('Try '+script_name+' --help for more information')
203 | exit(1)
204 | if args.version == '':
205 | print(script_name+': Missing version.')
206 | print('Try '+script_name+' --help for more information')
207 | exit(1)
208 |
209 | # Add leading 'v' for tags
210 | if args.commit and args.pull:
211 | raise Exception('Cannot have both commit and pull')
212 | args.commit = ('' if args.commit else 'v') + args.version
213 |
214 | if args.setup:
215 | setup()
216 |
217 | if not args.build and not args.sign and not args.verify:
218 | exit(0)
219 |
220 | # Disable for MacOS if no SDK found
221 | if args.macos and not os.path.isfile('gitian-builder/inputs/MacOSX10.11.sdk.tar.gz'):
222 | print('Cannot build for MacOS, SDK does not exist. Will build for other OSes')
223 | args.macos = False
224 |
225 | os.chdir('axe')
226 | if args.pull:
227 | subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge'])
228 | os.chdir('../gitian-builder/inputs/axe')
229 | subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge'])
230 | args.commit = subprocess.check_output(['git', 'show', '-s', '--format=%H', 'FETCH_HEAD'], universal_newlines=True, encoding='utf8').strip()
231 | args.version = 'pull-' + args.version
232 | print(args.commit)
233 | subprocess.check_call(['git', 'fetch'])
234 | subprocess.check_call(['git', 'checkout', args.commit])
235 | os.chdir(workdir)
236 |
237 | if args.build:
238 | build()
239 |
240 | if args.sign:
241 | sign()
242 |
243 | if args.verify:
244 | verify()
245 |
246 | if __name__ == '__main__':
247 | main()
248 |
--------------------------------------------------------------------------------
/roles/gitian/templates/gitian-lxc:
--------------------------------------------------------------------------------
1 | {{ gitian_user }} ALL=(ALL:ALL) NOPASSWD: ALL
2 | %sudo ALL=NOPASSWD: /usr/bin/lxc-start
3 | %sudo ALL=NOPASSWD: /usr/bin/lxc-execute
4 |
--------------------------------------------------------------------------------
/roles/gitian/templates/gpg.conf:
--------------------------------------------------------------------------------
1 | no-greeting
2 | default-key {{ gpg_key_id }}
3 | require-cross-certification
4 | charset utf-8
5 | keyserver hkp://keys.gnupg.net
6 | use-agent
7 | keyid-format 0xlong
8 | no-emit-version
9 |
--------------------------------------------------------------------------------
/roles/gitian/templates/lxc-net:
--------------------------------------------------------------------------------
1 | USE_LXC_BRIDGE="true"
2 | LXC_BRIDGE="lxcbr0"
3 | LXC_ADDR="10.0.3.1"
4 | LXC_NETMASK="255.255.255.0"
5 | LXC_NETWORK="10.0.3.0/24"
6 | LXC_DHCP_RANGE="10.0.3.2,10.0.3.254"
7 | LXC_DHCP_MAX="253"
8 |
--------------------------------------------------------------------------------
/roles/gitian/templates/profile:
--------------------------------------------------------------------------------
1 | # ~/.profile: executed by the command interpreter for login shells.
2 | # This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
3 | # exists.
4 | # see /usr/share/doc/bash/examples/startup-files for examples.
5 | # the files are located in the bash-doc package.
6 |
7 | # the default umask is set in /etc/profile; for setting the umask
8 | # for ssh logins, install and configure the libpam-umask package.
9 | #umask 022
10 |
11 | # if running bash
12 | if [ -n "$BASH_VERSION" ]; then
13 | # include .bashrc if it exists
14 | if [ -f "$HOME/.bashrc" ]; then
15 | . "$HOME/.bashrc"
16 | fi
17 | fi
18 |
19 | # set PATH so it includes user's private bin if it exists
20 | if [ -d "$HOME/bin" ] ; then
21 | PATH="$HOME/bin:$PATH"
22 | fi
23 |
24 | export DISTRO=debian
25 | export ARCH=amd64
26 | export USE_LXC=1
27 | export LXC_BRIDGE=lxcbr0
28 | export GITIAN_HOST_IP={{ gitian_host_ip }}
29 | export LXC_GUEST_IP={{ lxc_guest_ip }}
30 | export MIRROR_HOST={{ gitian_host_ip }}
31 |
--------------------------------------------------------------------------------
/roles/gitian/templates/rc.local:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 |
3 | echo 1 > /sys/fs/cgroup/cpuset/cgroup.clone_children
4 | echo 1 > /proc/sys/kernel/unprivileged_userns_clone
5 | echo 1 > /proc/sys/net/ipv4/ip_forward
6 |
7 | exit 0
8 |
--------------------------------------------------------------------------------