Runtime images
List Runtime Images
List registered images. Defaults to current rows only;
include_superseded=true returns history. Used by the admin
staleness page (Patch 5).
Query Parameters
falseHeader Parameters
Response Body
curl -X GET "https://loading/internal/v1/runtime-images?manifest_id=string&provider=string&include_superseded=false" \ -H "authorization: string"{
"images": [
{
"built_at": "2019-08-24T14:15:22Z",
"bundle_hash": "string",
"compatibility_hash": "string",
"id": "string",
"manifest_id": "string",
"provider": "string",
"registered_at": "2019-08-24T14:15:22Z",
"registered_by": "string",
"runtime_version": "string",
"snapshot_id": "string",
"superseded_at": "2019-08-24T14:15:22Z"
}
]
}{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string"
}
]
}Register Runtime Image
Insert a new row for (manifest_id, provider) and supersede the previous current row in the same transaction.
Concurrency: we acquire a transaction-scoped Postgres advisory lock keyed on (manifest_id, provider) before reading the current row. SELECT ... FOR UPDATE alone is not sufficient because:
- The first bake for a slot has no row to lock — two simultaneous registrations would both pass the partial- unique-index check and one would fail at INSERT.
- After T1 supersedes the existing current row and commits, T2's blocked SELECT FOR UPDATE re-reads, sees no current row, and proceeds to INSERT — both rows might then race the partial unique check. The advisory lock serialises every code path against the same slot, removing both windows. It auto-releases on transaction end (commit OR rollback). The lock key is a 64-bit hash of "<manifest_id>:"; collisions across unrelated slots are harmless (worst case: two unrelated bakes serialise) but identical slots always collide, which is what we want.
Idempotency: re-POST with the same snapshot_id + compatibility_hash for the same slot is a no-op — useful when a bake retries after a transient network blip. The response then reports superseded=False with the existing id.
Header Parameters
date-time10 <= length <= 80length <= 100length <= 50length <= 255Response Body
curl -X POST "https://loading/internal/v1/runtime-images" \ -H "authorization: string" \ -H "Content-Type: application/json" \ -d '{ "built_at": "2019-08-24T14:15:22Z", "compatibility_hash": "stringstri", "manifest_id": "string", "provider": "string", "snapshot_id": "string" }'{
"compatibility_hash": "string",
"id": "string",
"manifest_id": "string",
"provider": "string",
"snapshot_id": "string",
"superseded": true,
"superseded_id": "string"
}{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string"
}
]
}Rollback Runtime Image
Supersede the named row and un-supersede the most recently superseded row in the same (manifest, provider) slot.
Used by the continuous-bake pipeline when a freshly registered snapshot fails its post-bake smoke or soak checks. The previous "current" row is the one most-recently superseded for the slot — typically the snapshot the just-failed bake replaced.
No-op contract: if image_id is already superseded the call is
rejected (409) so a stale rollback can't accidentally re-promote
a 3-versions-back snapshot. Callers should check the current row
via GET first if there is any doubt.
Empty-slot guard: if the caller is rolling back the FIRST-EVER
registered image for a slot (no previous row to restore), the
rollback would leave the slot with no current image — silently
degrading future provisions to the GOLDEN_IMAGES_JSON env or
vanilla ubuntu fallback. For the automated smoke-failure path
this is dangerous: it makes a single bad smoke pull the
platform off baked images entirely. Default behaviour is now
409 in that case; pass ?allow_empty_slot=true for the manual
operator path where empty-current is genuinely intended (e.g.
decommissioning a runtime).
Concurrency: same advisory-lock key as the register path so a rollback can't race a concurrent register on the same slot.
Path Parameters
Query Parameters
falseHeader Parameters
Response Body
curl -X POST "https://loading/internal/v1/runtime-images/string/rollback?allow_empty_slot=false" \ -H "authorization: string"{
"manifest_id": "string",
"provider": "string",
"restored": "string",
"rolled_back_from": "string"
}{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string"
}
]
}