More doc
This commit is contained in:
parent
09752bf4d6
commit
205143d7a7
2 changed files with 102 additions and 4 deletions
103
README.md
103
README.md
|
@ -2,8 +2,14 @@
|
||||||
|
|
||||||
A lightweight and (quasi-)stateless CI built on top of Nomad.
|
A lightweight and (quasi-)stateless CI built on top of Nomad.
|
||||||
Our main principle: offload as much work to Nomad as possible.
|
Our main principle: offload as much work to Nomad as possible.
|
||||||
When we can't, offload it to Gitea, Consul, and the others.
|
We don't want to build an abstraction on top of it and hide
|
||||||
At a last resort, we might do it in Albatros...
|
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...
|
||||||
|
|
||||||
## Deploy
|
## Deploy
|
||||||
|
|
||||||
|
@ -13,6 +19,99 @@ nomad run hcl/builder.hcl
|
||||||
go run main.go
|
go run main.go
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 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" ]
|
||||||
|
}
|
||||||
|
"secrets": {
|
||||||
|
"SECRET1": "blabla",
|
||||||
|
"SECRET2": "hey hey"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Your secrets will be passed as a job payload
|
||||||
|
only if all trusted conditions are passing.
|
||||||
|
(For now, we can only check that based on sender's login).
|
||||||
|
|
||||||
|
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):
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl http://localhost:8080/build?job=builder%2Fdispatch-1678866433-15aad86a
|
||||||
|
<todo>
|
||||||
|
```
|
||||||
|
|
||||||
|
Of course, most of that will be handled by Gitea.
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
Passing secrets through environment variables has been criticized
|
||||||
|
as other process inspecting the process can dump the environment variables.
|
||||||
|
It is your responsability to ensure that no malicious process can
|
||||||
|
read the content of your environment variable. It should not be that hard,
|
||||||
|
containers use PID namespace by default, so one containerized process
|
||||||
|
can not access process information of other processes in the system.
|
||||||
|
|
||||||
|
## Writing your build script
|
||||||
|
|
||||||
|
The following variables will be
|
||||||
|
|
||||||
|
```bash
|
||||||
|
REPO_URL=https://git.deuxfleurs.fr/quentin/albatros.git
|
||||||
|
COMMIT=3fff73597f8ca18ef04c0d9bf64132ba55aadcaa
|
||||||
|
BRANCH=main
|
||||||
|
FLAVOR=default
|
||||||
|
SECRET1=xxx
|
||||||
|
SECRET2=xxx
|
||||||
|
```
|
||||||
|
|
||||||
## Ideas
|
## Ideas
|
||||||
|
|
||||||
- [ ] Register the builder programatically
|
- [ ] Register the builder programatically
|
||||||
|
|
3
main.go
3
main.go
|
@ -98,8 +98,7 @@ func hook(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Printf("Query info: %+v\n", dmeta)
|
log.Printf("Query info: %+v\n", dmeta)
|
||||||
log.Printf("Job info: %+v\n", dres)
|
log.Printf("Job info: %+v\n", dres)
|
||||||
|
|
||||||
fmt.Println(notification.CompareUrl)
|
io.WriteString(w, dres.DispatchedJobID)
|
||||||
io.WriteString(w, "ok")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func build(w http.ResponseWriter, r *http.Request) {
|
func build(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
Loading…
Reference in a new issue