Swamp Worker
Enlist a host as a swamp worker for one swamp serve orchestrator: install or upgrade it, reconcile its systemd user unit, mint its enrollment token, and report or remove exactly the worker this repo owns.
WHAT IT DOES
Turns "make this host a worker for my serve" into repeatable swamp methods —
and, for a single host, into one idempotent install-or-upgrade workflow. The
model renders the worker's systemd user unit, writes it only when it changed,
and starts it with enable --now plus loginctl enable-linger, so the worker
survives logout and reboot. It mints a long-duration enrollment token to a
0600 file, and remove decommissions the worker: it revokes the token so it
can never re-enrol, then deletes only its own namespaced artifacts. Every
artifact is namespaced by identity, so this worker coexists with, and never
touches, workers other repos install on the same host. For a set of hosts it
also renders per-node provisioning and removal scripts. Prefer it over the
built-in daemon, which allows only one worker per host.
INSTALL
swamp extension pull @svendowideit/swamp-workerDEPENDENCIES
None installed on the host beyond the swamp binary itself and the host's own
systemd (systemctl --user, loginctl). The host must have a running systemd
user manager — systemctl --user must work (a live logind and
user@<uid>.service with /run/user/<uid>) — or the ensure/provision steps
fail. A site extension (@figy/swamp-worker) supplies the serve URL, node set
and secret handling and drives this model over SSH. Linux only.
RUN
# Install or upgrade this host's worker in one idempotent run. `swampBinPath`
# MUST be the swamp binary on THIS host (token minting execs it) and `identity`
# must match the site's. Re-run to upgrade the binary and reconcile the unit.
swamp workflow run @svendowideit/swamp-worker-upgrade \
--input serveUrl=wss://swamp.x1yoga.fi.gy \
--input identity=figy --input swampBinPath=~/.local/bin/swamp
# Or use the methods directly: mint a token, then bring the unit up on this host.
swamp model method run worker mintToken --input duration=30d
swamp model method run worker ensureService \
--input serveUrl=wss://swamp.x1yoga.fi.gy
# Inspect the desired unit without changing the host, then read its state.
swamp model method run worker renderUnit \
--input serveUrl=wss://swamp.x1yoga.fi.gy
swamp model method run worker status
# Completely reverse it: `remove` revokes the token (disconnecting the
# worker), then stops, disables and deletes its artifacts.
swamp model method run worker removeCONFIGURE
Global arguments (set at model creation with --global-arg key=value, or
edited later with swamp model edit):
identity worker slug that namespaces every artifact (worker)
swampBinPath absolute path to the swamp binary (/usr/local/bin/swamp)
repoDir repo dir for local `swamp worker token` (.)
configDir token/env file dir (0600) (~/.config/swamp-worker)
cacheDirRoot per-identity cache dir root (~/.local/share/swamp-worker)
unitDir systemd user unit dir (~/.config/systemd/user)
swampHome SWAMP_HOME in the unit (~/.swamp)
swampConfigDir SWAMP_CONFIG_DIR in the unit (~/.config/swamp)
concurrency worker --concurrency (auto)
enableLinger run `loginctl enable-linger` (true)
otelSettingsModel @svendowideit/otel-settings model to export to ("" = off)
otelServiceName OTEL_SERVICE_NAME the worker reports (swamp-worker)
telemetryVault vault holding the OTLP bearer token ("")
authRef vault key for the bearer token (OTEL_EXPORTER_OTLP_TOKEN) swampBinPath is the setting that bites: it is exec'd on the orchestrator to
mint and revoke tokens, so it must point at an existing swamp binary there — a
per-user install is usually ~/.local/bin/swamp, not the /usr/local/bin/swamp
default. It is also the path the provisioning script installs on each node, so
on a set of hosts it must be writable and identical.
Telemetry: set otelSettingsModel to the @svendowideit/otel-settings model
whose contract this site publishes (e.g. otel) and the worker unit gains the
contract's OTEL_EXPORTER_OTLP_* env — so logs, metrics and traces export
from every node, attributed to otelServiceName with a per-node host=
resource attribute. Set telemetryVault/authRef when the gateway needs a
bearer token. Empty (the default) leaves the unit untouched. Per call:
renderUnit/ensureService take serveUrl, optional host, labels
(KEY=VALUE strings), concurrency and force (ensureService also takes
name); renderProvision takes serveUrl, host, labels, concurrency and
version; renderRemoval takes nothing; install takes version and force;
mintToken takes name (default <identity>-<hostname>), duration and
force — one call per node; clearStagedTokens takes names; revokeToken
takes name and purgeFile; remove takes name, revokeToken (default
true) and purgeData.
UPGRADE
Install and upgrade are the same idempotent workflow: re-run
@svendowideit/swamp-worker-upgrade to upgrade this host's swamp binary to
version (default latest) and reconcile its unit. It needs no new inputs.
WHAT IT INSTALLS
On the host: a systemd user unit swamp-worker-<identity>.service, the
worker's cache dir (holding the enrollment machine-id), and 0600 token and
env files under configDir. When otelSettingsModel is set, the unit also
carries the contract's OTEL_EXPORTER_OTLP_* env, so the worker exports
logs, metrics and traces. It enables user lingering. It installs no cron
triggers or webhooks of its own. remove revokes the enrollment token and
deletes those artifacts and nothing else — foreign worker units are never
enumerated or touched.
Global Arguments
| Argument | Type | Description |
|---|---|---|
| identity? | string | Worker identity slug. Namespaces every artifact (unit name, cache dir, |
| unitName? | string | Systemd user unit name (without .service). Defaults to |
| swampBinPath? | string | Absolute path to the swamp binary the worker unit executes. |
| repoDir? | string | Repository directory used for local `swamp worker token` calls. |
| configDir? | string | Directory holding the identity's token and env files (0600). |
| cacheDirRoot? | string | Root for per-identity worker cache dirs (each holds the machine-id the |
| stagingDir? | string | Orchestrator-side dir where `mintToken` writes each node's token plaintext |
| unitDir? | string | Directory where systemd user unit files are written. |
| swampHome? | string | SWAMP_HOME exported into the worker unit. |
| swampConfigDir? | string | SWAMP_CONFIG_DIR exported into the worker unit. |
| releaseBaseUrl? | string | Base URL for swamp release downloads when the binary is absent. |
| concurrency? | string | Worker `--concurrency` ('auto' = CPU count, min 1). |
| enableLinger? | boolean | Run `loginctl enable-linger` so the user service survives logout/reboot. |
| otelSettingsModel? | string | Name of the @svendowideit/otel-settings model whose contract the worker |
| otelServiceName? | string | OTEL_SERVICE_NAME the worker reports; the resource `service.name` is set |
| telemetryVault? | string | Vault holding the gateway OTLP bearer token (empty = unauthenticated). |
| authRef? | string | Vault key holding the gateway bearer token (a reference, never the secret). |
| Argument | Type | Description |
|---|---|---|
| serveUrl | string | Serve URL the worker dials. |
| host? | string | Host label value. Defaults to this machine's hostname. |
| labels? | array | Extra scheduling labels as KEY=VALUE strings. |
| concurrency? | string | Override the global concurrency for this render. |
| write? | boolean | Also write the unit file to disk (without reloading systemd). |
| Argument | Type | Description |
|---|---|---|
| serveUrl | string | Serve URL the worker dials. |
| host? | string | Host label value. Empty fills each node's own hostname at install time, so |
| labels? | array | Extra scheduling labels as KEY=VALUE strings. |
| concurrency? | string | Override concurrency. |
| version? | string | swamp release tag to install on the node; empty = latest. |
| Argument | Type | Description |
|---|---|---|
| version? | string | swamp release tag to install (empty = latest). |
| force? | boolean | Reinstall even when the binary is already present. |
| Argument | Type | Description |
|---|---|---|
| names? | array | Enrollment token names whose orchestrator-side staging files |
| Argument | Type | Description |
|---|---|---|
| name? | string | Enrollment token name — also names the 0600 orchestrator-side staging file |
| duration? | string | Token lifetime (hard deadline), e.g. 24h, 7d, 30d. |
| force? | boolean | Mint a fresh token even when one is already staged for this name. The old |
| Argument | Type | Description |
|---|---|---|
| name? | string | Enrollment token name to revoke (the target's base name, or an exact |
| allGenerations? | boolean | Also revoke every rotation generation of this name (`<name>-g<gen>`), so a |
| purgeFile? | boolean | Also delete the local token file, so the revoked token cannot be reused. |
| Argument | Type | Description |
|---|---|---|
| serveUrl | string | Serve URL the worker dials. |
| host? | string | Host label value. Defaults to this machine's hostname. |
| labels? | array | Extra scheduling labels as KEY=VALUE strings. |
| concurrency? | string | Override concurrency. |
| name? | string | Enrollment token name whose staged plaintext to install before starting |
| force? | boolean | Restart the unit even when nothing changed. |
| Argument | Type | Description |
|---|---|---|
| name? | string | Enrollment token name to revoke and whose staged file to drop. Defaults to |
| revokeToken? | boolean | Also revoke the enrollment token on the orchestrator (a complete |
| purgeData? | boolean | Also delete the identity's cache dir and token/env files. |
Resources
Install or upgrade this host's swamp worker in one idempotent run — the same command whether the worker is absent or already present. On a fresh host it mints a token, installs the swamp binary, writes the systemd user unit and starts it. On a host that already runs the worker it upgrades the swamp binary to the requested release and reconciles the unit, restarting only when the unit or token changed. Every step is idempotent, so re-running is always safe and changes only what differs. The `id
Added 1 workflows
- Has README or module doc2/2earned
- README has a code example1/1earned
- README is substantive1/1earned
- Most symbols documented1/1earned
- No slow types (deprecated)1/1earned
- Dependencies pass trust audit2/2earned
- Has description1/1earned
- Platform support declared (or universal)2/2earned
- License2/2earned
- Verified public repository2/2earned
Spawns a subprocess with Deno.Command().
- models/swamp_worker.ts:779 — this model drives systemctl/swamp/curl; arguments are quoted and this is the single injectable spawn seam, stubbed in tests
A field that looks like a secret but is not marked sensitive, so its value is not vaulted.
- models/swamp_worker.ts:1137 — not a secret — a file path