A first glyph
The smallest useful fleet is one host with two glyphs: install a package and enable its unit. This guide takes it from Emet source to a reconciled box and back.
The whole thing
main : List Scrollmain = [ scroll { name = "web" , glyphs = [ aptPackage { name = "nginx" } , systemdService { unit = "nginx.service" } ] } ]Save it as web.emet. That is the deploy: one scroll named web, two
glyphs.
Compile it
Look at the plan before shipping anything:
emetc build web.emet --textmain : List Scrollplanned scrolls (1): scroll `web` (2 glyphs): * ensure apt package `nginx` installed * enable + start systemd unit `nginx.service`The binary manifest is the default output; --text is the readable view.
Apply it
-
Start the agent as host
web.fakeenacts the plan in memory and touches nothing:Terminal window golemd --host web --reconciler fake --listen 127.0.0.1:7474On a Debian box you want real effects on, switch to the
hostreconciler — which acts as root, and so never runs without a token file:Terminal window golemd --host web --reconciler host --listen 127.0.0.1:7474 \--auth-token-file /etc/golem/token -
Compile-and-ship in one command:
Terminal window golemctl apply web.emet http://127.0.0.1:7474That address reaches an agent on this machine. For a Debian box across the room, name it
ssh://golem@webinstead:golemctlopens the SSH forward to its loopback agent and carries your bearer token (Trust model). -
Inspect what the node applied:
Terminal window golemctl state http://127.0.0.1:7474You get the applied scroll and its content id.
What golem did
The agent selected the web scroll, diffed it against an empty journal, and
enacted two Install ops:
| Glyph | What the reconciler did | What it recorded to reverse |
|---|---|---|
aptPackage { name = "nginx" } | apt-get install -y nginx (if absent) | InstalledByUs — remove on reverse; or WasPresent — leave alone |
systemdService { unit = "nginx.service" } | records prior enabled/active state, then enable --now | the prior state, to restore on reverse |
Each op’s reversal receipt is journalled. That is what makes the next step exact.
Take it back
Remove the glyphs from your Emet — an empty scroll:
main : List Scrollmain = [ scroll { name = "web", glyphs = [] } ]Re-apply:
golemctl apply web.emet http://127.0.0.1:7474The agent diffs the empty scroll against the journal, turns both glyphs into
Remove ops, and runs each recorded uninstaller — nginx is removed
only because golem installed it and captured InstalledByUs. If nginx
had been on the box already, the reverse leaves it. The unit is disabled and
its prior state restored.
That is the property worth having: removing a glyph and re-applying restores the box to what it was before golem touched that resource. See Reversible reconcile.
Where to next
- Build a real abstraction that lowers to glyphs: A service abstraction
- The capstone — a real multi-host lichess deploy: A tour of the lichess fleet