Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Let a job declare the network it needs

d79580247b8f33f7ffdf2f05847733cad12c187a · Keenan Nemetz · 6d ago · parent 4ac42680

Let a job declare the network it needs

A runner's --container-network decided the network for every job it took, so a
machine that could reach the network gave it to builds that never asked, and a
job that did need one could be handed to a machine that had none. The docs said
"add bridge only when a job needs it", which no workflow could express.

A job now says `network: none` or `network: bridge`. The request is pinned with
the run, and the lease only hands a bridge job to a runner that advertises the
capability, so a job waits for a capable machine instead of failing on one that
never could. The runner applies the job's request to its container, which means a
bridge runner can still withhold the network from a job that asked for none.

A job that declares nothing keeps the runner's own setting, which is what every
workflow meant before this field existed. The local run applies the same rule and
refuses a bridge job when it was started without one, so `vole workflow run` either
matches CI or says what to change on the command line.

The workflows page, the run page, and the runner's log line now say what a job
asked for and what it ran with. verify.yaml and release.yaml are deliberately not
in this change: the instance validates a pushed workflow with the binary it is
running, so they can declare the field once that binary knows it.

Closes #159.

docs/runner.md +28−5

@@ -98,8 +98,10 @@ instance or kept on the runner, so each of those channels has a bound:
98 98 branch cannot seed the cache another contributor's branch builds from. A
99 99 protected branch never shares a cache with a contributor branch.
100 100 - **Container.** `--container-memory`, `--container-cpus` and `--container-pids`
101 pass the runtime's own limits; `--container-network none` (the default) means a
102 step with no network. The runtime's storage driver, not Vole, is what bounds the
101 pass the runtime's own limits. `--container-network` is what this machine can
102 offer — `none` (the default) or `bridge` — and a job's own `network:` decides what
103 it gets, so a bridge runner can still run a job that asks for none. See
104 [Network](#network). The runtime's storage driver, not Vole, is what bounds the
103 105 container's writable layer, so size it on the host.
104 106
105 107 ## Images and image builds
@@ -114,8 +116,9 @@ was queued. It renders the definition to a Dockerfile, builds it with the
114 116 configured OCI runtime, and tags the result by the definition digest. A later job
115 117 with the same definition reuses that tag.
116 118
117 The image build uses the runtime's own default network. `--container-network`
118 applies to the job container, not to the image build.
119 The image build uses the runtime's own default network, so a base image and its
120 `run:` commands can fetch packages. The job's own network request applies to the job
121 container, not to the build.
119 122
120 123 An image definition is code. Its build runs on the runner through the OCI
121 124 builder, so approving a contributor tip that changes a definition also approves
@@ -131,7 +134,8 @@ one.
131 134
132 135 Container defaults are intentionally closed:
133 136
134 - no network (`--container-network none`); add `bridge` only when a job needs it;
137 - no network unless the job asks for one with `network: bridge`, or the runner was
138 started with it and the job says nothing;
135 139 - no capabilities, `no-new-privileges`, and no host mounts except the job tree;
136 140 - no Docker socket, SSH agent, or host environment;
137 141 - `/tmp` is a writable, executable tmpfs (compilers write their output there and
@@ -190,6 +194,25 @@ the runtime's mapping (container root is the runner user) or use a runtime with
190 194 The run record names the image, the definition digest when there is one, and the
191 195 runtime, so the run page says what actually executed.
192 196
197 ## Network
198
199 `--container-network` says what this machine can give a job: `none` (the default) or
200 `bridge`. It is a capability, not a setting for every job. The job's `network:`
201 decides what the container gets, and the runner applies it:
202
203 | Job says | This runner says `bridge` | This runner says `none` |
204 |---|---|---|
205 | nothing | bridge | none |
206 | `none` | none | none |
207 | `bridge` | bridge | the runner never receives the job |
208
209 So a machine with a network is not a machine that hands it to every build. A job
210 that asks for none is isolated on either kind of runner, and a job that asks for
211 bridge waits in the queue for a runner that advertises one instead of running
212 without the network it needs. The runner advertises this with every lease, the same
213 way it advertises `--label`, and the job's request is pinned with the run when it is
214 queued.
215
193 216 ## Caching
194 217
195 218 A job starts with an empty container, so without help every run downloads its