OXYGENHUB
# 1a1793bdfcc0 oxygenflow / README.md
3.5 KiB · Markdown · last changed README: the real OxygenFlow badge, not a relative stamp 1 month ago renderedsource blame history raw
1
# OxygenFlow
2
3
[![OxygenFlow]https://oxygenhub.io/andymccall/oxygenflow/flow/badge.svg]https://oxygenhub.io/andymccall/oxygenflow/flow
4
5
Hermetic pipelines for Oxygen repositories:
6
7
- a typed pipeline in `.flow/pipeline.kdl`
8
- jobs run in isolation tiers, Firecracker microVMs by default
9
- the host writes the receipts
10
- results go to OxygenHub as checks and appear on its Flow tab
11
12
The specification is [docs/spec.md]docs/spec.md. What works today is
13
[docs/m0.md]docs/m0.md.
14
15
## A pipeline
16
17
```kdl
18
schema-version 1
19
20
sandbox "alpine" {
21
    runtime "microvm"
22
    rootfs "cas://blob/…"      // printed by `flow rootfs import`
23
    memory-limit "256MiB"
24
    network "isolated"
25
}
26
27
job "build" {
28
    sandbox "alpine"
29
    exec "make"
30
}
31
32
job "test" {
33
    sandbox "alpine"
34
    depends-on "build"
35
    exec "sh" "-eu" "test.sh"   // argv, run as written: no shell unless you name one
36
}
37
```
38
39
Each job boots its own microVM:
40
41
- it has no network device
42
- the rootfs is read-only
43
- the workspace is the state being built, read-write at `/src`
44
- the job runs as a user that is not root
45
46
This repository's own pipeline is [.flow/pipeline.kdl].flow/pipeline.kdl.
47
The stamp at the top of this page is its result on OxygenHub. It shows the
48
run of the state you are viewing, not whatever the bookmark holds now, and
49
it names the state and each job's receipt.
50
51
## Commands
52
53
    flow check                 # validate .flow/pipeline.kdl, print jobs and the pipeline hash
54
    flow run [JOB…]            # run the pipeline on this directory, locally, in microVMs
55
    flow rootfs import T.tgz --sha256 HEX   # make a rootfs image; prints the `rootfs` line to pin
56
    flow rootfs list
57
    flow hash FILE             # BLAKE3, for pinning in flow.toml
58
    flow runner                # claim and run jobs for the hub in flow.toml
59
60
## A Flow home
61
62
`$FLOW_HOME` (default `~/.local/share/flow`) holds:
63
64
- `flow.toml`
65
- the pinned Firecracker binary, guest kernel and `flow-init`
66
- rootfs images under `cas/`
67
- scratch space
68
69
Every pinned file is checked against its BLAKE3 before use.
70
71
```toml
72
[microvm]
73
firecracker = { path = "bin/firecracker", blake3 = "…" }
74
kernel = { path = "kernel/vmlinux", blake3 = "…" }
75
init = { path = "bin/flow-init", blake3 = "…" }
76
77
[runner]                     # only for `flow runner`
78
hub = "https://hub.example:7343"
79
token = "…"                  # listed in the hub's [flow] runner_tokens
80
ca = "/path/to/hub-ca.pem"   # when the hub's certificate is self-signed
81
name = "runner-1"
82
```
83
84
Setting one up needs Linux x86-64 with KVM and e2fsprogs 1.43 or later:
85
86
1. Build `flow` with `cargo build --release -p flow`. Build the guest init
87
   as a static binary:
88
   `RUSTFLAGS="-C target-feature=+crt-static" cargo build --release -p flow-init --target x86_64-unknown-linux-gnu`.
89
2. Download Firecracker v1.17.0 from its GitHub release, and check the
90
   published SHA-256. Download the guest kernel
91
   `firecracker-ci/v1.15/x86_64/vmlinux-6.1.155` from Firecracker's CI
92
   bucket.
93
3. Run `flow rootfs import alpine-minirootfs-3.24.2-x86_64.tar.gz --sha256 …`.
94
4. Write `flow.toml`, pinning each file by its `flow hash`.
95
96
On OxygenHub, `hub.toml` lists the runner token and the repositories whose
97
pushes run pipelines:
98
99
```toml
100
[flow]
101
runner_tokens = ["…"]
102
repos = ["owner/*"]
103
```
104
105
## Tests
106
107
`cargo test --workspace` runs every test that needs no VM. The microVM
108
conformance test also runs when `FLOW_TEST_HOME` names a Flow home and
109
`FLOW_TEST_ROOTFS` is the hash of an Alpine rootfs in it. The test checks
110
literal argv, network isolation, the read-only rootfs, and that dependents
111
are skipped after a failure.