Skip to main content

tritonadm setup

tritonadm setup creates the control plane on a single headnode and destroys it again. It has four subcommands: bootstrap, converge, apply, and destroy. One of them is required. setup on its own is a usage error.

All four subcommands act on the local host through nictagadm, dladm, ipadm, imgadm, vmadm, svccfg, and zlogin. For that reason, all four run in the head node global zone as root. None of them reads the global --endpoint or --api-key options. The dispatch arm for setup does not receive them.

Synopsis

tritonadm setup bootstrap [OPTIONS]
tritonadm setup converge [OPTIONS]
tritonadm setup apply [OPTIONS]
tritonadm setup destroy [--dry-run] [--yes]

Description

setup bootstrap is genesis. It installs the platform image, the founder FoundationDB and tritond zones, and the global-zone agents. It mints the credentials, approves the founder compute node, and imports the answers as the intent commit. It creates the DNS server and the first certificate that the answers request. It ends with the mandatory founder pivot. You can run it again after any interruption before the pivot. It refuses to run again after the pivot.

setup converge moves the observed state toward the committed cluster intent. It covers ClickHouse, DNS and certificate re-proof, mantad, the booter, and boot policy. Every step is re-entrant, so it can run on any coherent deployment state. It is the forward path for a genesis that stopped after the founder pivot.

setup apply runs bootstrap and convergence in one pass. It is the flag-driven lab path. Its plan-shaping options are the ones listed below.

setup apply installs the signed zone images. It creates the control-plane zones with their first-boot metadata in dependency order, with a health gate between them. It installs the global-zone agents and preserves the one-time root credential. It then runs the founder pivot, which replaces the bootstrap FoundationDB and tritond zones with their durable successors.

The command has two entry paths. The flag-derived path resolves a plan from the options below, an optional TOML file passed with --config, and host facts probed at run time. The --answers path reads a JSON answers document and resolves it against a facts snapshot. It prints a plan preview with fingerprint words and stops on error-severity findings. It then lowers the approved plan into a production plan and runs the same executor.

Two profiles shape the control network. In poc, the control plane uses a host-private illumos etherstub with fixed addresses. tritond gets a second NIC on the admin network for off-box reachability. In production, the control plane uses an operator-supplied nic_tag with explicit addresses.

The declared scope of setup is a SmartOS compute node that already has the zones pool and the admin nic_tag in place. setup creates no zpool. The only host networking it creates is the poc etherstub nic_tag, the global-zone vnic, and that vnic's address.

setup destroy takes no resource options. It probes the host for every resource that apply can create and destroys what is present. Configuration that changed after apply cannot change the target of the teardown.

Options

setup bootstrap, setup converge, and setup apply

The three subcommands accept the same option set. --answers selects the answers-document path. Every plan-shaping option is refused together with it.

OptionValueDefaultDescription
--answerspathnoneResolve this JSON answers document against facts, print the plan preview, then lower and apply the approved plan. Cannot be combined with the plan-shaping options listed under Answers documents.
--factspathlive gatherA captured facts snapshot to resolve --answers against. Requires --answers. Without it, facts are gathered from this machine with triton_facts::gather().
--configpathnoneTOML file of plan settings. Options on the command line win over the file. Keys are listed under Configuration file.
--fdb-ipIPv4 address192.168.250.2 in pocControl-network address for triton-fdb0. In production this option, or a discoverable running triton-fdb0, is required.
--tritond-ipIPv4 addressnoneControl-network address for triton-tritond. Required in production. In poc the address is fixed at 192.168.250.10 and this value is not read.
--tritond-admin-ipIPv4 addressDHCP leasepoc only: static admin-network address for the second NIC of tritond. In production this value is not read.
--mantad-ipIPv4 address192.168.250.12 in poc with --with-mantadAddress of a mantad node. Repeat for a multinode cluster. Conflicts with --mantad-nodes.
--mantad-nodesintegernoneNumber of mantad nodes. Addresses are allocated from free addresses on the control network. Conflicts with --mantad-ip.
--replicationinteger1 for fewer than 3 nodes, 3 at 3 or moreByte-plane replication factor. A value of 2 or higher with fewer than 3 nodes is refused. Accepted values are clamped to the range 1 through the node count.
--clickhouse-ipIPv4 address192.168.250.11 in poc when ClickHouse is enabledControl-network address for triton-clickhouse.
--netmaskdotted mask255.255.255.0Admin-network mask in poc. Control-network mask in production.
--gatewayIPv4 addressfirst default route from route -n get defaultAdmin-network gateway in poc. Control-network gateway in production.
--resolverIPv4 addressfirst nameserver line in /etc/resolv.confDNS resolver written into the zones.
--nic-tagnic_tag nameadminpoc only: nic_tag for the off-box admin NIC of tritond.
--profilepoc or productionproduction when --controller-nic-tag is set, poc otherwiseControl-plane profile. Any other value is rejected.
--controller-nic-tagnic_tag namenoneproduction: the private control-network nic_tag. Setting it selects the production profile.
--channel-urlURLthe stable channel manifestChannel manifest URL. Wins over --channel.
--channelchannel namestableNamed channel shorthand, expanded to the manifest URL of that channel.
--image-dirpathnoneInstall images and agents from a local directory of built artifacts instead of the signed channel. Bypasses the channel fetch and its signature check. --channel and --channel-url are then unused.
--with-mantadflagoffAlso provision the mantad (S3) zones.
--with-clickhouseflagon in poc, off in productionAlso provision the triton-clickhouse zone.
--no-clickhouseflagoffDo not provision ClickHouse. Overrides both the profile default and --with-clickhouse.
--fdb-secrethex stringdiscovered, else newly mintedPin the FoundationDB cluster secret. An empty value and the literal generate both use the default.
--fdb-memoryGiB integerclamp(host_ram_gb / 8, 2, 8)Memory for triton-fdb0. Host RAM comes from prtconf -m. When it cannot be detected, the value is 16 GiB, which yields 2 GiB.
--fdb-diskGiB integer20Disk quota for triton-fdb0.
--tritond-memoryGiB integer4Memory for triton-tritond.
--tritond-diskGiB integer20Disk quota for triton-tritond.
--clickhouse-memoryGiB integer8Memory for triton-clickhouse.
--clickhouse-diskGiB integer40Disk quota for triton-clickhouse.
--dry-runflagoffPrint the resolved plan and the planned changes. Change nothing.
--yesflagoffSkip the confirmation prompt shown before a run whose plan contains a destructive change. Visible alias: --force.
--insecure-issuerflagoffAccept a plaintext single sign-on issuer when the answers carry no dns block, or DNS without ACME. The issuer is immutable once a realm is seeded. Without a DNS name it is lost with the founder zone. Throwaway labs only.
--force-skip-dns-preflightflagoffContinue after a failed DNS delegation preflight. DNS and certificate issuance will not work until the delegation matches the plan.
--force-skip-cert-gateflagoffContinue after the genesis certificate-issuance gate when ACME did not issue a wildcard bundle inside the wait budget. The cluster starts without TLS until the certificate reconciler succeeds.

There is no option for mantad or booter sizing, and no --with-booter option. mantad and booter sizing come from fixed constants. The booter is enabled through the configuration file key with_booter or through an answers document.

setup destroy

OptionValueDefaultDescription
--dry-runflagoffPrint the teardown diff. Change nothing.
--yesflagoffSkip the teardown confirmation prompt. Visible alias: --force.

Configuration file

--config reads a TOML file. Every key is optional. An unrecognized key is a parse error. Command-line options win over file values.

KeyTypeEquivalent option
profilestring--profile
controller_nic_tagstring--controller-nic-tag
nic_tagstring--nic-tag
netmaskstring--netmask
gatewaystring--gateway
resolverstring--resolver
fdb_ipstring--fdb-ip
tritond_ipstring--tritond-ip
tritond_admin_ipstring--tritond-admin-ip
mantad_ipsarray of strings--mantad-ip
booter_ipstringnone
mantad_nodesinteger--mantad-nodes
replicationinteger--replication
clickhouse_ipstring--clickhouse-ip
with_mantadboolean--with-mantad
with_booterbooleannone
with_clickhouseboolean--with-clickhouse
fdb_memory_gbinteger--fdb-memory
fdb_disk_gbinteger--fdb-disk
tritond_memory_gbinteger--tritond-memory
tritond_disk_gbinteger--tritond-disk
clickhouse_memory_gbinteger--clickhouse-memory
clickhouse_disk_gbinteger--clickhouse-disk
channel_urlstring--channel-url
channelstring--channel

poc control network

The poc profile uses fixed names and addresses.

ResourceValue
Etherstub nic_tagtriton0
Global-zone vniccpgz0
Global-zone address192.168.250.1/24
Netmask255.255.255.0
triton-fdb0192.168.250.2
Reserved for triton-fdb1 and triton-fdb2192.168.250.3, 192.168.250.4
triton-tritond192.168.250.10
triton-clickhouse192.168.250.11
triton-mantad192.168.250.12
triton-booter192.168.250.13

Zone sizing

ZoneMemoryDisk
triton-fdb0clamp(host_ram_gb / 8, 2, 8) GiB20 GiB
triton-tritond4 GiB20 GiB
triton-clickhouse8 GiB40 GiB
triton-mantad4 GiB100 GiB
triton-booter02 GiB40 GiB

Every control-plane zone gets cpu_cap 200 and a delegated dataset. Every control NIC is net0 on the control nic_tag, with vlan_id 0, MTU 1500, and primary set. In the poc profile tritond also gets net1 on the admin nic_tag, and net1 becomes the primary NIC. net1 is static when --tritond-admin-ip is given and DHCP otherwise.

Behavior

Plan resolution

setup apply resolves the plan before it touches the host. It reads --config when given, probes host facts, and looks for an existing FoundationDB cluster.

Discovery reads the live cluster file from a running triton-fdb0 over zlogin. It tries /etc/fdb/fdb.cluster first and /data/etc/fdb/fdb.cluster second. If neither is present, it reads the zone metadata keys triton:fdb_cluster_secret and triton:fdb_cluster_peers. A cluster file whose description is not triton is ignored. A lookup error is propagated. It is not read as an absent cluster.

The FoundationDB cluster secret resolves in this order: --fdb-secret, then the secret discovered from a running triton-fdb0, then a newly minted random 128-bit hex value.

The production profile requires --controller-nic-tag, an --fdb-ip or a discoverable running triton-fdb0, and --tritond-ip. Each missing value produces its own error.

Answers documents

--answers is refused in combination with --config, --tritond-admin-ip, --mantad-ip, --mantad-nodes, --replication, --clickhouse-ip, --netmask, --gateway, --resolver, --nic-tag, --profile, --controller-nic-tag, --fdb-secret, --fdb-memory, --fdb-disk, --tritond-memory, --tritond-disk, --clickhouse-memory, --clickhouse-disk, --with-mantad, --with-clickhouse, and --no-clickhouse. The image-source and execution options remain legal.

The plan preview prints verbatim. Any error-severity finding stops the run before anything is touched. With --dry-run the run stops at the preview. The preview needs no addresses, so you can validate an answers document off-node against a --facts snapshot.

An answers document whose admin network declares infra_range owns the control-plane addresses. Passing --fdb-ip or --tritond-ip together with it is refused. Lowering sets profile=production. It takes the control nic_tag from the name of the network, the netmask from its CIDR, the gateway verbatim, and the resolver from the first entry. A derived address outside the declared CIDR is rejected.

Order of operations

setup apply runs in this order:

  1. Resolve the plan and print it.
  2. Load images and agents. Scan --image-dir, or fetch the channel manifest and verify its minisign signature against the publisher key compiled into the binary.
  3. Validate the resolved image set. triton-platform is always required. triton-clickhouse is required when ClickHouse is enabled.
  4. Refuse to continue when the founder pivot will run and the artifact source carries no tritonagent. --dry-run skips this check. A resolved FoundationDB address that is a comma-separated coordinator list also skips this check.
  5. Assemble the resource graph and print the planned changes. With --dry-run, stop here.
  6. Apply the graph, in graph order:
    1. poc control network: nictagadm add -l triton0, the cpgz0 vnic, and the 192.168.250.1/24 address.
    2. poc boot service site/triton-gz-vnic: the start-method script at /opt/triton/triton-gz-vnic/bin/triton-gz-vnic (mode 0755) and the manifest at /opt/triton/triton-gz-vnic/smf/triton-gz-vnic.xml (mode 0644), imported and enabled, with a copy under /opt/custom/smf so SmartOS imports it again at boot.
    3. imgadm install of triton-platform.
    4. vmadm create of triton-fdb0.
    5. FoundationDB genesis.
    6. vmadm create of triton-tritond.
    7. triton-clickhouse, when enabled.
    8. The tritonagent bundle, its agent.env, and its SMF service.
    9. The proteusadm bundle.
  7. Read the one-time root password from /data/state/tritond/server.out inside the tritond zone. Write /root/triton-root-password at mode 0600, with endpoint=, username=root, and password= lines.
  8. Configure the CLI against http://<TRITOND_IP>:8080 by exchanging that password for a token pair. This step is skipped when a session already resolves from a stored login, an API key, or the environment. A failure here is a warning, not a genesis failure.
  9. Register the genesis zones in the infrastructure-zone registry of the control plane. The tritond zone is skipped when the founder pivot will run.
  10. Run the founder pivot.
  11. Write the ClickHouse integration settings. Restart the surviving tritond when a restart-required setting changed. Verify the result.
  12. Provision the mantad zones through the surviving control plane, when enabled.
  13. Register the mantad cluster in the storage registry, when the answers document declared manta.cluster_name. A failure is a warning.
  14. Provision triton-booter0 through the surviving control plane, when enabled.
  15. Print the summary.

A dry run still resolves the plan, fetches and verifies the channel manifest, and validates the image set. Those steps come before the graph diff.

Readiness gates

triton-fdb0 is created with no readiness probe. The genesis step that follows retries the cluster-creation command instead. triton-tritond gates on an HTTP success from http://<TRITOND_IP>:8080/v1/health, and its readiness is required. triton-clickhouse gates on http://<CLICKHOUSE_IP>:8123/ping, and its readiness is best-effort. Metrics never block the run.

GateBudgetPoll interval
HTTP readiness180 seconds4 seconds
Zone-file readiness240 seconds4 seconds
SMF service settle180 seconds2 seconds

An HTTP or zone-file gate logs a still-waiting milestone every 30 seconds.

FoundationDB genesis

Genesis is the single cluster-creation step, and it is authorization-gated. It runs fdbcli --exec "configure new single ssd" inside the zone only when /data/version is absent and /data/fdb-genesis.pending contains the literal 730. A /data/version that holds any other value refuses genesis. A missing /data/version on its own is not authority to run the command.

Genesis waits up to 30 seconds for the pending marker and up to 120 seconds for the database to report available. It polls every 250 milliseconds. It then revokes the zone metadata capability and stamps /data/version. On failure it collects diagnostics from the zone: svcs -xv site/triton-fdb, pgrep -fl fdbserver, the SMF log, the fdbserver log, and the recovery trace.

Founder pivot

The founder pivot runs at the end of every bootstrap and apply. It exits without action when the run has no triton-fdb0 zone to retire. Its steps:

  1. Reserve two free control-network addresses for the replacements.
  2. Approve the founder compute node. Poll the compute-node list and retry when the claim code has rotated.
  3. Grow triton-fdb1 through the plan, approve, and grow path.
  4. Provision triton-tritond1 through the control plane with first-boot peers that name both FoundationDB members. Gate on its /v1/health, then require an authenticated, store-backed read to succeed.
  5. Rewrite TRITONAGENT_ENDPOINT in agent.env and the stored CLI endpoint to point at triton-tritond1.
  6. Disable tritonagent synchronously, vmadm delete the founder tritond zone, then enable the agent again.
  7. Decommission and destroy triton-fdb0 through the plan, approve, and decommission path.
  8. Import the approved answers and their hashes into the control plane and read them back, when the run came from an answers document.
  9. Read the post-swap cluster status. Fail the run unless it reports both available and quorum reachable.
WaitBudget
Each grow, provision, and decommission operation20 minutes
Founder compute node reaching Approved5 minutes
Replacement tritond serving a store-backed read180 seconds

Operations are polled every 2 seconds. A pivot failure fails the run. The message states that genesis is not complete.

Running setup apply again after a successful pivot is not a supported flow. The resource graph still names triton-fdb0 and triton-tritond, so a second run creates them again as stray zones. The source records this as a known limitation and directs later changes through the control-plane paths.

Confirmation

apply prints the planned diff first. When the plan contains a destructive change and --yes was not passed, it prompts Apply the changes above? This modifies existing resources. with a default of No. A purely additive first-run bring-up applies with no prompt.

destroy prints the diff. It reports nothing to destroy. when the plan has no changes. Otherwise it prompts Tear down the resources above? This is destructive. with a default of No, unless --yes was passed.

Managed files and services

Zone images are staged into a temporary directory under /var/tmp. They are streamed to disk while hashing, verified against the manifest sha256, and installed with imgadm install -m <MANIFEST> -f <CONTENT>. An already-installed uuid is skipped.

Global-zone agent bundles extract under /opt/triton/<NAME> with /usr/bin/gtar and --no-overwrite-dir. Absolute paths and .. segments in a bundle are rejected. The installed version is read from /opt/triton/<NAME>/etc/version, so an install is idempotent on the stamp.

apply writes /opt/triton/tritonagent/etc/agent.env at mode 0644. It manages only the TRITONAGENT_ENDPOINT key, set to http://<TRITOND_IP>:8080. Operator-added keys such as RUST_LOG survive later applies. The tritonagent SMF service restarts when the bundle was extracted again or agent.env changed. proteusadm ships no SMF manifest, so no service is registered or restarted for it.

Summary output

The summary banner reports the admin UI at http://<HOST>:8081, the tritond API at http://<TRITOND_IP>:8080, the root-credential handoff path, each mantad S3 endpoint at port 7443, the booter health URL, and ClickHouse at port 8123. Its next-step lines name tritonadm api-key create. For a run that could not configure the CLI, they also name tritonadm configure --endpoint.

Teardown

setup destroy runs the same graph shape in reverse. It removes these resources, in order:

  1. The proteusadm bundle.
  2. The tritonagent bundle, its managed agent.env key, and its SMF service.
  3. triton-clickhouse and its image.
  4. The control-plane zones and every image uuid they reported.
  5. The site/triton-gz-vnic boot service and its files.
  6. The poc control network, with nictagadm delete -f.

The control-plane zone list is triton-fdb0, triton-tritond, triton-mantad0, and triton-booter0, plus every contiguous numbered triton-fdbN, triton-tritondN, and triton-mantadN found on the host, plus the legacy unindexed triton-mantad. Image uuids are read from the running zones, not from a channel manifest, so teardown works offline. A resource that is not present is a no-op. For that reason, the fixed poc network names are always attempted.

Only the TRITONAGENT_ENDPOINT key is removed from agent.env. The file is removed only when nothing else remains in it.

See also