Skip to main content

max / makenotwork

3.3 KB · 76 lines History Blame Raw
1 # Deploying pom
2
3 pom ships through **Bento**, not Sando, and not by hand.
4
5 Sando cannot do this job. `sando-daemon.toml` sets `build_host = "fw13"` and
6 `build::run` refuses to compile anywhere else, which is the never-build-on-prod
7 invariant and also makes Sando single-architecture. pom runs on astra (aarch64)
8 and on the Hetzner box (x86_64), so Sando could never build half of this release
9 without breaking its own rule. Bento already fans out native builds across both
10 hosts, so pom is a Bento recipe.
11
12 `deploy.sh` is gone. It cross-compiled with `cargo zigbuild` (against the
13 native-per-architecture rule, with a cargo-zigbuild that is not installed on
14 fw13), reached Hetzner on port 2200 which refuses this machine's key, and copied
15 config and the unit file over the live ones with no diff and no backup. It did
16 not work as written when 0.4.0 went out; that deploy was done by hand.
17
18 ## Running a deploy
19
20 Bump the version in `Cargo.toml`, commit, tag `v<version>`, push, then trigger
21 the build through Bento for both targets. The `/deploy` skill has the procedure.
22
23 What the recipe does, per target (`dist/recipes/linux.rhai`):
24
25 1. Pin the checkout to the release tag, and check both hosts report one commit.
26 2. `cargo clippy -D warnings` and `cargo test`, on that target's own build host.
27 3. `cargo build --release`.
28 4. Compare the binary's highest `GLIBC_` symbol against the service host's
29 `ldd --version`, and assert `pom --version` matches the tag.
30 5. Stage the binary on the service host and call the privileged installer.
31 6. Poll `/api/health` until the restarted instance answers, then assert the
32 running binary reports the version that was just installed.
33
34 The two instances go one at a time, and `require_all_targets` keeps the release
35 from counting as done until both are green. pom watches its own deploy, so the
36 restart takes one watcher down for a moment; the other stays up and keeps
37 watching. Never both at once.
38
39 ## What a deploy does not touch
40
41 **Config.** `pom-astra.toml` and `pom-hetzner.toml` differ per instance, and the
42 live config on prod once carried a `[targets.mnw.tests]` block this repo did not
43 have. `deploy.sh` would have silently deleted it. Config is a separate,
44 deliberate act; the installer refuses to go near it.
45
46 **The unit file.** Same reasoning. A hardened unit that has drifted from the
47 repo is a question for a human, not something a binary deploy overwrites.
48
49 ## One-time host setup
50
51 Each host that runs pom needs the installer and its scoped sudo grant:
52
53 ```
54 sudo install -d /usr/local/lib/bento
55 sudo install -m 0755 install-service.sh /usr/local/lib/bento/install-service.sh
56 sudo install -m 0440 bento-deploy.sudoers /etc/sudoers.d/bento-deploy
57 sudo visudo -cf /etc/sudoers.d/bento-deploy
58 ```
59
60 Edit the sudoers file first so the user matches how Bento reaches that host:
61 `max` on astra, `root` over Tailscale SSH on the Hetzner box. The grant covers
62 one script and nothing else; the script bounds its own arguments (source under
63 `/var/tmp/bento-deploy`, destination under `/usr/local/bin`, a bare `*.service`
64 unit), so it is a script-guarded grant rather than a broad
65 `install` + `systemctl` one.
66
67 ## Rollback
68
69 The installer keeps the previous binary as `<install-path>.prev`. Rolling back
70 is putting it back and restarting:
71
72 ```
73 sudo install -m 0755 /usr/local/bin/pom.prev /usr/local/bin/pom
74 sudo systemctl restart pom.service
75 ```
76