CLI Reference
cenvero-str-ctl is the operator interface to a node. It talks to the running
agent over a local socket, so it only works on the node itself and needs
root for any command that changes state. The socket is always available — it is
the node's management lifeline and can never be disabled.
cenvero-str-ctl <group> <command> [args] [flags]
- Add
--format json(oryaml) to any command for machine-readable output (the default is a human table/JSON view). - Add
-hto any group or command for its full help, subcommands, and flags. - The same managers are reachable over the node's REST API; this CLI is the local equivalent.
The command groups, by area:
| Area | Groups |
|---|---|
| Status & system | status version metrics hardware pull |
| System management | config service tls update license |
| Networking | network nic ipam dhcp dns vlan vxlan geneve vrf route |
| Security | firewall rules |
| Traffic shaping & visibility | bandwidth quota flow |
| Services & HA | lb l7lb bgp gateway nat64 ha bond cluster |
| Tenants & billing | tenant apikeys billing |
| Operations | task backup alert heal container plugin node audit |
Status & system
status
cenvero-str-ctl status # health summary: version, license, data plane, bridges, cluster
version
cenvero-str-ctl version # agent version
metrics
cenvero-str-ctl metrics # current metrics snapshot
hardware
Print this machine's hardware ID — the value an activation or SSL request is bound to. Use it to verify a pending request in your account before approving it.
cenvero-str-ctl hardware
pull
Force an immediate pull of the node's CA-signed TLS certificate and a license re-sync (fetch a pending activation, auto-renew, re-evaluate) now, instead of waiting for the next background poll. Run it right after approving a node's SSL/license in your account.
sudo cenvero-str-ctl pull
System management
config
| Command | Purpose |
|---|---|
config set [<key> <value>] | Change a whitelisted operational setting (run with no args to list keys) |
config show | Print the decoded on-disk configuration (secrets redacted) |
config dump | Dump the on-disk configuration |
config encode | Write the node's signed configuration from flags (used by the installer) |
config set writes to an operator local-overrides file that the agent layers
on top of its configuration at the next restart — and that a panel re-sync will
not clobber (local always wins). Use the positional config set <key> <value>
form, or the --api-bind / --api-rate-limit / --api-rate-burst shortcuts.
Apply with systemctl restart cenvero-stratum; verify with config show.
sudo cenvero-str-ctl config set api_rate_limit 2000
sudo cenvero-str-ctl config set --api-bind 10.0.0.5 --api-rate-limit 2000 --api-rate-burst 200
sudo cenvero-str-ctl config set # list every settable key
Settable keys: log_level, api_bind_address, api_rate_limit,
api_rate_burst, api_allowed_ips, api_allowed_origins,
api_read_timeout_secs, api_write_timeout_secs, api_idle_timeout_secs,
port_rest, port_grpc, port_websocket,
metrics_bind_addr, dns_listen_addr, dns_allowed_clients, dns_upstreams,
heal_interval_seconds, heal_disabled_checks, interface_reconcile_mode,
interface_hard_block, allow_untranslated_private_egress, and the six service switches (rest_disabled,
grpc_disabled, websocket_disabled, metrics_disabled, dns_disabled,
dhcp_disabled). Identity, the license server, the API token, the HA pair's
shared key and the TLS paths are refused — they are panel- or
identity-owned, not local operational settings. The cluster_* keys are
refused with what to run instead: a cluster is formed with cluster create
and joined with cluster join --code. The cluster and HA heartbeat ports
(port_cluster, port_ha_heartbeat) are refused too: the other nodes connect
to the fixed ports. See
Configuration for the full field reference.
config show / dump are read-only and decode the actual on-disk file (table,
--format json, or --format yaml); pass --include-secrets to reveal redacted
values, or --file <path> to inspect a specific file. config encode is what the
installer uses to write the node's configuration and prints the resulting
api_token.
service
See and toggle the agent's network services. service status shows each service's
ENABLED switch, its ADDRESS:PORT, and a live STATE. Toggle a service on
or off; the change applies on the next agent restart.
| Command | Purpose |
|---|---|
service status | Show each service (aliases: list, top, ls, ps) |
service <name> on | Enable a service (also service on <name>) |
service <name> off | Disable a service (also service off <name>) |
Toggleable services: rest, grpc, websocket, metrics, dns, dhcp.
Disabling rest warns first (it also serves the operator/billing API). The **IPC
control socket is not toggleable** — it is how this CLI reaches the agent.
sudo cenvero-str-ctl service status
sudo cenvero-str-ctl service rest off
sudo cenvero-str-ctl service websocket on
sudo systemctl restart cenvero-stratum # apply
Enabling rest, grpc or websocket is only half of it — the management APIs
also require an API token before they will serve, so a service you switch on with
no token configured stays down. See api-token below.
api-token
Manage the bearer token the management APIs (REST, gRPC, WebSocket) require. With no token the agent refuses to open a management API at all rather than serve one without a credential, so this is what turns them on.
| Command | Purpose |
|---|---|
api-token generate | Mint a strong random token, store it, print it once |
api-token set | Store a token you supply, read from stdin |
api-token status | Report whether a token is set — never prints the value |
api-token clear | Remove it; the APIs stop serving at the next restart |
sudo cenvero-str-ctl api-token generate
sudo cenvero-str-ctl service on rest
sudo systemctl restart cenvero-stratum
generate shows the token once and it is not recoverable afterwards — copy it
then. To choose the value yourself, pipe it in so it never reaches your shell
history; there is deliberately no flag to pass it as an argument:
printf '%s' "$MY_TOKEN" | sudo cenvero-str-ctl api-token set
Tokens shorter than 16 characters are refused. The value is stored in your local
overrides, so a later configuration sync from the panel will not discard it. It is
not settable through config set, which rejects credential keys for the same
shell-history reason.
A management API binds only when all three hold: a token exists, the service is on, and the node has a TLS certificate — the agent never serves plaintext.
tls
Manage the management API's TLS certificate. After install the node serves a temporary self-signed certificate; in CA mode it obtains a CA-signed certificate once you approve the request in your account (Certificates). The private key never leaves the node.
| Command | Purpose |
|---|---|
tls info | Live certificate: mode (ca-signed/self-signed), expiry, SAN domains |
tls show | The certificate / key / public-key file locations |
tls pubkey | Print the public-key file location |
tls request | Request a CA-signed certificate from the panel now (online) |
tls pull | Pull this node's CA-signed certificate now (collect it once approved) |
tls regenerate | Generate a fresh certificate now (hot-reloaded, no restart) |
tls csr | Generate a key + CSR locally without contacting the panel (offline) |
tls install <cert> [chain] | Install a signed certificate obtained out-of-band |
tls pending-status | Report any pending certificate request (online or offline) |
tls reset-pending | Discard a pending offline CSR so you can start fresh |
tls reset | Clear the current certificate + pending request and re-obtain a fresh one |
tls domain list | List the hostnames the certificate is asked to cover |
tls domain add <domain> | Add a hostname and request a new certificate (waits for your approval in CA mode) |
tls domain remove <domain> | Remove a hostname and request a new certificate (waits for your approval in CA mode) |
sudo cenvero-str-ctl tls info
sudo cenvero-str-ctl tls pull # collect the CA-signed cert after approval
sudo cenvero-str-ctl tls domain add api.example.net
The certificate always covers the node's IP(s) plus loopback; a hostname you point
at the node's IP can be added with tls domain add. Names must be plain hostnames
— no wildcards or IP addresses. In CA mode the new certificate waits for your
approval: the command saves the name and reports "status": "pending" (exit code
0). Once approved the node installs it automatically, or collect it at once with
tls pull. See TLS & Licensing.
update
Pull-based agent updates from your licensed release channel.
| Command | Purpose |
|---|---|
update check | Report current vs latest version + channel (no download) |
update apply | Download, verify, and apply an available update now (alias update now) |
update rollback | Roll back to the previously-installed version |
cenvero-str-ctl update check
sudo cenvero-str-ctl update apply
sudo cenvero-str-ctl update rollback # undo the last apply
update apply verifies the download's signature, swaps the binary atomically, and
restarts under watchdog supervision with self-rollback if the post-restart health
check fails. A node in the Frozen license state keeps running but cannot pull
updates until the license is renewed. See Upgrades.
update rollback restores the binary that the most recent update apply
preserved, undoing that update; restart the agent (systemctl restart
cenvero-stratum) to run the restored version. If no update has been applied on
this node there is nothing to restore and it reports *"no previous version to roll
back to"*. Rollback is a change, so it is refused while the license is Frozen.
Re-applying a version at or below the highest version this node has ever run is
refused by downgrade protection — to move forward again, install a newer release.
license
| Command | Purpose |
|---|---|
license activate <license-key> | Send this machine's activation request (confirm it in your account) |
license fetch <license-key> | Fetch the signed license once it has been confirmed |
license renew | Force a license renewal for this machine |
license refresh | Re-fetch the signed license for this machine |
license load <file> | Load a signed license file manually |
license status | Full installed-license picture: identity, validity/state, features, hardware binding |
The license key is positional, not a flag. Activation binds the license to this machine's hardware ID and waits for you to confirm the machine in your account; the agent then installs the signed license automatically.
Every command that installs a license (activate once confirmed, fetch, renew,
refresh, load) has the running agent load it at once. If the agent is not
running, the license is still saved, and the agent loads it when it starts.
sudo cenvero-str-ctl license activate CNVR-XXXX-XXXX-XXXX-XXXX
sudo cenvero-str-ctl license status
license status is read-only and works offline from on-disk state, so it still
answers when the agent is down or the node cannot reach the license server.
The same picture is available over the API as GET /api/v1/license, which reads
the running agent rather than the disk — useful for checking a fleet's expiry
dates without a shell on every box. See API Reference.
See Licensing for the warning → grace → freeze model.
Networking
network
A network is a managed private network: a CIDR pool whose usable host IPs are each materialized into an endpoint profile (a fixed IP paired with a generated MAC). You attach a workload by claiming a free endpoint — the endpoint is the workload's network identity.
| Command | Purpose |
|---|---|
network create | Create a network (--name --cidr [--gateway --vlan --tenant] [--host-gateway [--snat] [--dhcp]]) |
network host-gateway <id> [--snat] [--dhcp] or network host-gateway <id> --off | Set a network's host gateway; the flags given are the whole setting |
network list | List networks |
network show <id> | Network detail + its endpoints |
network endpoints <id> | List a network's endpoint profiles (IP ↔ MAC) |
network attach <id> [--ip] [--mac] | Claim an endpoint (optionally a specific IP and MAC) |
network set-mac <endpoint-id> <mac> | Change an endpoint's MAC, keeping its IP |
network detach <endpoint-id> | Free a bound endpoint |
network delete <id> | Delete a network |
sudo cenvero-str-ctl network create --name app-net --cidr 10.20.0.0/24 --gateway 10.20.0.1
sudo cenvero-str-ctl network attach <network-id> --ip 10.20.0.50
Each endpoint is an IP paired with a MAC address, and the MAC is assigned for you.
Pass --mac when the workload already has a fixed address of its own — a virtual
machine image, or an appliance whose license is tied to one — so the fabric
accepts the address it will actually send from:
sudo cenvero-str-ctl network attach <network-id> --ip 10.20.0.50 --mac 52:54:00:ab:01:02
# ...or change it afterwards, keeping the same IP
sudo cenvero-str-ctl network set-mac <endpoint-id> 52:54:00:ab:01:02
A MAC must be unique across endpoints, and a multicast address is refused — one can never be a source address, so traffic from it would be dropped.
--host-gateway puts the network's gateway on the node so workloads can reach
it; --snat adds internet access through the node's public address (the node's
uplink must be configured) and --dhcp serves the network over DHCP. See
The host gateway.
sudo cenvero-str-ctl network create --name web --cidr 10.60.0.0/24 --gateway 10.60.0.1 --host-gateway --snat
sudo cenvero-str-ctl network host-gateway <network-id> --off
routed
Public addresses your provider routes to this server, handed to virtual machines
one at a time (vm create --public-ip auto|<address>). See
Public Addresses.
| Command | Purpose |
|---|---|
routed add <address or prefix> [--tenant T] [--description TEXT] | Add one address or a block (up to a /20); --tenant reserves it for one tenant |
routed list [--tenant T] | The blocks, what is free, and which virtual machine uses each address |
routed remove <id or prefix> | Remove a block no virtual machine uses |
sudo cenvero-str-ctl routed add 203.0.113.16/29 --description "provider subnet"
cenvero-str-ctl routed list
nic
| Command | Purpose |
|---|---|
nic list | List detected network interfaces |
nic detect | Re-scan and list interfaces |
nic accel | Show the acceleration mode (hardware vs software) per interface |
ipam
| Command | Purpose |
|---|---|
ipam pools | List IP pools |
ipam allocations | List every allocation (optional tenant id) |
ipam allocate | Allocate an IP address |
ipam release | Release an IP address |
dhcp
| Command | Purpose |
|---|---|
dhcp leases | List DHCP leases |
dhcp reservations | List static MAC→IP reservations |
dhcp reserve <mac> <ip> [--hostname] | Pin a static MAC→IP reservation |
dhcp release <mac> | Remove a static reservation, returning the address to the pool |
sudo cenvero-str-ctl dhcp reserve 52:54:00:ab:01:02 10.0.0.50 --hostname db01
A reserved address is handed out on the client's next request, survives an agent
restart, and appears immediately in dhcp leases.
dns
Manage authoritative zones, records, recursive forwarders, and DNSSEC.
| Command | Purpose |
|---|---|
dns zones | List zones |
dns records [zone_id] / dns list [zone_id] | List records (optionally for one zone) |
dns add <zone_id> <name> <type> <value> [ttl] [source_subnet] | Add a record |
dns delete <record_id> | Delete a record |
dns dnssec <zone> | Show a zone's DNSSEC keys + the DS record to lodge with the parent |
dns zone list/add <name>/delete <zone_id> | Zone CRUD |
dns record list [zone_id]/add .../delete <record_id> | Record CRUD |
dns forwarder list/set <ip…>/add <ip…>/remove <ip…> | Manage recursive forwarders |
Each forwarder is an IP or IP:port (bare IPs default to :53). dns forwarder
changes apply to the running agent; persist them across restarts with
config set dns_upstreams <ip,...>.
sudo cenvero-str-ctl dns zone add app-net.internal
sudo cenvero-str-ctl dns add 1 api A 10.20.0.55 300
vlan
A per-VLAN allow/deny table. An empty table means every VLAN is allowed (default).
| Command | Purpose |
|---|---|
vlan list | List the allow/deny policy |
vlan deny <id> | Lock down a VLAN |
vlan allow <id> | Record an explicit allow |
vlan clear <id> | Clear a VLAN's policy (back to default-open) |
vxlan
| Command | Purpose |
|---|---|
vxlan list | List overlay networks |
vxlan create <vni> <subnet> | Create an overlay network |
vxlan delete <vni> | Delete an overlay network |
vxlan peers <vni> | List a VNI's remote peers |
vxlan peer-add <vni> <host> <mac> <vtep_ip> | Add a remote peer — vtep_ip must be an IP address; pass "" as <mac> when you do not know it (broadcast and unknown traffic is then sent to the peer, and its addresses are learned) |
vxlan peer-remove <vni> <host> | Remove a remote peer |
vxlan fdb | Dump the overlay forwarding database |
route
Static routes (optionally in a non-main table) and the policy rules that steer traffic into those tables.
| Command | Purpose |
|---|---|
route list [table] | List routes (optional table id) |
route add <json> | Add a route — JSON {destination,gateway,interface,metric,table} |
route delete <id> | Delete a route by id |
route rule list | List policy-routing rules |
route rule add <json> | Add a rule — JSON {priority,from,to,fwmark,iif,oif,table} |
route rule delete <id> | Delete a policy-routing rule by id |
Security
firewall
| Command | Purpose |
|---|---|
firewall allow <json> | Add an allow rule — JSON rule object, e.g. '{"source_ip":"10.20.0.0/24","protocol":"tcp","dest_port":443}' |
firewall deny <json> | Add a deny rule (same JSON rule object) |
firewall list | List firewall rules; a rule saved with a setting that is not enforced carries not_enforced entries |
firewall delete <id> | Delete a rule |
firewall default | Show the default action for traffic no rule matches (allow or deny) |
firewall default set <action> | Set the default action, allow or deny (kept across restarts) |
firewall conntrack | Show the connection-tracking table |
firewall conntrack-flush [ipv4] | Drop connection-tracking state so rule changes apply to connections that are already open (optionally just one peer) |
firewall schedule set/clear/list | Attach a time-of-day/day-of-week activation window (UTC) to a rule |
firewall connlimit set/clear/status | Per-source concurrent-connection limits (IPv4) |
A rule may match protocol (tcp, udp, icmp), source_ip, dest_ip,
source_port, dest_port (with dest_port_max for a range), interface,
mac, level and priority. Every rule is stateful and applies to traffic
arriving at the node, so chain and stateful can be left out; any other value
for them, an unrecognised key, or an address, MAC or protocol that cannot be
read is refused with an error. See Firewall.
On a member of a cluster, firewall deny refuses a rule whose source is a
member's address when it could drop the cluster's own traffic. See
Members' addresses are never blocked.
rules
The structured firewall rule table (chains, priorities, stateful matching).
| Command | Purpose |
|---|---|
rules list | List all rules |
rules add | Add a rule |
rules remove <id> | Remove a rule by id |
rules preset <web/db/mail/game/minimal/open> | Apply a server preset rule-set atomically |
rules batch <json-rule-array> | Apply a JSON array of rules atomically |
On a member of a cluster, a rule that drops or rejects a member's address is
refused, and the answer says to take that member out with
cluster remove <node-id> first: a block of it would cut this node off from
it. See
Members' addresses are never blocked.
Traffic shaping & visibility
bandwidth
| Command | Purpose |
|---|---|
bandwidth list | List per-MAC rate limits and shared pools |
bandwidth set <json-limit> | Create/update a per-MAC rate limit |
bandwidth delete <id> | Remove a per-MAC rate limit — that MAC is no longer shaped |
bandwidth pool | Show limits and pools (the same view as list) |
Shared pools are created and filled over the API (/api/v1/bandwidth/pools) — see
API Reference.
quota
Monthly per-MAC usage caps that reset at the start of each UTC month.
| Command | Purpose |
|---|---|
quota list | List quotas with their status |
quota set <json> | Create/update a quota |
quota get <mac> | Show one MAC's quota + status |
flow
| Command | Purpose |
|---|---|
flow list | List active flows (optional state filter) |
flow stats | Aggregate flow statistics |
Services & HA
lb
L4 virtual IPs (VIPs) with a backend pool.
| Command | Purpose |
|---|---|
lb list | List VIPs |
lb create | Create a VIP and backend set |
lb show | Show a VIP's detail |
lb backends <id> | List a VIP's backends |
lb add-backend / lb remove-backend | Adjust backends live |
lb drain <vip_id> <backend_id> | Stop sending new connections to a backend and let the existing ones finish |
lb set-health <vip_id> <backend_id> <up/down> | Force one backend up or down by hand — a manual override, not the health-check setup (a configured check can flip it back on its next probe) |
lb delete | Delete a VIP |
bgp
| Command | Purpose |
|---|---|
bgp status | Engine status |
bgp neighbors | List peers |
bgp routes / bgp rib / bgp fib | Route table / RIB / forwarding table |
bgp peer | Manage peers (add/list/remove) |
bgp announce / bgp withdraw | Advertise / withdraw a prefix |
bgp announcements | List active announcements |
bgp prefix-list | Manage prefix-lists (add <json> / list) |
bgp route-map | Manage route-maps (add <json> / list) |
bgp policy | Bind import/export route-maps (import/export <neighbor> <route-map> / list) |
bgp import-policy | Manage import policy |
gateway
| Command | Purpose |
|---|---|
gateway status | HA status of this node and its peer |
gateway failover | Yield the VIP to the peer now |
gateway failback | Take the VIP back when this node is the preferred owner |
ha
Gateway high-availability: two paired nodes run active/standby and the active node
owns a virtual IP (VIP), taking it over on failover. A node with no peer is
active and holds its VIP itself.
| Command | Purpose |
|---|---|
ha status | Show HA status (active/standby/solo, VIP, peer) |
ha set-peer | Refused: the pair's settings cannot be set on the node |
ha configure | Refused: the pair's settings cannot be set on the node |
A pair's settings (peer address, priority, VIP, and a shared secret) reach a
node only in its delivered configuration, read at agent boot; setting up a pair
yourself comes in a later release (see
Gateway High Availability). Use
ha status (or gateway status) for live status and gateway failover /
gateway failback for manual moves; the same are on the REST API.
bond
Combine physical NICs into a bond for redundancy or throughput. A bond is created
with a device name you choose (use the cnv- prefix, max 15 chars) in one of two
modes: active-backup (one member carries traffic, another takes over on failure)
or 802.3ad (LACP aggregation, needs a matching switch port-channel).
| Command | Purpose |
|---|---|
bond list | List bonds |
bond show <id> | Show a bond (mode, MTU, active member, members) |
bond create --name <dev> --mode active-backup/802.3ad [--mtu N] | Create a bond |
bond add-member <id> --iface <nic> | Enslave a NIC |
bond remove-member <id> --iface <nic> | Release a NIC |
bond set-mtu <id> --mtu N | Set the MTU across the bond + members |
bond delete <id> | Delete a bond (releases its members first) |
sudo cenvero-str-ctl bond create --name cnv-bond0 --mode active-backup
sudo cenvero-str-ctl bond add-member <bond-id> --iface cnv-nic-1
sudo cenvero-str-ctl bond set-mtu <bond-id> --mtu 9000
create prints the bond's logical id (e.g. bond-1a2b…); use that id — not the
device name — with the other subcommands. Members are referenced by interface name.
cluster
Form a cluster, join one, and manage its members (agent 1.0.0-rc.81 or later on
every member; see Clustering Overview). Every one
runs from any member: a change that only the cluster's leader can make is passed
to it. Most need clustering in the node's licence. Five work whatever the
licence says, without clustering in it and while it is frozen: status,
join-code list, join-code revoke, remove and leave. forget always
works, as root on the node itself.
| Command | Purpose |
|---|---|
cluster status | This node's role (leader, follower, candidate; disabled on a node that is not in a cluster, not running when it could not start — the agent log says why), the leader, the cluster's id and name, how many members vote, and every member: its id, name, address, role, whether it votes, whether it is online and when it was last seen. On a member that is not taking part in its cluster, error says why (see Clustering Overview). Works without clustering in the licence |
cluster create --name <name> --bind <ip> [--wait] | Form a cluster with this node as its first member. --bind is this node's own address for the others (port 7073) |
cluster join-code create [--expires 15m] | Make a join code: shown once, works once, expires after --expires (60s to 24h; 15 minutes by default) |
cluster join-code list | The join codes, with their state (active, used, revoked, expired), who made them and which node used them — never the codes. Works without clustering in the licence |
cluster join-code revoke <id> | Withdraw a code that has not been used. Works without clustering in the licence and while it is frozen |
cluster join --code <code> --bind <ip> [--adopt-cluster-tenants] [--wait] | Join this node to a cluster. --code - reads the code from standard input. --adopt-cluster-tenants lets the cluster's tenant records win over this node's where they conflict |
cluster remove <node-id> | Take a member out of the cluster; the others refuse it at once. Works without clustering in the licence and while it is frozen |
cluster leave | Take this node out of its cluster; it becomes standalone and keeps its own objects. On a member that is not the leader it answers once the leader has taken it out; if the leader's answer is lost, it is refused and says what to run (see Remove a node, or leave). Works without clustering in the licence and while it is frozen |
cluster rekey [<node-id>] [--wait] | Give a member (this node when none is named) a new identity |
cluster ca rotate [--wait] | Replace the cluster's certificate authority; the members keep their identities and move to the new one |
cluster forget --yes | Make this node standalone without the others' agreement — for a node removed while it was down, or whose identity expired. Root, on the node itself; changes nothing on the others |
The commands that start work — create, join --code, rekey, ca rotate —
answer with a task at once; --wait follows it until it
ends.
# On the first node
sudo cenvero-str-ctl cluster create --name prod --bind 10.0.0.5 --wait
# On any member: a code for the next node
sudo cenvero-str-ctl cluster join-code create --expires 30m
# On the new node: paste the code and press Enter (it is read from standard input)
sudo cenvero-str-ctl cluster join --code - --bind 10.0.0.6 --wait
sudo cenvero-str-ctl cluster status
The cluster commands manage the whole cluster from any member; the other
command groups work on the node they run on. Manage another member's machines,
networks and other objects from the web console or
the API.
Two commands are only for a cluster set up by hand with an earlier version,
before join codes existed: cluster join <node-id> <address>, run on its
leader, adds a member (a cluster formed with join codes refuses it: add nodes
with a join code), and cluster pin-members, run on its leader, records the
identity of every member so they can use the features above. cluster profile
still exists but is refused: every node runs the same services.
Tenants & billing
tenant
Tenants are your downstream customers on this node, each with a resource quota and optional scoped API keys.
| Command | Purpose |
|---|---|
tenant list | List tenants |
tenant create --name <name> | Create a tenant |
tenant delete <id> | Delete a tenant — also removes its scoped API keys, quota, private networks, and IPAM pools/allocations |
tenant quota <id> | Show a tenant's bandwidth cap, and its virtual machine cap and count on this node |
tenant quota-set <id> --max-bandwidth-bps N | Set a tenant's bandwidth cap (0 = unlimited). Only what you pass changes; nothing to change, a negative value, or an unknown tenant is refused |
tenant quota-set <id> --max-vms N | Cap the tenant's virtual machines on this node (0 = unlimited; Compute, early access). Lowering it never touches existing machines |
tenant key-generate <id> [--name <label>] [--ttl 720h] | Mint a scoped API key for a tenant |
tenant key-list <id> | List a tenant's scoped API keys |
tenant key-revoke <key-id> | Revoke a scoped API key |
A scoped key authenticates as the tenant but is confined to that tenant's resources: it can read its tenant, quota and billing state, manage its own tenant's keys, and see and run its own machines (start, stop, restart, consoles, password resets) — the web console's customer portal — but creating or deleting machines, networks or volumes and changing the tenant, its quota or its billing state (suspend, resume, limit) stay with the operator. The secret is shown only once, at mint time.
apikeys
Operator API keys for the billing API. A minted key authenticates your billing
system against the agent's /api/v1/billing endpoints.
| Command | Purpose |
|---|---|
apikeys mint <label> | Mint a new key (secret shown once) |
apikeys list | List keys (no secrets) |
apikeys revoke <id> | Revoke a key by id |
billing
Drive one of your customers' (a tenant's) account state — the same actions your billing system calls over REST.
| Command | Purpose |
|---|---|
billing suspend <tenant-id> | Suspend a tenant |
billing resume <tenant-id> | Resume a tenant |
billing limit <tenant-id> --rate-mbps N | Apply an aggregate rate cap (Mbps; 0 = unlimited) |
billing unlimit <tenant-id> | Remove a tenant's rate limit |
billing status <tenant-id> | Show a tenant's billing state |
See Billing Integration.
Operations
task
Every operation on a virtual machine, an image or a volume is recorded as a
task: who started it, what it acts on, how far it got, a log, and how it ended.
The commands that start one print its id in their answer ("task").
| Command | Purpose |
|---|---|
task list [--state S] [--type T] [--object ID] [--owner ID] [--tenant T] [--since WHEN] [--limit N] | Tasks, newest first. --state takes a comma-separated list (queued, running, succeeded, failed, cancelled, interrupted); --type a type (vm.start) or a prefix ending in a dot (backup.); --object a machine, image, volume, snapshot or backup id; --owner a key id, or root for this command line; --since a time (2026-09-29T12:00:00Z) or a duration back from now (24h) |
task show <id> | One task: state, progress, who started it, when |
task log <id> [--start N] [--follow] | Its log as text; --follow keeps printing until the task ends. --format json prints the page as it comes from the agent |
task cancel <id> | Stop an image download or import, a backup or a restore; anything else finishes or rolls back on its own |
cenvero-str-ctl task list --state running
cenvero-str-ctl task log tsk-3f2a0c1e9b7d-0mumq7fmz-a05dee --follow
A task that was running when the agent stopped reads interrupted until the
agent, once running again, finishes or undoes the operation; the task then ends
with that outcome, and its log says so. Tasks are kept for 30 days (at most
20,000). The same tasks are served at /api/v1/tasks (see
API Reference).
backup
| Command | Purpose |
|---|---|
backup create [config/full] | Create a backup (default config) |
backup restore <id/path> | Unpack a full backup into the node's restore/ area; to complete the rollback, stop the agent, put the unpacked snapshot in place, and start it again. A config backup is an export for your records and is refused |
backup list | List backups |
backup schedule add <expression> [config/full] [retention] | Add a schedule (e.g. daily@03:00 full 7) |
backup schedule remove <id> | Remove a schedule |
alert
| Command | Purpose |
|---|---|
alert status | Alerting status (counts + action-dispatch success/failure) |
alert list [firing/acknowledged/resolved] | List alerts, newest first, optionally in one state |
alert history | Every alert kept (resolved alerts are kept for 30 days, at most 10,000 alerts) |
alert ack <alert_id> | Acknowledge a firing alert (it stays open until its condition clears) |
alert condition list | List threshold conditions |
alert condition add <json> | Add a condition, e.g. '{"metric_type":"pps","operator":"gt","threshold":1000,"duration_secs":60}'; prints it with its new id |
alert condition remove <id> | Remove a condition (its open alerts resolve) |
alert action list | List configured actions across all conditions (never shows a webhook's secret) |
alert action add <condition_id> <websocket/log/webhook> [config] | Attach an action; for webhook, config is a public http(s) URL and the output shows the signing secret once |
How conditions fire and resolve, and how to verify a webhook's signature, is in Monitoring.
heal
| Command | Purpose |
|---|---|
heal status | Latest health-check results |
heal check | Force an immediate health-check run |
container
Attach a container's network namespace to a managed network using the same plumbing a VM endpoint uses (a managed IP + MAC, a veth pair into the network's bridge).
| Command | Purpose |
|---|---|
container list | List attached containers |
container show <id> | Show an attachment by its logical id |
container attach --runtime <lxc/docker/podman> --network <id> --netns-pid <pid> [--ip <ip>] [--firewall] | Attach a container netns |
container detach <id> | Detach (tears down the veth, frees the endpoint) |
sudo cenvero-str-ctl container attach --runtime docker --network net-1 --netns-pid 12345
--netns-pid is the PID of any process inside the container (e.g. its init).
attach prints a logical container id; use that id with show / detach.
When the network belongs to a tenant, the container's port on the bridge is
separated from every other tenant's workloads before the container's interface
comes up (see Tenants & Bandwidth). If that separation cannot
be applied on this node, attach fails with an error instead of attaching the
container without it.
plugin
| Command | Purpose |
|---|---|
plugin install <target> | Install a plugin — a bare <name> from the official store, <username>/<name> from a trusted external store, or a local package path |
plugin list | List installed plugins |
plugin show | Show plugin detail |
plugin remove | Remove a plugin |
plugin verify <name> | Re-check an installed plugin: its files are the ones that were signed, and its certificate is genuine, covers this node and is not revoked. Exits non-zero if it does not pass |
plugin verify <path> | Run every install check on a package file without installing it. Exits non-zero if it would be refused |
plugin enable / plugin disable | Enable / disable a plugin (enable re-verifies it first) |
plugin store add <signed-store-file> | Trust an external plugin store (verified offline) |
plugin store list | List trusted plugin stores |
plugin store remove <username> | Remove a trusted external store |
The official Cenvero store is always present (its plugins install as a bare
<name>). An added external store's plugins install as <username>/<name>. See
Plugins.
node
| Command | Purpose |
|---|---|
node info | Node information: hardware id, agent version |
audit
The node's audit log: every change made on the node, by whom, from where, on what, and how it ended. See Monitoring for what is recorded.
| Command | Purpose |
|---|---|
audit list [filters] [--limit N] [--before N] [--order asc] | Records, newest first, 100 at a time (at most 1,000). The answer's next is the --before of the following page |
audit export [filters] [--output FILE] | Every matching record as JSON lines, oldest first, fingerprints included. --output writes a file readable only by root; without it, standard output |
audit verify [--checkpoint N:HASH] | Check that no record was changed, removed or added afterwards. Prints the first broken record if there is one and exits non-zero; prints the newest record's number and hash (last_seq, head_hash) to keep off the node, and checks one you kept |
Filters, for list and export:
| Flag | Keeps |
|---|---|
--since, --until | Records from / up to a time (RFC 3339, 2026-09-29T00:00:00Z, or Unix seconds) |
--principal | One principal, exactly as listed ("api key ak-12ab", root) |
--kind | One kind of principal: operator-token, operator-key, tenant-key, root, system, unauthenticated |
--tenant | Records made with one tenant's keys |
--action | Actions starting with this (vms. for every machine action) |
--object | Objects starting with this (/vms/vm-1a2b3c4d) |
--outcome | success, failure or refused |
sudo cenvero-str-ctl audit list --since 2026-09-29T00:00:00Z --outcome refused
sudo cenvero-str-ctl audit export --output /root/audit-$(date -u +%F).jsonl
sudo cenvero-str-ctl audit verify
Virtual machines (Compute, early access)
Needs a licence that includes Compute for every change; looking always works. See Compute.
| Command | Purpose |
|---|---|
compute status | Whether virtual machines are available on this node, and why not |
image register --name N --url URL --sha256 HEX [--wait] | Register a base image from a URL (the SHA-256 is required) |
image register --name N --path FILE [--sha256 HEX] [--wait] | Register a base image from a file on this node |
image list / image show <id> / image delete <id> | List, show, delete (refused while a machine uses it) |
vm create --name N --image ID [--vcpus N] [--memory MiB] [--disk GiB] --network NET[=IP]… [--public-ip auto or IP]… [flags] | Create and start a machine (all flags) |
vm list [--tenant T] / vm show <id> | List, show |
vm start <id> / vm stop <id> [--timeout S] / vm force-stop <id> / vm restart <id> [--force] | Start and stop (Lifecycle) |
vm resize <id> --disk GiB | Grow a stopped machine's disk |
vm update <id> [--vcpus N] [--memory MiB] | Change CPUs and memory: live within the machine's maximums, otherwise at its next restart (Resizing) |
vm nic add <id> --network NET[=IP] or --public-ip auto or IP [--bandwidth-mbps N] | Add an interface, also to a running machine |
vm nic remove <id> <nic> / vm nic replug <id> <nic> | Remove an interface (by index, name or address); reconnect a running machine to a recreated one |
vm password <id> --user U | Set a guest account's password through the guest agent (read from the terminal or standard input, never the command line) |
vm guest-agent <id> | Whether the guest agent answers, and the guest's own addresses |
vm console <id> [--force] | The serial console on this terminal; Ctrl+] disconnects (Consoles) |
vm delete <id> --yes | Delete a machine and its disk |
Every change above prints the id of the task that records it; follow
it with task log <id> --follow.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Invalid arguments |
| 3 | Agent unreachable (is cenvero-stratum.service running?) |
| 4 | Operation blocked by license enforcement (see Licensing) |
See also
- API Reference — the same managers over REST, plus the WebSocket event stream and the gRPC health check.
- Configuration — the node config model and every field.
- Operations — day-2 running, updates, and troubleshooting.