Zaroz
Units API guide

Labels, user data and list filters

Every unit has three inputs you control.

InputRuleWhen it can changeThe unit reads it at
key1 to 40 chars, DNS-label shapeneverenv ZAROZ_UNIT_KEY, /zaroz/unit.json
labelsat most 16 pairs; key ^[a-z0-9]([a-z0-9_.-]*[a-z0-9])?$ up to 32 chars; value up to 64 characters; whole map under 2 KiBany time/zaroz/unit.json (updated live)
user_dataany JSON, at most 64 KiB, 32 levels deep; null means noneon create, on start of a stopped unit, on allocate; each replaces the old value whole/zaroz/user-data.json and GET /user-data on the signal socket

user_data is not a secret store. The console shows it, every read of the unit returns it, and it is part of the cluster object. Keep secrets in the Workload's environment.

Change labels at any time

PATCH .../units/{key} replaces the whole label map. It works in every policy mode and on running units; the unit sees the change in /zaroz/unit.json within about a second.

curl

TerminalCode
curl -sS -X PATCH "$UNITS/plot-ana" -H "$AUTH" -H "Content-Type: application/json" \ -d '{"labels": {"kind": "plot", "owner": "ana", "tier": "free"}}'

TypeScript

TypeScriptCode
await call("PATCH", `${UNITS}/plot-ana`, { labels: { kind: "plot", owner: "ana", tier: "free" }, // the whole map is replaced });

Python

Code
call("PATCH", f"{UNITS}/plot-ana", { "labels": {"kind": "plot", "owner": "ana", "tier": "free"}, # the whole map is replaced })

Find units by label

GET .../units accepts these filters. They combine with AND.

ParameterMeaning
label=key:valueexact match; repeat it for several (at most 8); a value may contain colons
origin=policy|code|warmwho created the unit
key_prefix=plot-keys starting with the text
include=user_dataadd each unit's user_data (omitted by default to keep the page small; GET .../units/{key} always has it)
include_gone=truealso units scaled away in the last 30 days, so their logs stay reachable

curl

TerminalCode
# every unit made by your code whose labels include kind=plot AND owner=ana curl -sS -G "$UNITS" -H "$AUTH" \ --data-urlencode "origin=code" \ --data-urlencode "label=kind:plot" \ --data-urlencode "label=owner:ana" \ --data-urlencode "key_prefix=plot-" \ --data-urlencode "include=user_data"

TypeScript

TypeScriptCode
const q = new URLSearchParams(); q.set("origin", "code"); q.append("label", "kind:plot"); q.append("label", "owner:ana"); q.set("key_prefix", "plot-"); q.set("include", "user_data"); const { body } = await call("GET", `${UNITS}?${q}`); for (const u of body.data) console.log(u.key, u.state, u.labels);

Python

Code
status, body = call("GET", UNITS, params=[ ("origin", "code"), ("label", "kind:plot"), ("label", "owner:ana"), ("key_prefix", "plot-"), ("include", "user_data"), ]) for u in body["data"]: print(u["key"], u["state"], u["labels"])

Labels are the right place for what a matchmaker needs to choose a unit (mode:2v2, region:eu, owner:ana). user_data is the right place for what the unit itself needs to start (a roster, a job, a world location).

Last modified on