| 1 |
# Bento deploy units |
| 2 |
|
| 3 |
`bentod` runs as a systemd **user** service on fw13 (the x86_64 build gate). |
| 4 |
Unlike `sandod` (a hardened system service with a dedicated `sando` user), |
| 5 |
bentod is a user service under the operator: building the apps needs the |
| 6 |
operator's SSH keys (to the tailnet build hosts and the mbp ops-agent), the app |
| 7 |
checkouts under `~/Code/Apps`, and the `_private` layer for signing secrets |
| 8 |
(`secrets_root`). A dedicated system user can't reach those without copying keys |
| 9 |
and bind-mounting home — so a user service is the right model, and it lets the |
| 10 |
operator redeploy bentod with `systemctl --user restart` (no sudo). |
| 11 |
|
| 12 |
## Files |
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
| `bentod.service` | `~/.config/systemd/user/` | The user service unit. | |
| 17 |
| `bento-daemon.toml.example` | `~/.config/bento/bento-daemon.toml` | Daemon-local config (paths + listen). Absolute paths only — no shell expansion. | |
| 18 |
| `bento.toml.example` | `~/.config/bento/bento.toml` | Build topology (hosts + apps). `repo` paths are tilde-expanded. | |
| 19 |
|
| 20 |
## Stand-up (no root except enable-linger) |
| 21 |
|
| 22 |
```sh |
| 23 |
# 1. Build + install the binary |
| 24 |
cd ~/Code/MNW/bento/daemon && cargo build --release |
| 25 |
install -D -m 0755 target/release/bentod ~/.local/bin/bentod |
| 26 |
|
| 27 |
# 2. Config + state dirs |
| 28 |
mkdir -p ~/.config/bento ~/.local/state/bento/logs ~/Dist |
| 29 |
install -m 0644 ~/Code/MNW/bento/deploy/bento-daemon.toml.example ~/.config/bento/bento-daemon.toml |
| 30 |
install -m 0644 ~/Code/MNW/bento/deploy/bento.toml.example ~/.config/bento/bento.toml |
| 31 |
# (edit the two configs: absolute home paths, real host/app rows) |
| 32 |
|
| 33 |
# 3. Service |
| 34 |
mkdir -p ~/.config/systemd/user |
| 35 |
install -m 0644 ~/Code/MNW/bento/deploy/bentod.service ~/.config/systemd/user/ |
| 36 |
loginctl enable-linger "$USER" |
| 37 |
systemctl --user daemon-reload |
| 38 |
systemctl --user enable --now bentod |
| 39 |
|
| 40 |
# 4. Verify |
| 41 |
curl -s http://127.0.0.1:8765/state | python3 -m json.tool |
| 42 |
``` |
| 43 |
|
| 44 |
## Auth (CF2) |
| 45 |
|
| 46 |
On the loopback bind above, build triggers are reachable only from fw13, so no |
| 47 |
token is required. To operate bentod over the tailnet, bind the tailnet IP in |
| 48 |
`bento-daemon.toml` and set `BENTO_API_TOKEN` via an `EnvironmentFile` in the |
| 49 |
unit — bentod refuses to start on a non-loopback bind without it (same posture |
| 50 |
as Sando's `SANDO_API_TOKEN`). |
| 51 |
|
| 52 |
## Recipes |
| 53 |
|
| 54 |
A real `/build` reads `<app>/<recipe_dir>/<platform>.rhai` from each app's |
| 55 |
checkout. The recipes now exist, one per platform per app: |
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
| goingson | yes | yes | yes | yes (unsigned, unsupported) | |
| 60 |
| audiofiles | yes | — (egui, no iOS) | yes | yes (unsigned, unsupported) | |
| 61 |
| balanced_breakfast | pending¹ | pending¹ | yes | yes (unsigned, unsupported) | |
| 62 |
|
| 63 |
¹ BB has no Developer ID signing / notarization infra or iOS project yet, so its |
| 64 |
macOS/iOS recipes are deferred until that lands. BB ships in a later wave. |
| 65 |
|
| 66 |
A `linux.rhai` serves both arches — `build_host()` resolves to the native host |
| 67 |
the topology assigns the target (`linux/x86_64` → fw13, `linux/aarch64` → astra), |
| 68 |
so there is no cross-compilation and no hard-coded host name. macOS/iOS recipes |
| 69 |
run on the mbp `agent`-transport host where the Developer ID key is usable. |
| 70 |
|
| 71 |
### Recipe host-function vocabulary |
| 72 |
|
| 73 |
Beyond `step`/`sh`/`sh_ok`/`log`/`collect`/`publish`/`secret`/`env` and the |
| 74 |
macOS helpers (`codesign`/`notarize`/`staple`/`verify_gatekeeper`/`keychain_*`), |
| 75 |
recipes can read their own context: |
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
| `version()` | the version being built (e.g. `"0.4.2"`) | |
| 80 |
| `build_host()` | the host this target builds on (e.g. `"fw13"`) | |
| 81 |
| `repo()` | the app's checkout path (`~`-prefixed; `cd` into it — commands don't auto-cd) | |
| 82 |
| `target()` / `platform()` / `arch()` | `"linux/x86_64"` / `"linux"` / `"x86_64"` | |
| 83 |
|
| 84 |
Non-Tauri apps (audiofiles) set `version_path` in the topology to the crate |
| 85 |
`Cargo.toml` carrying the version, since they have no `tauri.conf.json`. |
| 86 |
|