{% if let Some(n) = notice %}<pclass="note">{{ n }}</p>{% endif %}
8
{% if let Some(e) = error %}<pclass="error">{{ e }}</p>{% endif %}
9
{% if let Some(t) = new_token %}
10
<sectionclass="panel strip ok">
11
<h2>Registration token</h2>
12
<p>Use it once, within a day, on the machine that will run jobs. It is shown only now.</p>
13
<preclass="snippet">flow runner register {{ hub }} --token {{ t }} --name NAME [--ca hub-ca.pem] [--label LABEL]
14
flow runner</pre>
15
<pclass="small mute">The runner sends its signing identity when it registers; this hub accepts receipts from it signed by that key only.</p>
16
</section>
17
{% endif %}
18
<sectionclass="panel">
19
{% if runners.is_empty() %}<pclass="mute">No runners yet. Create a registration token below and run <code>flow runner register</code> on the runner.</p>{% else %}
<tdclass="small"><ahref="/admin/runners?runner={{ r.name|urlencode }}#queue"title="{% if row.jobs.is_empty() %}Its jobs in the queue{% else %}{{ row.jobs_line() }}{% endif %}">{{ row.doing() }}</a></td>
<formclass="tiny"method="post"action="/admin/runners/{{ r.id }}/scope"title="Empty for the whole site, an owner, or owner/repository"><inputtype="hidden"name="_csrf"value="{{ shell.csrf }}"><inputtype="text"name="scope"size="14"placeholder="owner or owner/repo"><button>set</button></form></td>
<td>{% if r.key.is_empty() %}<spanclass="mute"title="Bound on its first signed receipt">not yet</span>{% else %}<codetitle="{{ r.key }} · {{ r.key_name }}">{{ r.key|short }}</code>{% endif %}</td>
<tdclass="small">{% if r.arch.is_empty() %}<spanclass="mute">unknown</span>{% else %}{{ r.arch }} · {{ r.os }} · flow {{ r.version }}{% endif %}{% let f = r.facts_line() %}{% if !f.is_empty() %}<br><spanclass="mute"title="Measured by the runner at its last claim{% if !r.kernel.is_empty() %}; kernel {{ r.kernel }}{% endif %}">{{ f }}</span>{% endif %}{% if !row.swarm.is_empty() %}<br><spanclass="mute"title="Where other runners fetch image chunks from it">swarm {{ row.swarm }}</span>{% endif %}</td>
<tdclass="small">{% for l in r.label_list() %}<spanclass="lbl">{{ l }}</span> {% endfor %}</td>
32
<tdclass="small">{{ r.max_jobs|plural("job", "jobs") }}{% if let Some(m) = r.memory_mib %} · {{ m }} MiB{% endif %}{% if let Some(c) = r.cpus %} · {{ c }} vCPU{% endif %}</td>
33
<tdclass="small">{% if let Some(t) = r.last_seen_ms %}<timetitle="{{ t|when_i }}">{{ t|ago_i }}</time>{% else %}<spanclass="mute">never</span>{% endif %}</td>
{% if r.state == "active" %}<buttonname="state"value="draining"title="Finish current jobs, take no new ones">drain</button><buttonname="state"value="disabled"title="Refuse its requests at once">disable</button>{% else %}<buttonname="state"value="active">resume</button>{% endif %}</form>
36
<formclass="tiny"method="post"action="/admin/runners/{{ r.id }}/remove"onsubmit="returnconfirm('Remove {{ r.name }}? Its credential stops working; its jobs keep its name.')"><inputtype="hidden"name="_csrf"value="{{ shell.csrf }}"><buttonclass="danger-btn">remove</button></form></td>
<selectname="repo"aria-label="Repository"><optionvalue="">every repository</option>{% for r in queue_repos %}<option{% if *r == filter.repo %} selected{% endif %}>{{ r }}</option>{% endfor %}</select>
<selectname="runner"aria-label="Runner"><optionvalue="">every runner</option>{% for r in queue_runners %}<option{% if *r == filter.runner %} selected{% endif %}>{{ r }}</option>{% endfor %}{% if !filter.runner.is_empty() && !queue_runners.contains(filter.runner) %}<optionselected>{{ filter.runner }}</option>{% endif %}</select>
<aclass="go end"href="/admin/insights?range=24h{% if !filter.repo.is_empty() %}&repo={{ filter.repo|urlencode }}{% endif %}{% if !filter.runner.is_empty() %}&runner={{ filter.runner|urlencode }}{% endif %}"target="_blank"rel="noopener"title="Pickup time, jobs, durations and runners, charted (opens a new window)">Charts ↗</a>
<pclass="small mute">Queued jobs are in the order runners claim them: repositories take turns, a repository with jobs running waiting behind those without; a job waits for its dependencies and for a runner whose scope, tier and room fit it.</p>
<pclass="small">A runner registers with a one-time token: it sends its signing identity, architecture and labels, and gets its own credential, kept in <code>runner.toml</code> beside its <code>flow.toml</code>.</p>