コンテンツにスキップ

What this deployment is running, and how far back it can be taken.

GET
/api/v1/system/upgrade
curl --request GET \
--url https://example.com/api/v1/system/upgrade \
--header 'Authorization: Bearer <token>'

The running build, the applied schema, and the compatibility floor

Media typeapplication/json

The state of the upgrade mechanism and of this deployment’s schema.

object
available
One of:
null
components
required

Everything this deployment is made of — core and every poller — with what each runs and whether an upgrade can move it (ADR-051 Inc.6).

Replaces the two fields that answered the same question from opposite ends (pollers, which said who an upgrade carried and who it stranded, and poller_alignment, which said who was off core’s build). They were views of one table and could disagree about which poller a row was; a selection dialog needs the table.

There is no “nobody asked” state here. The old pollers field was null until the central updater named its own compose project, because without that list core cannot tell a co-located poller from a remote one. That is now a property of a row (co_located), so a deployment with no central updater still gets a full list — and still gets the button, since aligning remote sites touches nothing on this host.

Array<object>

One row of the components list: something this deployment is made of, and what it runs.

Deliberately does not say whether the row is already on the target. That depends on which release the operator picked, which this does not know; it is a string comparison the caller makes.

object
co_located
required

It shares core’s compose project, so it follows core’s own checkbox and cannot be unselected on its own.

boolean
id
required

Sanitized poller id, or core for the core+WebUI row.

string
kind
required

Which kind of thing this is.

string
Allowed values: core poller
live_in_pool
required

How many live pollers this row’s pool has, including this one; 0 for core.

Carried so the caller can say which pools go dark for the selection actually made. It used to be a dark_pools field computed from “everything that could move”, which stops being true the moment a row can be unchecked — and a warning that does not follow the checkboxes is worse than none, because it reads the same when it matters.

integer
moves_back
required

It is ahead of this core, so moving it to core’s build is a downgrade.

Computed here and not in the WebUI on purpose: ordering versions is semver, where 0.2.10 comes after 0.2.9, and this repository already keeps that comparison in one place because the other thing deciding from it is whether a rollback is allowed.

boolean
needs_site_prep
required

Moving this component would carry it to a site that has not said an upgrade is safe there.

A remote site replaces its own poller by running docker compose beside it. A site whose updater predates the fix for that operation resolves the poller’s certificate mount against the wrong directory, and Docker creates the missing source empty rather than failing — so the replacement starts, has nothing to trust the bus with, and never comes back. Both ends report success, because the command exited 0.

The site declares the opposite when it can, so true covers a site running an older updater, one whose updater is stopped, and one that has never said. All three call for the same thing before a press, and none of them may read as safe. false for anything an upgrade would not move on its own — this deployment’s core, a poller sharing its compose project, one that is offline, and one with no site updater at all.

Clearing it takes recreating the container that answers, which is not the same as replacing the file it was created from. An apply installs the site’s new composition and then recreates poller by name — deliberately, because a bare up -d would destroy the updater running the apply — so a site can hold a current composition and a stale updater, and this stays true until that service is recreated. The cheap repair is therefore up -d --force-recreate yagra-poller-updater at the site; re-issuing the bundle is for a site whose composition is itself older than the fix. Setting YAGRA_CERT_DIR to an absolute path makes the next upgrade survivable and clears nothing here — deliberately, because the site is still on the old updater.

boolean
pool

The pool it serves; null for core, which serves none.

string | null
progress
One of:
null
reason
One of:
null
upgradable
required

Whether an upgrade can move it at all. A false row is still listed — dropping it would read as “that poller is gone” rather than “that poller cannot come”.

boolean
version

What it is running now, when it has reported a version.

string | null
current
required

The running build.

object
build_profile

release or ci-fast (/etc/yagra-build-profile); null outside a container.

string | null
core_version
required

The crate version this core was compiled from.

string
hostname

The container’s hostname, which is how a replica identifies itself in the logs.

string | null
source_ref

The commit the image was built from (/etc/yagra-source-ref); null outside a container.

string | null
uptime_seconds
required

Seconds since this process started.

integer format: int64
enabled
required

Whether an upgrade can be requested from here — the updater is deployed, alive, and the operator’s switch is on. When false, this response describes only what is installed.

boolean
last_run
One of:
null
offers
required

The moves this deployment could make, each with its direction and whether it is allowed. Excludes the running version. Empty when the updater has found nothing.

Array<object>

A release the operator could move to, with the direction and the verdict already decided by the server — the comparison is semver, and it is the same rule that decides whether a rollback is safe.

object
blocked
One of:
null
core_digest

Resolved image digest, when the sidecar could resolve one.

string | null
direction
required

Whether this moves forward or back.

string
Allowed values: upgrade rollback
tag
required

The release tag.

string
poller_convergence
One of:
null
schema
required

Applied migrations and the compatibility floor they imply.

object
applied_count
required

How many migrations have been applied.

integer format: int64
compat
One of:
null
latest_version

The newest applied migration version; null only on a database with none.

integer | null format: int64
updater
required

The updater container’s own state.

object
allow_bundle
required

Whether it will install an uploaded image archive. Off unless the host’s compose file turns it on — it is the only path that can bring an image this deployment never named onto the host, so it is gated separately from the mechanism as a whole (ADR-050 Increment 3).

boolean
bundle_max_bytes

The largest archive core will accept, in bytes. Present whenever allow_bundle is, so the UI can refuse an oversized file before spending an hour uploading it.

integer | null format: int64
check_interval_secs

How often it re-checks the registry, in seconds.

integer | null format: int64
fresh
required

Whether its last report is recent enough for it to be considered alive.

boolean
installed
required

Whether this deployment has an upgrade mechanism at all — that is, whether the host wired the hand-off directory in. false describes how the deployment was installed rather than anything that went wrong: upgrading from the WebUI needs a container composition that carries the privileged updater alongside core, so a native installation, or a composition that does not ship it, cannot offer it. The command-line upgrade path is unaffected.

boolean
last_seen

Unix seconds of its last report.

integer | null format: int64
paused
required

Whether the sidecar has seen the switch turned off. Distinct from upgrade_enabled, which is what this deployment stored: while the two disagree the change has not reached the sidecar yet, which takes at most one of its beats.

boolean
present
required

Whether the updater has ever reported. Meaningful only where installed is true, and there it means the container is missing or has not finished starting — a fault, not a property of the deployment.

boolean
repo

The image repository it is pinned to. Fixed by the host environment and not settable over this API.

string | null
upgrade_enabled
required

The operator’s switch, as stored by this deployment. Separate from enabled, which also depends on the updater being alive: this one says what was chosen, and it is what the toggle in Settings ▸ Upgrade reflects.

boolean
Example
{
"components": [
{
"kind": "core",
"progress": {
"command": "prefetch",
"state": "running"
},
"reason": "no_site_updater"
}
],
"offers": [
{
"blocked": "below_floor",
"direction": "upgrade"
}
],
"poller_convergence": {
"targets": [
{
"state": "waiting"
}
]
}
}

No valid bearer token

Media typeapplication/json

The ADR-019 envelope every failure renders as. pub(crate) and schema-bearing so the OpenAPI document can name one error shape for every endpoint (ADR-035) instead of leaving 4xx/5xx bodies undescribed — a client that has to guess the failure shape ends up parsing the success shape and reading undefined.

object
error
required
object
code
required

Stable machine-readable code. Clients branch on this, never on the message.

string
message
required

Operator-facing sentence. Safe to display; never carries an internal error’s own text.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example"
}
}

Role lacks ManageSystem

Media typeapplication/json

The ADR-019 envelope every failure renders as. pub(crate) and schema-bearing so the OpenAPI document can name one error shape for every endpoint (ADR-035) instead of leaving 4xx/5xx bodies undescribed — a client that has to guess the failure shape ends up parsing the success shape and reading undefined.

object
error
required
object
code
required

Stable machine-readable code. Clients branch on this, never on the message.

string
message
required

Operator-facing sentence. Safe to display; never carries an internal error’s own text.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example"
}
}

This deployment has no metadata store

Media typeapplication/json

The ADR-019 envelope every failure renders as. pub(crate) and schema-bearing so the OpenAPI document can name one error shape for every endpoint (ADR-035) instead of leaving 4xx/5xx bodies undescribed — a client that has to guess the failure shape ends up parsing the success shape and reading undefined.

object
error
required
object
code
required

Stable machine-readable code. Clients branch on this, never on the message.

string
message
required

Operator-facing sentence. Safe to display; never carries an internal error’s own text.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example"
}
}