Skip to main content

max / makenotwork

4.0 KB · 78 lines History Blame Raw
1 // wam: Linux release recipe for Bento (x86_64 on fw13, aarch64 on astra).
2 //
3 // One recipe serves both arches and both service hosts. build_host() resolves
4 // to whichever native host the topology assigns the target, and deploy()
5 // resolves to whichever machine bento.toml says that target runs on, so there
6 // is no cross-compilation and no hard-coded host name anywhere in here. That
7 // matters more than usual here: the two legs are different architectures on
8 // different machines, and a recipe that named hosts could install the aarch64
9 // binary on the Hetzner box.
10 //
11 // Unlike pom's recipe this one ends at `deploy`, not `collect`. wam installs
12 // itself rather than handing off to Sando, because a bad wam deploy costs an
13 // internal ticket list rather than anyone's platform or the monitoring that
14 // watches it. The reasoning is written out in bento.toml next to the
15 // `[[deploy]]` tables; the short form is that the ladder is a real cost and
16 // belongs where a bad deploy is expensive.
17
18 let h = build_host();
19 let v = version();
20 let r = repo();
21
22 step("checkout");
23 // Pin to the release tag, not whatever main is at pull time. The daemon runs
24 // the same pin as a cross-host barrier before either target builds, so both
25 // arches come from one commit rather than from two machines' idea of main --
26 // which for a mesh that syncs between the two nodes is the difference between
27 // one protocol and two.
28 let sha = checkout_sha(h);
29 log("pinned " + h + " to wam-v" + v + " @ " + sha);
30
31 step("prebuild");
32 sh_ok(h, "cd " + r + " && cargo clippy --all-targets " + feature_flags() + " -- -D warnings");
33 sh_ok(h, "cd " + r + " && cargo test " + feature_flags());
34
35 step("build");
36 sh_ok(h, "cd " + r + " && cargo build --release " + feature_flags());
37 let binary = resolve_artifact(h, r + "/target/release/wam");
38
39 step("verify");
40 // The build host must not produce a binary the service host's glibc is too old
41 // to exec. Bento can make this check here, unlike in pom's handed-off recipe,
42 // precisely because wam keeps its `[[deploy]]` entry: the check needs to know
43 // which machine runs the binary, and that entry is where that is written.
44 log(glibc_check(binary));
45
46 // The version that is about to ship is the version in the tag. A binary
47 // reporting something else means the checkout and the release disagree.
48 sh_ok(h, binary + " --version | grep -qw " + v);
49
50 step("deploy");
51 // Stages under /var/tmp/bento-deploy/wam/ and calls the privileged installer,
52 // which keeps the outgoing binary as <dst>.prev, installs atomically, and
53 // restarts the unit. That .prev file is wam's whole rollback story, and it is
54 // proportionate: putting it back and restarting is one command.
55 log(deploy(binary));
56
57 // The health assertions live inside the deploy step rather than a step of their
58 // own. `step()` names one of a fixed set the daemon knows (checkout, prebuild,
59 // build, sign, notarize, staple, verify, package, publish, collect, deploy,
60 // handoff); a "health" step aborts the run AFTER the install has already
61 // happened, which is the worst of both -- the binary is live and the release
62 // reads failed. Assertions about the running service belong to the step that
63 // started it.
64 //
65 // What "healthy" means is the service's business, so the recipe asserts it
66 // itself against the host it just restarted.
67 //
68 // The assertion is 401, not 200, and that is the point of this release. The
69 // binary being replaced is an April build that predates the require_auth
70 // middleware: it answered /tickets with 200 and the full ticket body to an
71 // unauthenticated caller. A 200 here would mean the new binary did not take.
72 // 401 proves both that wam came back up and that it is refusing anonymous
73 // reads, which is the one thing this deploy exists to change.
74 sh_ok(deploy_host(), "test -x " + install_path());
75 sh_ok(deploy_host(), "code=$(curl -s -o /dev/null -w '%{http_code}' " + health_url() + "); test \"$code\" = 401 || { echo \"wam answered $code, expected 401 -- auth is not being enforced\"; exit 1; }");
76
77 log("wam " + v + " (" + target() + ") built on " + h + " and live on " + deploy_host());
78