1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
# Ambient CI
Ambient is a CI system centered around building in network isolation
inside a per-build virtual machine.
Unlike my previous attempts at building a CI system, Ambient is meant
to be safe, secure, and also reasonable to maintain in the long-term.
## Ambient CI - an ever present continuous integration system
Ambient is a PRE-ALPHA level project to build a CI system. It's only
ever been tested on Debian 12 (bookworm). To try this:
- you need: vmdb2, ansible, QEMU, possibly more
- build the VM image:
`sudo ./ambient-build-debian-image --image ~/ambient.qcow2--cache ~`
- building an image requires root access, but you can re-use the
image any number of times, and you only need to build it once
- the cache option names a directory where a cache file is created
to speed up future builds
- the image option is the name of the finished VM image
- this can take a few minutes
- run a build: `./ambient-run --image ambient.qcow2 --log log --artifact output.tar test-project`
- this builds the project in `test-project` in a VM, by running
`test-project/.ambient-script`
- this will write the build log to `log` and any artifacts produced
by the build to `output.tar`
## The virtual machine
You need to prepare a virtual machine image to use with `ambient-run`.
The provided `ambient-build-debian-image` builds a Debian one, but any
operating system will work, if prepared the right way.
The VM will get be run using QEMU (the `kvm` command), and probably
only works for x86-64, for now. (This can be fixed, at a cost of
speed.) The VM will be given two extra devices, one with the source
files, and one for the output files. On Linux, these devices are `vdb`
and `vdc`. The input device will contain a tar archive with the source
tree. The build shall write a tar archive of the exported artifacts to
the output device. The output device has a size limit, and the build
can't write more than that. `ambient-run` extracts the tar archive
from the output device.
The operating system in the virtual machine must run the build by
extracting the source tar, and run `.ambient-script` from there. The
script must be given the output device as its only argument. See
`ambient-run-script` in the source file for how the Debian image does
it. See also `ambient.service` for the systemd unit that invokes the
script. The build is non-interactive.
The first serial port (`/dev/ttyS0` in the Debian image) can be used
for a build log. It is captured to a file by `ambient-run` (see the
`--log` option). For now, the log is unstructured and just contains
the raw output from the serial port.
## Building Rust programs
The `rust.yml` extra playbook installs a Rust toolchain with `rustup`.
A Rust project might have an `.ambient-script` like this (assuming the
output binary is `helloworld`):
~~~sh
#!/bin/bash
set -xeuo pipefail
output="$1"
export PATH="/root/.cargo/bin:$PATH"
export CARGO_HOME=cargo-home
cargo build
tar -cf "$output" -C target/debug helloworld
~~~
The build in the VM has no network access at all. To provide
dependencies, you can use `cargo fetch`:
~~~sh
$ mkdir cargo-home
$ CARGO_HOME=cargo-home cargo fetch
~~~
This will mean the dependencies get downloaded into `cargo-home` in
the source tree, and `ambient-run` will provide them to the build VM
with the rest of the sources.
## Links
These were an inspiration:
* <https://asylum.madhouse-project.org/blog/2022/08/02/the-big-ci-hunt/>
* <https://asylum.madhouse-project.org/blog/2022/08/05/the-ideal-ci-part-one/>
* <https://asylum.madhouse-project.org/blog/2022/08/07/the-ideal-ci-part-two/>
## Acknowledgment
Lars Wirzenius has been doing the initial programming. Daniel
Silverstone and Rob Kendrick have given encouragement and guidance.
Soile Mottisenkangas helped come up with the name.
|