| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <pstm-uri>/saddles</pstm-uri>
- <pstm-template>main</pstm-template>
- </head>
- <body>
- <section>
- <h2>Saddles</h2>
- <p stm-if="saddles == null">Loading…</p>
- <div stm-if="saddles != null">
- <details>
- <summary><strong>Register saddle</strong></summary>
- <form stm-action="saddles.register">
- <div class="form-row"><label>Name</label>
- <input type="text" name="name" required placeholder="saddle-1"></div>
- <div class="form-row"><label>Host</label>
- <input type="text" name="host" required placeholder="localhost:7100"></div>
- <button type="submit">Register</button>
- </form>
- </details>
- <div class="cards">
- <section class="card" stm-for-saddle-in="saddles.saddles">
- <h3 stm-text="saddle.name">name</h3>
- <p><span stm-attribute.class="'badge badge-' + saddle.status" stm-text="saddle.status">status</span>
- <span class="muted" stm-text="saddle.host">host</span></p>
- <p stm-if="saddle.current_goal_id > 0">Supervising goal:
- <a stm-attribute.href="'/goals/' + saddle.current_goal_id"
- stm-text="saddle.current_goal_title">goal</a>
- <span class="badge badge-kind-goal">goal</span>
- <span class="muted" stm-if="saddle.allocated_display.length > 0" stm-text="'since ' + saddle.allocated_display">since</span></p>
- <p stm-if="saddle.current_task_id > 0 && saddle.current_goal_id == 0">Current task:
- <a stm-attribute.href="'/tasks/' + saddle.current_task_id" stm-text="saddle.current_task_title">task</a>
- <span class="muted" stm-if="saddle.allocated_display.length > 0" stm-text="'since ' + saddle.allocated_display">since</span></p>
- <p stm-if="saddle.current_task_id == 0" class="muted">No current task</p>
- <p><span stm-attribute.class="'badge badge-health-' + saddle.health"
- stm-text="saddle.health">healthy</span>
- <span class="muted" stm-if="saddle.daemon_state.length > 0"
- stm-text="'daemon ' + saddle.daemon_state + (saddle.uptime_display.length > 0 ? ' · up ' + saddle.uptime_display : '')">daemon</span>
- <span class="muted" stm-text="'contacted ' + saddle.last_contact_display + ' ago'">contacted</span></p>
- <p stm-if="saddle.token.length > 0" class="muted">API token:
- <code stm-text="saddle.token">token</code></p>
- <details stm-if="saddle.ssh_public_key.length > 0">
- <summary>SSH public key</summary>
- <p class="muted">Add this as a <strong>deploy key</strong> on the git server
- (with write access) so this saddle can clone and push.</p>
- <pre class="ssh-key"><code stm-text="saddle.ssh_public_key">key</code></pre>
- <button type="button"
- stm-attribute.data-clipboard="saddle.ssh_public_key"
- onclick="navigator.clipboard.writeText(this.getAttribute('data-clipboard')).then(function () { this.textContent = 'Copied'; }.bind(this))">Copy key</button>
- </details>
- <p stm-if="saddle.ssh_public_key.length == 0" class="muted">No SSH key reported yet —
- it appears here once the daemon generates one.</p>
- <details>
- <summary>Git identity</summary>
- <form stm-action="saddle.update_identity" class="inline">
- <label>Committed as</label>
- <input type="text" name="git_name" stm-attribute.value="saddle.git_name"
- placeholder="saddle-1">
- <input type="text" name="git_email" stm-attribute.value="saddle.git_email"
- placeholder="saddle-1@example.net">
- <button type="submit">Save</button>
- <span class="muted">Empty fields fall back to the daemon's default identity.</span>
- </form>
- </details>
- <p stm-if="saddle.capabilities.length > 0">Capabilities:
- <span stm-for-capability-in="saddle.capabilities" stm-key="capability.link_id">
- <span class="badge"><span stm-text="capability.name">tag</span>
- <button type="button" class="inline chip-remove"
- stm-action="capability.detach" stm-confirm="Remove this capability?">×</button></span>
- </span>
- </p>
- <p stm-if="saddle.capabilities.length == 0" class="muted">No capabilities — matches only tasks with none required.</p>
- <form class="inline" stm-if="saddles.capability_options.length > 0"
- stm-action="saddle.attach_capability">
- <label stm-attribute.for="'cap-' + saddle.id">Add capability</label>
- <select stm-attribute.id="'cap-' + saddle.id" name="capability_id" required>
- <option stm-for-option-in="saddles.capability_options" stm-attribute.value="option.id"
- stm-text="option.name">capability</option>
- </select>
- <button type="submit">Add</button>
- </form>
- <form class="inline">
- <button type="button" stm-action="saddle.refresh">Refresh status</button>
- <button type="button" stm-action="saddle.unregister" stm-confirm="Remove this saddle? A running task is re-queued.">Remove</button>
- </form>
- </section>
- <section class="card" stm-if="saddles.saddles.length == 0">
- <p class="muted">No saddles registered. The dispatcher pairs queued tasks with idle saddles automatically.</p>
- </section>
- </div>
- <h3>Capabilities</h3>
- <p class="muted">Tags the dispatcher routes by: a task is only assigned to a saddle carrying every
- tag the task requires. Manage a saddle's tags on its card above; require tags on a task's page.</p>
- <details>
- <summary><strong>New capability</strong></summary>
- <form stm-action="saddles.create_capability" class="inline">
- <label for="new-capability">Name</label>
- <input type="text" id="new-capability" name="name" required placeholder="gpu">
- <button type="submit">Create capability</button>
- </form>
- </details>
- <table>
- <thead><tr><th>Tag</th><th>Saddles carrying it</th><th>Tasks requiring it</th><th></th></tr></thead>
- <tbody>
- <tr stm-for-capability-in="saddles.capabilities">
- <td><span class="badge" stm-text="capability.name">tag</span></td>
- <td stm-text="capability.saddle_count">0</td>
- <td stm-text="capability.task_count">0</td>
- <td><button type="button" stm-action="capability.delete"
- stm-confirm="Delete this capability everywhere?">Delete</button></td>
- </tr>
- <tr stm-if="saddles.capabilities.length == 0">
- <td colspan="4" class="muted">No capabilities defined yet.</td>
- </tr>
- </tbody>
- </table>
- </div>
- </section>
- </body>
- </html>
|