a73x

aa035c16

docs: the docs download what is served

a73x   2026-08-11 04:13

Commit message
docs: the docs download what is served

/dl keeps one release. Each is staged at its own immutable /dl/<version>/
and `latest` is a symlink to whichever that is, so a versioned URL is
good only while its release is the current one — and every download
command written with a pinned V stops working the day the next tag
ships. All of them were pinned, so all of them 404.

They take /dl/latest/, which always answers. The artifacts there carry
the version in their filenames, so nothing can hardcode one: V is read
out of SHA256SUMS, which is fetched first because it is what verifies
the rest. The client CLI is verified now too, having been the one
download that was not.

docs/quickstart.md
Old New
@@ -20,13 +20,16 @@ under Self-hosting, or a Mac, see "Join a Mac"), download and verify the
20 host bundle: 20 host bundle:
21 21
22 ```sh 22 ```sh
23 V=v0.0.1 23 curl -fsSLO https://eitri.sh/dl/latest/SHA256SUMS
24 curl -fsSLO "https://eitri.sh/dl/$V/eitri-server_${V}_linux_amd64.tar.gz" 24 V=$(sed -n 's/.*eitri-server_\(v[^_]*\)_linux_amd64\.tar\.gz$/\1/p' SHA256SUMS)
25 curl -fsSLO "https://eitri.sh/dl/$V/SHA256SUMS" 25 curl -fsSLO "https://eitri.sh/dl/latest/eitri-server_${V}_linux_amd64.tar.gz"
26 sha256sum -c SHA256SUMS --ignore-missing 26 sha256sum -c SHA256SUMS --ignore-missing
27 tar xzf "eitri-server_${V}_linux_amd64.tar.gz" && cd "eitri-server_${V}_linux_amd64" 27 tar xzf "eitri-server_${V}_linux_amd64.tar.gz" && cd "eitri-server_${V}_linux_amd64"
28 ``` 28 ```
29 29
30 `/dl/latest/` is the current release. Its filenames carry the version, so
31 `SHA256SUMS`—which you need to verify anyway—is where you read it from.
32
30 Then click **+ Add host** in the console and run the command it prints 33 Then click **+ Add host** in the console and run the command it prints
31 from the unpacked bundle—it installs the agent and joins this machine 34 from the unpacked bundle—it installs the agent and joins this machine
32 to your tenant: 35 to your tenant:
@@ -115,10 +118,13 @@ targets the hosted service by default, so the only thing to set is a personal
115 access token: 118 access token:
116 119
117 ```sh 120 ```sh
118 V=v0.0.1 121 OS=$(uname -s | tr A-Z a-z) ARCH=amd64 # arm64 laptop → ARCH=arm64
119 curl -fsSLO "https://eitri.sh/dl/$V/eitri-cli_${V}_$(uname -s | tr A-Z a-z)_amd64.tar.gz" # arm64 laptop → _arm64 122 curl -fsSLO https://eitri.sh/dl/latest/SHA256SUMS
120 tar xzf eitri-cli_${V}_*.tar.gz 123 V=$(sed -n "s/.*eitri-cli_\(v[^_]*\)_${OS}_${ARCH}\.tar\.gz\$/\1/p" SHA256SUMS)
121 sudo install -m 0755 eitri-cli_*/eitri /usr/local/bin/eitri 124 curl -fsSLO "https://eitri.sh/dl/latest/eitri-cli_${V}_${OS}_${ARCH}.tar.gz"
125 sha256sum -c SHA256SUMS --ignore-missing
126 tar xzf "eitri-cli_${V}_${OS}_${ARCH}.tar.gz"
127 sudo install -m 0755 "eitri-cli_${V}_${OS}_${ARCH}/eitri" /usr/local/bin/eitri
122 128
123 export EITRI_TOKEN=<pat> # mint one in the console → Settings → Personal access tokens 129 export EITRI_TOKEN=<pat> # mint one in the console → Settings → Personal access tokens
124 ``` 130 ```
@@ -215,18 +221,22 @@ sign-in provider—and its unit. The client bundle
215 (`eitri-cli_<version>_<os>_<arch>.tar.gz`) is the single `eitri` binary for 221 (`eitri-cli_<version>_<os>_<arch>.tar.gz`) is the single `eitri` binary for
216 your laptop, built for linux and macOS. arm64 boxes take the arm64 bundle. 222 your laptop, built for linux and macOS. arm64 boxes take the arm64 bundle.
217 223
218 Download and verify—set `V` to the current release (shown at 224 Download and verify. `SHA256SUMS` comes first: it verifies the rest, and its
219 [/dl](https://eitri.sh/dl/)): 225 filenames name the release, so `V` is read from it rather than typed:
220 226
221 ```sh 227 ```sh
222 V=v0.0.1 228 curl -fsSLO https://eitri.sh/dl/latest/SHA256SUMS
223 curl -fsSLO "https://eitri.sh/dl/$V/eitri-server_${V}_linux_amd64.tar.gz" 229 V=$(sed -n 's/.*eitri-server_\(v[^_]*\)_linux_amd64\.tar\.gz$/\1/p' SHA256SUMS)
224 curl -fsSLO "https://eitri.sh/dl/$V/eitri-oidc_${V}_linux_amd64.tar.gz" 230 curl -fsSLO "https://eitri.sh/dl/latest/eitri-server_${V}_linux_amd64.tar.gz"
225 curl -fsSLO "https://eitri.sh/dl/$V/eitri-cli_${V}_$(uname -s | tr A-Z a-z)_amd64.tar.gz" 231 curl -fsSLO "https://eitri.sh/dl/latest/eitri-oidc_${V}_linux_amd64.tar.gz"
226 curl -fsSLO "https://eitri.sh/dl/$V/SHA256SUMS" 232 curl -fsSLO "https://eitri.sh/dl/latest/eitri-cli_${V}_$(uname -s | tr A-Z a-z)_amd64.tar.gz"
227 sha256sum -c SHA256SUMS --ignore-missing 233 sha256sum -c SHA256SUMS --ignore-missing
228 ``` 234 ```
229 235
236 Every artifact also has an immutable home at `/dl/<version>/`, which is what
237 [/dl](https://eitri.sh/dl/) links; `/dl/latest/` is the moving alias, and only
238 the current release is served.
239
230 Plain files at stable URLs—no install script. `sha256sum -c` must say OK 240 Plain files at stable URLs—no install script. `sha256sum -c` must say OK
231 for every tarball before you unpack anything. 241 for every tarball before you unpack anything.
232 242
docs/upgrade.md
Old New
@@ -38,14 +38,14 @@ disable upgrade checks entirely.
38 An agent whose version never orders—a `dev` or `-dirty` build—never gets the 38 An agent whose version never orders—a `dev` or `-dirty` build—never gets the
39 button. The manual path is the same swap, done by you. 39 button. The manual path is the same swap, done by you.
40 40
41 On Linux, set `V` to the release you want (shown at 41 On Linux, take the current release from `/dl/latest/` and read its version out
42 [/dl](https://eitri.sh/dl/)); on an arm64 host, `_arm64` replaces `_amd64` 42 of `SHA256SUMS`; on an arm64 host, `_arm64` replaces `_amd64` throughout:
43 throughout:
44 43
45 ```sh 44 ```sh
46 V=v0.0.4 45 curl -fsSLO https://eitri.sh/dl/latest/SHA256SUMS
47 curl -fsSLO "https://eitri.sh/dl/$V/eitri-server_${V}_linux_amd64.tar.gz" 46 V=$(sed -n 's/.*eitri-server_\(v[^_]*\)_linux_amd64\.tar\.gz$/\1/p' SHA256SUMS)
48 curl -fsSL "https://eitri.sh/dl/$V/SHA256SUMS" | grep " eitri-server_${V}_linux_amd64.tar.gz$" | sha256sum -c - 47 curl -fsSLO "https://eitri.sh/dl/latest/eitri-server_${V}_linux_amd64.tar.gz"
48 grep " eitri-server_${V}_linux_amd64.tar.gz$" SHA256SUMS | sha256sum -c -
49 tar xzf "eitri-server_${V}_linux_amd64.tar.gz" 49 tar xzf "eitri-server_${V}_linux_amd64.tar.gz"
50 sudo cp /usr/local/bin/eitri-agent /usr/local/bin/eitri-agent.prev 50 sudo cp /usr/local/bin/eitri-agent /usr/local/bin/eitri-agent.prev
51 sudo install -m 0755 "eitri-server_${V}_linux_amd64/eitri-agent" /usr/local/bin/eitri-agent 51 sudo install -m 0755 "eitri-server_${V}_linux_amd64/eitri-agent" /usr/local/bin/eitri-agent
@@ -53,7 +53,9 @@ sudo systemctl restart eitri-agent
53 ``` 53 ```
54 54
55 The host bundle is the artifact—there is one set of bytes per platform per 55 The host bundle is the artifact—there is one set of bytes per platform per
56 release, and it is the same one the console's button fetches. 56 release, and it is the same one the console's button fetches. Each release also
57 has an immutable home at `/dl/<version>/`, but only the current one is served,
58 so `/dl/latest/` is the address that always answers.
57 59
58 Running VMs survive the restart—the unit's `KillMode=process` (see Operations 60 Running VMs survive the restart—the unit's `KillMode=process` (see Operations
59 below) leaves the guests alone. The `.prev` copy mirrors what the button path 61 below) leaves the guests alone. The `.prev` copy mirrors what the button path