Monitor API
Notes about endpoints
Some of the endpoints below require the monitor API token. Requests to these endpoints need to prove you know that token:
Authorization: Bearer <monitor API token>
Some of the endpoints below may require sequential processing in the backend. While requests to other endpoints are guaranteed to be cheap, requests to these endpoints can be a bit expensive when successful, because they’re processed one at a time in the monitor thread.
The monitor thread interacts with external resources like the GitHub API and the hypervisor, and it runs a loop that looks like the pseudocode below:
loop {
if registrations_last_updated.elapsed()
> MONITOR_DOT_TOML.api_cache_timeout
{
registrations = github_api::list_registered_runners();
registrations_last_updated = Instant::now();
}
guests = hypervisor_api::list_guests();
hypervisor_api::take_screenshots(guests);
hypervisor_api::check_ipv4_addresses(guests);
if let Some((request, response_tx)) = monitor_request_rx
.recv_timeout(MONITOR_DOT_TOML.monitor_poll_interval)
{
response_tx.send(match request {
// ...
});
}
}
Reserving runners
The recommended way to reserve runners is to use the tokenless API (POST /select-runner), which uses a temporary artifact to prove that the request is genuine and authorised.
This allows self-hosted runners to be used in pull_request runs (rather than only pull_request_target), and in workflows that do not have access to secrets.
Alternatively you can use the monitor API token, which for workflows means you will need to define it as a secret like ${{ secrets.MONITOR_API_TOKEN }}.
POST /select-runner
— Reserve one runner for a job using an artifact
- May require sequential processing in the backend
- ?unique_id (required; UUIDv4)
- uniquely identifies this job in its friendly name, even if the same workflow is called twice in the workflow call tree
- ?qualified_repo (required;
<user>/<repo>) - the repository running this job
- ?run_id (required; number)
- the workflow run id of this job
POST /profile/profile_key/take
— Reserve one runner for a job using the monitor API token
- Requires monitor API token
- May require sequential processing in the backend
- Response: application/json —
{"id", "runner"}|null
- profile_key (string)
- what kind of runner to take
- ?unique_id (required; UUIDv4)
- uniquely identifies this job in its friendly name, even if the same workflow is called twice in the workflow call tree
- ?qualified_repo (required;
<user>/<repo>) - the repository running this job
- ?run_id (required; number)
- the workflow run id of this job
POST /profile/profile_key/take/count
— Reserve runners for a set of jobs using the monitor API token
- Requires monitor API token
- May require sequential processing in the backend
- Response: application/json —
[{"id", "runner"}]|null
- profile_key (string)
- what kind of runners to take
- count (number)
- how many runners to take
- ?unique_id (required; UUIDv4)
- uniquely identifies these jobs in their friendly names, even if the same workflow is called twice in the workflow call tree
- ?qualified_repo (required;
<user>/<repo>) - the repository running these jobs
- ?run_id (required; number)
- the workflow run id of these jobs
Runner internals
GET /github-jitconfig
— Get the ephemeral runner token for this runner
- May require sequential processing in the backend
- Response: application/json
GET /boot
— Get the boot script for this runner
- May require sequential processing in the backend
- Response: text/plain
Dashboard internals
GET /dashboard.html
— Get the rendered contents of the dashboard for live updates
- Response: text/html
GET /dashboard.json
— Get a machine-readable version of the contents of the dashboard
- Response: application/json
GET /profile/profile_key/screenshot.png
— Get the last cached screenshot of a rebuild guest
- Response: image/png
GET /runner/runner_id/screenshot.png
— Get the last cached screenshot of a runner guest
- Response: image/png
GET /runner/runner_id/screenshot/now
— Take a screenshot of a runner guest immediately
- May require sequential processing in the backend
- Response: image/png
Policy overrides (EXPERIMENTAL)
Policy overrides provide rudimentary support for autoscaling, implemented as part of Servo’s effort to self-host WPT runs (#21). The design has several unsolved problems, and should not be used.
They allow us to dynamically reconfigure a server’s runner targets to meet the needs of a workflow. This can be useful if that workflow is huge and parallel, and you want to divert as much of your concurrent runner capacity as possible to it.
GET /policy/override
— Get the current policy override
POST /policy/override
— Initiate a new policy override
- Requires monitor API token
- Response: application/json —
{"<<profile_key>>": <count>}
- ?<profile_key>=count (required; string/number pairs)
- how many runners to target for each profile key
DELETE /policy/override
— Cancel the current policy override
- Requires monitor API token
- Response: application/json —
{"<<profile_key>>": <count>}