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.

Phase 4: a job can name the machine it needs

6c03e461ee409f4bd053ee552edd87b6188a5eb2 · Keenan Nemetz · 16d ago · parent b238ac24

Phase 4: a job can name the machine it needs

`runs-on: [linux, arm64]` on a job, `--label linux` on a runner, and the
lease hands a job only to a runner carrying every label it asked for. Extra
labels on the runner are not a mismatch — the rule is set inclusion, so a
machine more specific than the job needs still qualifies — and a job with no
runs-on matches every runner, which is what every job did before this
existed.

Both spellings are accepted (`runs-on: linux` and a list), because both are
the obvious way to write it and a dialect already separate from GitHub's
should not also fail on the spelling a person guessed. Labels are validated
in pre-receive by the same rule the runner applies to --label at startup: a
label no runner can carry leaves a job queued forever and looks exactly like
a busy pool, which is the failure nobody debugs because there is no error.

Labels are pinned at enqueue next to the steps and the artifact patterns. A
workflow edited after a push must not change where an already-queued job is
allowed to run. That also settles the derived-store question: run_labels is
queue state, not history, because a finished run's requirement is recoverable
from the pinned workflow blob, so `vole index rebuild` does not restore
labels and nothing needs it to.

A label is a claim by the runner about itself, unlike --repos, which the
server enforces. A runner that lies about its architecture only takes work it
will do badly; a runner that could name repositories it was not granted would
be an access-control hole. /runners now shows what each connected runner
takes, and says "any job" for an unlabelled one — the other half of "why has
my build not started", since queue depth alone cannot say that no runner
carrying the needed label is connected.

Enqueue takes labels as a second argument rather than a field on Run: they
are lease-time policy, not part of what a run is, and every reader of a Run
(a gate, a page, a record rebuild) would be looking at a field only a lease
ever consulted.

Measured: TestRunsOnWaitsForARunnerThatCarriesTheLabel — a runner carrying
only `linux` leaves a `[linux, fast]` job queued and the runner carrying both
builds it. TestLabelsDecideWhichRunnerMayTakeAJob covers no requirement,
exact match, one label missing, wrong labels and extra labels;
TestLabelsArePinnedAtEnqueue, TestForgettingARepositoryDropsItsLabels,
TestABadRunnerLabelIsRefusedBeforeConnecting,
TestRunsOnLabelsAreParsedAndValidated and
TestRunnersPageShowsWhatEachRunnerTakes cover the edges.

internal/web/templates.go +4−2

@@ -563,10 +563,11 @@ release a description; the tarball below works either way.</p>
563 563 channel that is open and being refreshed is a runner, and it disappears when it closes.</p>
564 564 {{if .Sessions}}
565 565 <table>
566 <tr><th>Runner</th><th>State</th><th>Last seen</th></tr>
566 <tr><th>Runner</th><th>Takes</th><th>State</th><th>Last seen</th></tr>
567 567 {{range .Sessions}}
568 568 <tr>
569 569 <td>{{.Account}}</td>
570 <td class="muted">{{if .Labels}}{{.Labels}}{{else}}<span class="muted">any job</span>{{end}}</td>
570 571 <td>{{if .Idle}}<span class="muted">waiting for work</span>{{else if .RunID}}<a href="/r/{{.Repo}}/runs/{{.RunID}}">{{.Job}}</a> on <a href="/r/{{.Repo}}">{{.Repo}}</a>{{else}}<span class="muted">busy</span>{{end}}</td>
571 572 <td class="muted">{{since .Seen.Unix}}</td>
572 573 </tr>
@@ -574,7 +575,8 @@ channel that is open and being refreshed is a runner, and it disappears when it
574 575 </table>
575 576 {{else}}
576 577 <p class="muted">No runner is connected: none has been seen in the last {{.Window}}. Start one
577 with <code>vole runner --remote ssh://git@&lt;host&gt;</code>.</p>
578 with <code>vole runner --remote ssh://git@&lt;host&gt;</code>. If a job asks for a machine with
579 <code>runs-on</code>, the runner has to carry that label with <code>--label</code>.</p>
578 580 {{end}}
579 581
580 582 <h2>Queue</h2>