# 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: * * * ## 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.