| 2 |
2 |
|
# versioned with the code it describes.
|
| 3 |
3 |
|
#
|
| 4 |
4 |
|
# A service, not an app or a library: pom is run rather than distributed. There
|
| 5 |
|
- |
# is no bundle for a user to download and no crate to publish, so the release
|
| 6 |
|
- |
# ends at `deploy` -- the binary lands on the hosts that run it and their units
|
| 7 |
|
- |
# restart.
|
|
5 |
+ |
# is no bundle for a user to download and no crate to publish.
|
|
6 |
+ |
#
|
|
7 |
+ |
# The kind says what pom IS. Who delivers it is a separate question, and the
|
|
8 |
+ |
# answer changed: Bento used to install the binary and restart the unit itself
|
|
9 |
+ |
# (`[[deploy]]` tables, now gone). Under the Sando/Bento boundary Bento builds
|
|
10 |
+ |
# and packages, and Sando decides whether a thing advances a stage. So the
|
|
11 |
+ |
# release ends at `collect`, and the daemon's `[handoff.pom]` table carries the
|
|
12 |
+ |
# artifact to sandod, which verifies it against its record, gates it, and
|
|
13 |
+ |
# promotes it tier by tier.
|
|
14 |
+ |
#
|
|
15 |
+ |
# That is what pom gets out of the move: a content-addressed release history and
|
|
16 |
+ |
# a real rollback horizon, instead of the single `<install-path>.prev` file
|
|
17 |
+ |
# Bento's installer kept. pom had the worst deploy story of anything shipped
|
|
18 |
+ |
# purely because of its architecture; this is the fix.
|
|
19 |
+ |
#
|
|
20 |
+ |
# Bento refuses to start if this file and the daemon config disagree — a service
|
|
21 |
+ |
# must either deploy itself or hand off, never neither and never both.
|
| 8 |
22 |
|
kind = "service"
|
| 9 |
23 |
|
|
| 10 |
24 |
|
# Two arches, two machines, built natively on each. Sando cannot do this job:
|
| 23 |
37 |
|
# makes a bare `v0.4.1` ambiguous the day it is created rather than eventually.
|
| 24 |
38 |
|
tag_format = "pom-v{version}"
|
| 25 |
39 |
|
|
| 26 |
|
- |
# NOT the both-or-neither gate it looks like. `require_all_targets` is consulted
|
| 27 |
|
- |
# by `publish`, and a service never publishes -- it deploys. So this flag does
|
| 28 |
|
- |
# nothing here today, and the 0.4.1 release proved it: x86_64 installed on the
|
| 29 |
|
- |
# Hetzner box and restarted it while the aarch64 build was still failing its test
|
| 30 |
|
- |
# gate, leaving the mesh split across two versions until the retry landed.
|
|
40 |
+ |
# Still not the both-or-neither gate it looks like: `require_all_targets` is
|
|
41 |
+ |
# consulted by `publish`, and pom does not publish. The 0.4.1 release showed what
|
|
42 |
+ |
# that costs -- x86_64 installed on the Hetzner box and restarted it while the
|
|
43 |
+ |
# aarch64 build was still failing its test gate, leaving the mesh split across
|
|
44 |
+ |
# two versions until the retry landed.
|
| 31 |
45 |
|
#
|
| 32 |
|
- |
# Left on because it is the right intent and costs nothing, but do not read it as
|
| 33 |
|
- |
# a guarantee. Wiring it into deploy is not a one-line change either: the gate
|
| 34 |
|
- |
# asks that every OTHER target already be green, which for sequential deploys
|
| 35 |
|
- |
# means the first one could never go. A real both-or-neither needs a barrier
|
| 36 |
|
- |
# between build and deploy across the matrix. Tracked as an infra problem.
|
|
46 |
+ |
# What changes under the handoff is where the guarantee comes from. It is no
|
|
47 |
+ |
# longer Bento's to give: each arch is handed over as its own artifact with its
|
|
48 |
+ |
# own evidence, and Sando resolves BOTH bundles before it touches a node, so a
|
|
49 |
+ |
# version missing its x86_64 half fails the promote whole rather than halfway.
|
|
50 |
+ |
# The split-mesh failure moves from "possible, untracked" to "refused by the
|
|
51 |
+ |
# promote".
|
|
52 |
+ |
#
|
|
53 |
+ |
# Left on because it is the right intent and costs nothing.
|
| 37 |
54 |
|
require_all_targets = true
|
| 38 |
55 |
|
|
| 39 |
|
- |
# Where each target lands. The recipe never names a machine -- it calls
|
| 40 |
|
- |
# deploy(), and the target it is already building for decides where that goes.
|
|
56 |
+ |
# No `[[deploy]]` tables. They are what a service that installs ITSELF declares,
|
|
57 |
+ |
# and pom no longer does -- the daemon's `[handoff.pom]` sends the collected
|
|
58 |
+ |
# artifact to sandod instead, and sandod owns install, restart, health and
|
|
59 |
+ |
# rollback from there.
|
| 41 |
60 |
|
#
|
| 42 |
|
- |
# install_path is /usr/local/bin/pom, which is what pom.service actually
|
| 43 |
|
- |
# ExecStarts and what both live hosts have today. Not /opt/pom/pom: that was
|
| 44 |
|
- |
# copied from mnw-cli's companion shape and matches nothing on either box.
|
| 45 |
|
- |
|
| 46 |
|
- |
[[deploy]]
|
| 47 |
|
- |
target = "linux/x86_64"
|
| 48 |
|
- |
# Reached over Tailscale SSH on 22 as root. NOT port 2200 -- that is what the
|
| 49 |
|
- |
# old deploy.sh used and it refuses this machine's key for both root and max,
|
| 50 |
|
- |
# which is why the 0.4.0 deploy was done by hand.
|
| 51 |
|
- |
host = "root@100.120.174.96"
|
| 52 |
|
- |
install_path = "/usr/local/bin/pom"
|
| 53 |
|
- |
service = "pom.service"
|
| 54 |
|
- |
health_url = "http://100.120.174.96:9100/api/health"
|
| 55 |
|
- |
|
| 56 |
|
- |
[[deploy]]
|
| 57 |
|
- |
target = "linux/aarch64"
|
| 58 |
|
- |
# astra builds this one and astra runs it, so the binary never leaves the box.
|
| 59 |
|
- |
host = "astra"
|
| 60 |
|
- |
install_path = "/usr/local/bin/pom"
|
| 61 |
|
- |
service = "pom.service"
|
| 62 |
|
- |
health_url = "http://100.106.221.39:9100/api/health"
|
|
61 |
+ |
# Kept here as the record of what the old path was, because the addresses moved
|
|
62 |
+ |
# to sando's topology rather than disappearing:
|
|
63 |
+ |
#
|
|
64 |
+ |
# linux/x86_64 root@100.120.174.96 (Tailscale SSH on 22, NOT 2200 -- 2200 is
|
|
65 |
+ |
# what the retired deploy.sh used and it refuses this machine's
|
|
66 |
+ |
# key for both root and max, which is why 0.4.0 was done by hand)
|
|
67 |
+ |
# linux/aarch64 astra
|
|
68 |
+ |
# both install_path /usr/local/bin/pom, unit pom.service,
|
|
69 |
+ |
# health http://<host>:9100/api/health
|