Skip to main content

Updates and release channels

Two things update independently, with two different commands:

  • The tritonadm binary on your workstation or head node. tritonadm self-update replaces it.
  • The deployed cloud, which is the control-plane zones and the agents on every node. tritonadm update reprovisions the zones and refreshes the agents.

Both commands read the same signed release channel, so this page starts with the channel. For the order to run them in on a live cluster, see Apply an update.

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:

ChannelPublished from
edgeBuilds of main.
stableBuilds from a v* tag.

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 to genesis.

setup bootstrap and setup apply fall back to stable when you pass neither --channel nor --channel-url. setup converge with no channel flag and no --image-dir reads the channel the cluster follows, and falls back to stable when it cannot read one. Every other command that reads the channel falls back to the channel the cluster follows, the channel.upstream_url setting, read through tritond. With no session, those commands fail with this message:

no --channel given, and the cluster's channel could not be read; pass `--channel edge` (or `stable`, or `--channel-url URL`)

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 the 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. versions and channel revisions accept --channel and --channel-url.

FlagEffect
--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.

The CLI config file does not store the selection. The cluster does, in its channel.upstream_url setting. A genesis from the channel sets it to the channel it installed from. tritonadm setup converge sets it when it is unset. An --image-dir genesis leaves it unset. To change the channel the cluster follows, on any host with a signed-in tritonadm:

tritonadm config set channel.upstream_url https://tritoncloud.nyc3.digitaloceanspaces.com/channels/edge.json

update, self-update, and self-update --check then need no channel flag.

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 versions

The command shows the control plane's build and image, every other registered infra zone against the channel's triton-platform image, each node's agent and sandbox runtime, and each gateway zone against the gateway image pin, and marks drift. The infra zones are the boot service, ClickHouse, DNS edge, each FoundationDB member, mantad, notifyd, the portal, and the MantaFS masters and storage zones, one row each, labeled by kind. A zone of a kind this build of tritonadm does not know has no target. Its targets come from the cluster's channel unless --channel or --channel-url names another.

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:

  1. Resolve the channel URL from --channel-url, --channel, the cluster's channel.upstream_url, and --revision.
  2. Fetch the manifest and its .minisig. Verify the signature against the compiled-in publisher key.
  3. 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>.
  4. Compare the entry's stamp with the compiled-in build stamp. Stop if they match. Any stamp that differs is installed, older or newer.
  5. Download the tarball. Verify its sha256 against the signed manifest. Extract the tritonadm binary from the top level of the archive.
  6. Run the extracted binary's hidden api-version command, and send one request carrying that admin API version to the running tritond. tritond answers it before authentication. When tritond does not serve that version, or cannot be asked, stop and change nothing, unless --force. A build older than the api-version command speaks an older version and is not checked. With no tritond to ask, the command prints a warning and skips the check. --image-dir is not checked.
  7. 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. A lock on <INSTALL_DIR>/tritonadm.lock keeps two swaps or rollbacks from running at once. 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; `tritonadm self-update --rollback` puts it back

When tritond does not serve the candidate's admin API, the command fails and changes nothing:

the candidate speaks admin API <VERSION>, which the running tritond does not serve yet. Update tritond first (`tritonadm update tritond`), then self-update; --force swaps it anyway
FlagEffect
--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.
--checkReport 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.
--in-clusterUse the in-cluster channel. Conflicts with --channel-url, --channel, --revision, and --image-dir.
--rollbackPut tritonadm.prev back in place of the running binary. Conflicts with the source flags and --check.
--forceSwap in a build that the running tritond does not serve, or that the command could not check.

Roll back the CLI​

tritonadm.prev survives one update cycle, so you can reverse a bad release without a download. On the host where the binary is installed, as a user that can write to its directory:

tritonadm self-update --rollback

Output:

rolled back <INSTALL_DIR>/tritonadm to the previous build
the replaced binary is now <INSTALL_DIR>/tritonadm.prev

A second --rollback undoes the first. With no tritonadm.prev, the command fails with no <INSTALL_DIR>/tritonadm.prev to roll back to. To go back further, run tritonadm self-update --revision <REV> with a known-good sealed revision.

A tritonadm built against a newer admin API version than the running tritond serves fails every request with error (ApiVersionUnsupported): server does not support this API version: <VERSION> and exit status 5. Roll it back, update tritond, then update the CLI again.

Update the deployed cloud​

danger

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

Then apply:

tritonadm update

The whole-fleet run​

With no component, or with components drawn only from tritonadm, tritond, adminui, control-plane, and agents that include at least one of the last four, update runs one whole-fleet plan. tritonadm update tritonadm on its own updates the local binary instead, like self-update:

  1. Print the channel and revision, and a plan for every node.
  2. Check that each node's agent and the control plane keep a fleet API version in common. A plan that breaks that is refused unless you pass --force.
  3. Ask Proceed? once, unless you pass --yes.
  4. When the run includes tritonadm and the running tritond serves the new build's admin API, replace it, then run the new binary with the same arguments, pinned to the planned revision. When tritond does not serve it, or cannot be asked, keep the installed binary for steps 5 to 7 and replace it after step 7.
  5. Refresh the in-cluster channel and wait for the boot service mirrors.
  6. Snapshot the control-plane zone, then reprovision it from triton-platform.
  7. Refresh the agent on every selected node, and the sandbox runtime on each node that runs sandboxes or has a bundle.
  8. Print what each node runs.

tritond, adminui, and control-plane limit the run to the control plane, and agents limits it to the agents. --check and --dry-run stop after the plan. The whole-fleet run refuses a --channel or --channel-url that differs from the cluster's channel.upstream_url, because nodes update from the in-cluster copy of that channel.

FlagEffect
--cn <CN>Update the agent on this node only, by hostname or UUID. Repeatable. A named node is attempted even when its agent has gone quiet.
--hold <CN>Leave this node's agent and sandbox runtime as they are. Repeatable.
--forceRun a plan that leaves a node's agent and the control plane with no fleet API version in common. For recovery. Selected agents are refreshed over SSH from the head node, so a node that is cut off still receives its refresh when the run includes agents. Held and unreachable nodes are not refreshed.

--cn and --hold apply only to the whole-fleet run. With any other component they fail, and the message names tritonadm update and tritonadm update agents. Naming a host-local component together with a whole-fleet one fails, and the message tells you to run them separately.

Host-local components​

Every other component updates on the head node, as before. --all walks them all in this order: tritond, tritonagent, proteusadm, fdb, clickhouse, booter, dnsedge, portal, mantad, tritonadm. tritonadm runs last because it replaces the binary that drives the run.

tritonadm update tritonagent proteusadm
ComponentAliasesWhat the update does
tritonadmDelegates to self-update, with this run's channel or --image-dir.
tritondReprovisions the triton-tritond zone from the triton-platform image. Applies under --all, --image-dir, or --in-cluster. Named on its own, tritond takes the whole-fleet run.
adminuiadmin-backend, uiReprovisions the same triton-tritond zone. Named on its own, adminui takes the whole-fleet run. The aliases stay host-local.
tritonagentagentExtracts the agent bundle again under /opt/triton/tritonagent. Restarts its SMF service when the bundle changed.
proteusadmExtracts the bundle again. It has no SMF manifest, so no service is registered or restarted.
fdbtriton-fdb, triton-fdb0When the registry knows active FoundationDB members, tritond reprovisions each member on its own compute node, one at a time on a quorate cluster. Otherwise it reprovisions the local bootstrap zone from triton-platform.
clickhousetriton-clickhouseReprovisions the triton-clickhouse zone from the triton-platform image.
bootertriton-booter, triton-booter0Reprovisions the triton-booter0 zone from the triton-platform image.
dnsedgetriton-dnsedge, triton-dnsedge0Reprovisions the triton-dnsedge0 zone from the triton-platform image. Authoritative DNS stops until the zone is back.
portaltriton-portal, triton-portal0Reprovisions the triton-portal0 zone on this head node from the triton-platform image. When the zone's triton:portal_static_dir names a hand-copied UI, it clears that key and reboots the zone, so the portal serves the UI built into the image. Then it records the image in the zone's registration. A portal zone on another node is not updated.
mantadtriton-mantadWhen a managed mantad deployment exists, tritond reprovisions one member at a time. Otherwise it reprovisions every contiguous local triton-mantadN zone from triton-platform.

How a host-local run behaves​

update first plans every component without changes and prints a preview for each. Then it applies. Consequences of that split:

  • --check and --dry-run stop 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; skip or not in --image-dir; skip. An image prefixes the image name, as in triton-platform not in channel; skip.
  • A zone that does not exist is reported as zone <ALIAS> not provisioned; skip. update never provisions an absent zone.
  • For portal, the preview adds portal: will serve the image's UI instead of <DIR> (clears triton:portal_static_dir, reboots the zone) when the zone serves a hand-copied UI. That step counts as an update and needs the confirmation. It runs only once the zone is on the channel's image, so a run that failed before clearing the key finishes it next time. When the reboot fails after the key is cleared, the error names vmadm reboot <ZONE_UUID>. Run it, then run update portal again: a second run finds the key empty, does not reboot, and records the zone's image.
  • An unknown component name logs a warning to stderr, and the command skips it.
  • Zone lookup uses triton-fdb1 when triton-fdb0 is absent, and triton-tritond1 when triton-tritond is absent.
  • After a zone component's reprovision, and on any run that finds the zone already on the channel's image, update records that image in the zone's registration, which versions reads. The host-local mantad walk does not record its zones. When update has no session at all (no endpoint, no credential, and no local tritond socket), it skips that step. A failure to record prints a warning and does not fail the run.
  • A component that is already on the channel's stamp reports that and does nothing.
  • The tritonadm component is not counted in the --check and --dry-run totals. Under --check, its preview prints the tritonadm self-update --check command to run instead.
  • The managed fdb and mantad rolls run after the local walk.

One confirmation covers the local walk. 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 or --force to skip the prompt in automation.

FlagEffect
--allUpdate every host-local component that is present in both the source and the host.
--checkReport what is outdated. Changes nothing.
--dry-runPrint the planned actions. Changes nothing.
--yesSkip the confirmation prompt.
--forceOn a host-local run, skip the prompt as --yes does.
--channel-url <URL>Override the channel manifest URL. Defaults to the cluster's channel.upstream_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.
--in-clusterUpdate from the in-cluster channel that channel refresh or channel import published, with no public egress. Trusts the cluster's DC channel-signing key alongside the publisher key. Conflicts with --channel-url, --channel, --revision, and --image-dir.

agents cannot take --image-dir or --in-cluster, because agents update from the channel only.

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 fleet to a known-good revision:

tritonadm update --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, proteusadm, and sandbox-runtime. 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.

warning

--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​