2023-03-15 08:21:42 +00:00
|
|
|
# Albatros
|
|
|
|
|
|
|
|
A lightweight and (quasi-)stateless CI built on top of Nomad.
|
|
|
|
Our main principle: offload as much work to Nomad as possible.
|
2023-03-15 09:08:18 +00:00
|
|
|
We don't want to build an abstraction on top of it and hide
|
|
|
|
Nomad internals, but instead expose them as directly and transparently
|
|
|
|
as possible, so that you can benefit from all the features of this software.
|
|
|
|
**Albatros is a specialized CI for Nomad**
|
|
|
|
|
|
|
|
When we can't offload our work directly to Nomad, we should consider
|
|
|
|
offloading it to Gitea, Consul, and the others. At a last resort,
|
|
|
|
we might do it in Albatros...
|
2023-03-15 08:21:42 +00:00
|
|
|
|
|
|
|
## Deploy
|
|
|
|
|
2023-03-15 09:28:09 +00:00
|
|
|
Requirements: Nomad, Consul
|
2023-03-15 09:16:49 +00:00
|
|
|
Optional: Gitea
|
|
|
|
|
2023-03-15 08:21:42 +00:00
|
|
|
```
|
|
|
|
nomad namespace apply -description "Continuous Integration" ci
|
|
|
|
nomad run hcl/builder.hcl
|
|
|
|
go run main.go
|
|
|
|
```
|
|
|
|
|
2023-03-15 09:08:18 +00:00
|
|
|
## Register a build
|
|
|
|
|
|
|
|
Add to Consul a key in albatros hierarchy
|
|
|
|
named after your repo URL as base64. Example:
|
|
|
|
|
|
|
|
```
|
|
|
|
albatros/aHR0cHM6Ly9naXQuZGV1eGZsZXVycy5mci9xdWVudGluL2FsYmF0cm9zLmdpdA==
|
|
|
|
```
|
|
|
|
|
|
|
|
The key must contain a JSON file with your desired token, trust conditions, and secrets:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"token": "s3cr3t",
|
|
|
|
"trusted_if": {
|
|
|
|
"sender": [ "quentin", "lx" ]
|
|
|
|
}
|
2023-03-15 09:28:09 +00:00
|
|
|
"secret": "SECRET1=xx\nSECRET2=yy",
|
2023-03-15 09:08:18 +00:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2023-03-15 09:28:09 +00:00
|
|
|
Your secret will be injected in your build environment only
|
|
|
|
when trustig condition are matched. It wil be available in a dedicated
|
|
|
|
file. Its path is communicated through an environment variable (see below).
|
|
|
|
For now, we can only check that based on sender's login.
|
2023-03-15 09:08:18 +00:00
|
|
|
|
|
|
|
Then you can trigger a build as follow:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ curl -d @example/albatros.json http://localhost:8080/hook?token=s3cr3t&flavor=default
|
|
|
|
builder/dispatch-1678866433-15aad86a
|
|
|
|
```
|
|
|
|
|
|
|
|
You need to pass your token, and you can optionally pass a flavor, that can
|
|
|
|
be used later by your build script.
|
|
|
|
|
|
|
|
As you can see, you now have an identifier representing your job, you
|
|
|
|
can use it to follow your logs (don't forget to urlencode it):
|
|
|
|
|
|
|
|
```
|
2023-03-15 10:37:01 +00:00
|
|
|
$ curl http://localhost:8080/build?job=builder%2Fdispatch-1678866433-15aad86a&log=stderr
|
2023-03-15 09:08:18 +00:00
|
|
|
<todo>
|
|
|
|
```
|
|
|
|
|
|
|
|
Of course, most of that will be handled by Gitea.
|
|
|
|
|
2023-03-15 09:12:30 +00:00
|
|
|
## Writing your build script
|
|
|
|
|
|
|
|
You must create an executable `.albatros` file at the root of your repository.
|
|
|
|
Then, you can use the interpreter you want to execute it, let use `bash`
|
|
|
|
as an example, but please use python, javascript, or anything else that has
|
|
|
|
proper error handling...
|
|
|
|
|
|
|
|
```bash
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
echo "Building commit $COMMIT"
|
|
|
|
go build
|
|
|
|
```
|
|
|
|
|
|
|
|
During the build, the following environment variables are available:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
REPO_URL=https://git.deuxfleurs.fr/quentin/albatros.git
|
|
|
|
COMMIT=3fff73597f8ca18ef04c0d9bf64132ba55aadcaa
|
|
|
|
BRANCH=main
|
|
|
|
FLAVOR=default
|
2023-03-15 09:28:09 +00:00
|
|
|
SECRET_PATH=/var/run/secrets/albatros/secret.txt
|
2023-03-15 09:12:30 +00:00
|
|
|
```
|
|
|
|
|
2023-03-15 09:13:22 +00:00
|
|
|
## Gitea integration
|
2023-03-15 09:12:30 +00:00
|
|
|
|
|
|
|
*Todo*
|
|
|
|
|
2023-03-15 09:08:18 +00:00
|
|
|
## Security model
|
|
|
|
|
|
|
|
Albatros only tries to protect your secrets.
|
|
|
|
To achieve that, we only inject them in the build script
|
|
|
|
if the job has been `sent` (triggered) by a trusted sender.
|
|
|
|
This decision is taken by looking at the webhook payload content.
|
|
|
|
|
|
|
|
To protect against sender impersonification, your webhook
|
|
|
|
must be called only by trusted code, and more generally, your token
|
|
|
|
must remain secret.
|
|
|
|
|
|
|
|
We assume otherwise that anyone can trigger the webhook
|
|
|
|
through Gitea while replacing the content of the build script
|
|
|
|
by a malicious software. Signing the build script is tempting
|
|
|
|
but it will not prevent someone to put its malicious code, for example
|
|
|
|
in a Rust project, in the `build.rs` file. So you must
|
|
|
|
assume that your CI will execute untrusted code.
|
|
|
|
|
|
|
|
To protect against undesired code execution,
|
|
|
|
you must harden your environment, for example by using
|
|
|
|
VMs instead of containers, timeouts, and restricting
|
|
|
|
some IO. All of that must be handled by Nomad. Also,
|
|
|
|
be careful to the local network in which your workload
|
|
|
|
will be executed.
|
|
|
|
|
2023-03-15 08:21:42 +00:00
|
|
|
## Ideas
|
|
|
|
|
|
|
|
- [ ] Register the builder programatically
|
2023-03-15 09:12:30 +00:00
|
|
|
- [ ] Allow users to define their own set of builders (ones with more CPU+RAM, etc.)
|