OXYGENHUB
# d7e2c2754807 oxygenhub / templates / admin_runner.html
4.8 KiB · HTML · last changed Administration: a sidebar of grouped pages, one page per section (closes #288) 15 days ago source blame history raw
b6b7e4cf Andy McCall ↶ 1
{% extends "base.html" %}
737de0fa Andy McCall ↶ 2
{% import "admin_nav.html" as an %}
b6b7e4cf Andy McCall ↶ 3
{% block title %}{{ r.name }} · Runners{% endblock %}
4
{% block mainclass %} class="wide"{% endblock %}
5
{% block content %}
6
<div class="head"><h1>{{ r.name }} <small><span class="runner-status st-{{ r.status() }}">{{ r.status() }}</span> · <a href="/admin/runners">Runners</a></small></h1></div>
737de0fa Andy McCall ↶ 7
<div class="settings-layout">
8
{% call an::nav(crate::web::admin::AdminSection::Runners) %}
9
<div class="sections settings-body">
b6b7e4cf Andy McCall ↶ 10
<section class="panel">
11
  <dl class="facts">
12
    <dt>Signing key</dt><dd>{% if r.key.is_empty() %}<span class="mute">bound on its first signed receipt</span>{% else %}<code class="full">{{ r.key }}</code> {{ r.key_name }}{% endif %}</dd>
13
    <dt>Machine</dt><dd>{% if r.arch.is_empty() %}<span class="mute">not reported yet</span>{% else %}{{ r.arch }} · {{ r.os }} · flow {{ r.version }}{% endif %}</dd>
7f5f6c05 Andy McCall ↶ 14
    <dt>Labels</dt><dd>{% for l in r.label_list() %}<span class="lbl">{{ l }}</span> {% endfor %}{% if r.label_list().is_empty() %}<span class="mute">none</span>{% endif %}{% if !r.admin_label_list().is_empty() %} <span class="mute small">({{ r.admin_label_list().len() }} set here)</span>{% endif %}</dd>
15
    <dt>Time limit</dt><dd>{% if let Some(m) = r.timeout_minutes %}{{ m }} min for its jobs, below the site's{% else %}<span class="mute">the site's</span>{% endif %}</dd>
4d2e44d7 Andy McCall ↶ 16
    <dt>Tiers</dt><dd>{% if r.tier_list().is_empty() %}<span class="mute">not reported yet</span>{% else %}{{ r.tier_list().join(", ") }}{% endif %}{% if let Some(i) = r.image_list() %} · {{ i.len()|plural("image", "images") }} held{% endif %}</dd>
b6b7e4cf Andy McCall ↶ 17
    <dt>Capacity</dt><dd>{{ r.max_jobs|plural("job", "jobs") }} at once{% if let Some(m) = r.memory_mib %}, {{ m }} MiB{% endif %}{% if let Some(c) = r.cpus %}, {{ c }} vCPU{% endif %}</dd>
18
    <dt>Running now</dt><dd>{{ running|plural("job", "jobs") }}</dd>
19
    <dt>Ran</dt><dd>{{ jobs|plural("job", "jobs") }}, {{ passed }} passed{% if jobs > 0 %} ({{ passed * 100 / jobs }}%){% endif %}, busy {{ self.busy() }}</dd>
20
    <dt>Registered</dt><dd>{% if r.source == "config" %}configured in hub.toml{% else %}by {{ r.created_by }}{% endif %}, <time title="{{ r.created_ms|when_i }}">{{ r.created_ms|ago_i }}</time></dd>
21
    <dt>Last seen</dt><dd>{% if let Some(t) = r.last_seen_ms %}<time title="{{ t|when_i }}">{{ t|ago_i }}</time>{% else %}never{% endif %}</dd>
22
  </dl>
23
</section>
24
<section class="panel">
7f5f6c05 Andy McCall ↶ 25
  <h2>Settings</h2>
26
  <form class="card" method="post" action="/admin/runners/{{ r.id }}/limits">
27
    <input type="hidden" name="_csrf" value="{{ shell.csrf }}">
28
    <label>Labels given here, beside those it reports{% if !r.reported_label_list().is_empty() %} ({{ r.reported_label_list().join(", ") }}){% endif %}</label>
29
    <input type="text" name="labels" value="{{ r.admin_labels }}" placeholder="gpu, plex">
30
    <label>Job time limit in minutes (empty: the site's)</label>
31
    <input type="number" name="timeout_minutes" min="1" max="1440" value="{% if let Some(m) = r.timeout_minutes %}{{ m }}{% endif %}">
32
    <button type="submit">SAVE</button>
33
  </form>
34
</section>
4d2e44d7 Andy McCall ↶ 35
{% if !declines.is_empty() %}<section class="panel">
36
  <h2>Declined</h2>
37
  <p class="small mute">Jobs this runner handed back before running them, and why (OxygenFlow spec §11.5).</p>
38
  <div class="table"><table>
39
  <tr><th>Repository</th><th>Run</th><th>Job</th><th>Reason</th><th>When</th></tr>
40
  {% for d in declines %}<tr>
41
    <td><a href="/{{ d.owner }}/{{ d.name }}">{{ d.owner }}/{{ d.name }}</a></td>
42
    <td><a href="/{{ d.owner }}/{{ d.name }}/flow/{{ d.run_number }}">#{{ d.run_number }}</a></td>
43
    <td>{{ d.job }}</td>
44
    <td>{{ d.reason }}</td>
45
    <td class="small"><time title="{{ d.ms|when_i }}">{{ d.ms|ago_i }}</time></td>
46
  </tr>{% endfor %}
47
  </table></div>
48
</section>{% endif %}
7f5f6c05 Andy McCall ↶ 49
<section class="panel">
b6b7e4cf Andy McCall ↶ 50
  <h2>Jobs</h2>
51
  {% if history.is_empty() %}<p class="mute">No jobs yet.</p>{% else %}
52
  <div class="table"><table>
53
  <tr><th>Repository</th><th>Run</th><th>Job</th><th>Status</th><th>Duration</th><th>Started</th><th>Receipt</th></tr>
54
  {% for j in history %}<tr>
55
    <td><a href="/{{ j.owner }}/{{ j.repo }}">{{ j.owner }}/{{ j.repo }}</a></td>
56
    <td><a href="/{{ j.owner }}/{{ j.repo }}/flow/{{ j.run_number }}">#{{ j.run_number }}</a></td>
57
    <td>{{ j.job }}</td>
58
    <td><span class="flow-glyph st-{{ j.status }}">{{ crate::web::flow::glyph(j.status) }}</span> {{ j.status }}</td>
59
    <td>{{ crate::web::runners::duration(j) }}</td>
60
    <td class="small">{% if let Some(t) = j.started_ms %}<time title="{{ t|when_i }}">{{ t|ago_i }}</time>{% endif %}</td>
61
    <td class="small">{% if !j.receipt_attest.is_empty() %}<a href="/{{ j.owner }}/{{ j.repo }}/receipts/{{ j.receipt_attest }}">signed</a>{% endif %}</td>
62
  </tr>{% endfor %}
63
  </table></div>
64
  {% if let Some(b) = older %}<p><a href="?before={{ b }}">Older jobs</a></p>{% endif %}
65
  {% endif %}
66
</section>
737de0fa Andy McCall ↶ 67
</div>
68
</div>
b6b7e4cf Andy McCall ↶ 69
{% endblock %}