Updates and release channels
Two things update independently, with two different commands:
- The
tritonadmbinary on your workstation or head node.tritonadm self-updatereplaces it. - The deployed cloud, which is the control-plane zones and the
global-zone agents.
tritonadm updatereprovisions the zones and extracts the agents again.
Both commands read the same signed release channel, so this page starts with the channel.
How a channel works
A channel is a minisign-signed JSON manifest published at
https://tritoncloud.nyc3.digitaloceanspaces.com/channels/<NAME>.json. A
detached signature is published at the same URL plus .minisig. Continuous
integration publishes two named channels:
| Channel | Published from |
|---|---|
edge | Builds of main. |
stable | Builds from a v* tag. |
tritonadm uses stable when you pass neither --channel nor
--channel-url. A channel exists only after something is published to it.
stable resolves only after a tagged build has run. No tagged build has
been published yet, so pass --channel edge on every command that reads
the channel.
The manifest declares a schema version, the channel name, an updated_at
timestamp, a publisher string, an optional sealed revision, and four
artifact maps: images, agents, services, and tritonadm. Every
artifact entry has a build stamp in YYYYMMDDTHHMMSSZ form, a lowercase hex
sha256, and a size in bytes. Agent, service, and tritonadm entries have
one url. An image entry has a manifest_url and a content_url.
tritonadm understands schema version 1. It refuses a manifest that
declares a higher schema version and does not parse it.
What tritonadm verifies
Every channel fetch that tritonadm performs downloads both the manifest
and its .minisig. It verifies the signature against the publisher public
key compiled into the binary from cli/tritonadm/publisher.pub (minisign
key id 6A95AFF9C8B898E7). A signature that does not verify stops the
command with channel signature did NOT verify against publisher pubkey.
tritonadm then compares the downloaded artifact bytes against the sha256
in that signed manifest.
The tools/install.sh bootstrap script does not perform this check. It
verifies the sha256 of the tritonadm tarball against the channel JSON it
fetched over TLS, and nothing more. Its trust root is TLS to the channel
host. Every later channel fetch by tritonadm itself, including
self-update --check, enforces the publisher signature. See
Install the tritonadm CLI.
Select a channel
Three flags select the manifest. They appear on install, update, and
self-update.
| Flag | Effect |
|---|---|
--channel <NAME> | Expands to https://tritoncloud.nyc3.digitaloceanspaces.com/channels/<NAME>.json. |
--channel-url <URL> | Uses this manifest URL as given. Takes precedence over --channel. |
--revision <REV> | Points the resolved URL at the frozen snapshot .../channels/<NAME>/<REV>.json. |
tritonadm channel revisions accepts only --channel-url and --channel.
The CLI config file does not store the selection. Pass the selector on each command, and pass the same selector to every command in one run.
The cluster records one upstream, the channel.upstream_url setting.
tritonadm setup converge reads it when you pass no --channel.
tritonadm channel refresh mirrors it into the in-cluster channel that
compute nodes install from. Genesis does not set it. Set it once after
genesis, on any host with a signed-in tritonadm:
tritonadm config set channel.upstream_url https://tritoncloud.nyc3.digitaloceanspaces.com/channels/edge.json
tritonadm channel refresh then fetches the upstream and verifies it
against the publisher key. It signs the manifest again with the cluster's
own channel-signing key and publishes it in the cluster. Compute nodes fetch
from the booter's mirror, never from the upstream. --revision <STAMP> pins
the mirror to a sealed revision. --no-wait returns the operation id instead
of waiting.
Check what is installed
The CLI
Run this on any host where tritonadm is installed.
tritonadm self-update --check
The command prints the stamp compiled into the running binary and the stamp that the channel advertises for this binary's target triple.
installed: <INSTALLED_STAMP>
candidate: <CANDIDATE_STAMP> (<BYTES> bytes)
When the two stamps match, the command prints already up to date and exits
zero. When they differ, --check exits non-zero. You can use this exit code
as a gate in automation.
tritonadm --version prints the crate version from Cargo.toml. The
channel identifies builds by stamp, not by that version. self-update --check
is the comparison that matters.
The channel contents and the host
On the head node, in the global zone, as root:
tritonadm install --list
The command prints the channel name and updated_at, then the images,
agents, and tritonadm maps. It reads the installed status from the host:
imgadm list -H -o uuid for images, and /opt/triton/<NAME>/etc/version
for agents.
The deployed components
On the head node, in the global zone, as root:
tritonadm update --check --all
--check plans every component without changes. It reports how many updates
are available and how many components failed to plan. It changes nothing.
Update the CLI
Run self-update as a user that can write to the install directory. On a
head node that directory is /opt/triton/bin, so run it as root.
tritonadm self-update
The sequence is:
- Resolve the channel URL from
--channel-url,--channel, and--revision. - Fetch the manifest and its
.minisig. Verify the signature against the compiled-in publisher key. - Find the entry for this binary's target triple. The triple is compiled in,
not detected at run time. A channel with no entry for it fails with
channel has no tritonadm entry for target <TARGET>. - Compare the entry's stamp with the compiled-in build stamp. Stop if they match.
- Download the tarball. Verify its sha256 against the signed manifest.
Extract the
tritonadmbinary from the top level of the archive. - Replace the binary atomically.
The replacement copies the new binary to <INSTALL_DIR>/tritonadm.new. It
renames the live binary to <INSTALL_DIR>/tritonadm.prev. Then it renames
.new over tritonadm. Both the extracted binary and the staged copy get
mode 0755. The command prints where the new binary is and where the
previous binary is kept.
tritonadm updated at <INSTALL_DIR>/tritonadm
previous binary preserved at <INSTALL_DIR>/tritonadm.prev (manually delete when satisfied)
| Flag | Effect |
|---|---|
--channel-url <URL> | Override the channel manifest URL. |
--channel <NAME> | Named channel. --channel-url takes precedence. |
--revision <REV> | Update to, or roll back to, the frozen snapshot of a sealed revision. |
--install-dir <DIR> | Override the install directory. Defaults to the directory that contains the running executable. |
--check | Report installed against candidate and exit. Exits non-zero when they differ. |
--image-dir <DIR> | Use the newest local tritonadm-<STAMP>.tar.gz instead of the channel. Conflicts with --channel-url, --channel, and --revision. |
Roll back the CLI
tritonadm.prev survives one update cycle, so you can reverse a bad release
without a download. Move tritonadm.prev back over tritonadm by hand, or
run tritonadm self-update --revision <REV> with a known-good sealed
revision.
Update the deployed cloud
tritonadm update reprovisions and restarts running control-plane
components. A zone reprovision replaces the immutable zone root and reboots
the zone. NICs, customer_metadata, and a delegated /data dataset
survive. Plan for the control plane to be unavailable while the command
runs.
Run update on the head node, in the global zone, as root. Plan first:
tritonadm update --check --all
Then apply:
tritonadm update --all
You can name components instead of --all. A command with neither
components nor --all is a usage error.
tritonadm update tritonagent proteusadm
Components
| Component | Aliases | What the update does |
|---|---|---|
tritonadm | Delegates to self-update, with this run's channel or --image-dir. | |
tritond | Reprovisions the triton-tritond zone from the triton-platform image. | |
adminui | admin-backend, ui | Reprovisions the same triton-tritond zone. The admin UI is part of the platform image. |
tritonagent | agent | Extracts the agent bundle again under /opt/triton/tritonagent. Restarts its SMF service when the bundle changed. |
proteusadm | Extracts the bundle again. It has no SMF manifest, so no service is registered or restarted. | |
fdb | triton-fdb, triton-fdb0 | Reprovisions the triton-fdb0 zone from the triton-platform image. |
clickhouse | triton-clickhouse | Reprovisions the triton-clickhouse zone from the triton-clickhouse image. |
mantad | triton-mantad | Reprovisions every contiguous triton-mantadN zone from the triton-platform image. Uses the unindexed triton-mantad alias when no numbered zone exists. |
--all walks the components in this order: tritond, tritonagent,
proteusadm, fdb, clickhouse, mantad, tritonadm. tritonadm runs
last because it replaces the binary that drives the run. adminui is not a
separate --all entry, because the tritond update already reprovisions
that zone.
How a run behaves
update first plans every component without changes and prints a preview
for each. Then it applies. Consequences of that split:
--checkand--dry-runstop after the preview and change nothing.- An artifact that is missing from the source is reported as a skip that
names the source. It is not an error. An agent reports
not in channel; skipornot in --image-dir; skip. An image prefixes the image name, as intriton-platform not in channel; skip. - A zone that does not exist is reported as
zone <ALIAS> not provisioned; skip.updatenever provisions an absent zone. That is what Genesis on the founder does. - An unknown component name logs a warning to stderr, and the command skips it.
- Zone lookup uses
triton-fdb1whentriton-fdb0is absent, andtriton-tritond1whentriton-tritondis absent. - A component that is already on the channel's stamp reports that and does nothing.
- The
tritonadmcomponent is not counted in the--checkand--dry-runtotals. Under--check, its preview prints thetritonadm self-update --checkcommand to run instead.
One confirmation covers the whole run. It appears only when at least one planned action would modify or remove running state:
Apply the updates above? This reprovisions/restarts running components.
The default answer is No. Pass --yes (visible alias --force) to skip
the prompt in automation.
| Flag | Effect |
|---|---|
--all | Update every known component that is present in both the source and the host. |
--check | Report what is outdated. Changes nothing. |
--dry-run | Print the planned actions. Changes nothing. |
--yes, --force | Skip the confirmation prompt. |
--channel-url <URL> | Override the channel manifest URL. |
--channel <NAME> | Named channel. --channel-url takes precedence. |
--revision <REV> | Update against the frozen snapshot of a sealed revision. |
--image-dir <DIR> | Use a local directory of built images and agent tarballs. Conflicts with --channel-url, --channel, and --revision. |
The FoundationDB data-format gate
A reprovision of the FDB zone is gated on the data_format_min_read of the
incoming image against the zone's on-disk /data/version. The planning pass
evaluates the gate before any change, so the FDB zone is never reprovisioned
across a data-format gap. A gate failure is reported as an error against
that component. The error text names the migration runbook, and the run
exits non-zero. The other components named in the same run still apply.
Pin or roll back to a revision
Every published build is also sealed as an immutable, signed snapshot named after its build stamp. A signed revision index records it next to the moving channel pointer. List the snapshots:
tritonadm channel revisions --channel edge
The listing names the channel. It marks the revision that the moving pointer advertises now. It prints the sealed revisions, newest first.
channel: <CHANNEL>
current: <REVISION>
=== revisions (newest first) ===
<REVISION> sealed=<PUBLISHED_AT> by=<PUBLISHER> <- current
Each of those ids is a valid --revision value for install, update, and
self-update. To pin the whole head node to a known-good revision:
tritonadm update --all --revision <REVISION>
A frozen snapshot is a full manifest signed by the same publisher key as the moving pointer. It goes through the same verification.
Update from local artifacts
--image-dir replaces the signed channel with a directory of locally built
files, for development and air-gapped hosts. It is available on update
and self-update. On both commands it conflicts with --channel-url,
--channel, and --revision.
tritonadm update --all --image-dir /var/tmp/artifacts
In that directory, update reads images from a <STEM>.imgmanifest or
<STEM>.json paired with a <STEM>.zfs.gz next to it. It reads agents from
<NAME>-<STAMP>.tar.gz for the known agent names tritonagent and
proteusadm. It reads the CLI from the newest tritonadm-<STAMP>.tar.gz.
When several stamps are present, the newest wins. If the directory has no
tritonadm tarball, the self-update step reports not in --image-dir; skip
and does not fail later.
--image-dir bypasses the release channel. It therefore bypasses the
minisign signature check and the sha256 comparison against a signed
manifest. Point it only at artifacts that you built or trust.
Next steps
- Install the tritonadm CLI covers the first
install of the CLI and the trust model of
install.sh. - Genesis on the founder covers
tritonadm setup bootstrap, which provisions the zones thatupdatelater reprovisions. tritonadm self-updatereference lists the command surface.tritonadm installreference covers the install of a single image or agent from the same channel.- Installation overview puts these commands in order.