| 1 | #!/bin/sh |
| 2 | set -eu |
| 3 | umask 077 |
| 4 | server=__SERVER__ |
| 5 | |
| 6 | install_agent() { |
| 7 | [ "$(id -u)" != 0 ] || { echo 'Run this installer as your login user, without sudo.' >&2; return 1; } |
| 8 | case $(uname -s) in |
| 9 | Linux) os=linux; base=${XDG_DATA_HOME:-"$HOME/.local/share"}/agent-relay |
| 10 | command -v systemctl >/dev/null || { echo 'This installer needs a systemd user session.' >&2; return 1; } |
| 11 | systemctl --user show-environment >/dev/null || { echo 'Sign in to a systemd user session, then run the installer again.' >&2; return 1; } ;; |
| 12 | Darwin) os=darwin; base="$HOME/Library/Application Support/AgentRelay" ;; |
| 13 | *) echo "Use $server/agent/install.ps1 from Windows PowerShell." >&2; return 1 ;; |
| 14 | esac |
| 15 | case $(uname -m) in |
| 16 | x86_64|amd64) arch=x64 ;; |
| 17 | aarch64|arm64) arch=arm64 ;; |
| 18 | *) echo 'This installer supports x64 and arm64 machines.' >&2; return 1 ;; |
| 19 | esac |
| 20 | command -v curl >/dev/null || { echo 'Install curl, then run this installer again.' >&2; return 1; } |
| 21 | mkdir -p "$base" |
| 22 | chmod 700 "$base" |
| 23 | stage=$(mktemp -d "$base/.install.XXXXXX") |
| 24 | trap 'rm -rf "$stage"' EXIT HUP INT TERM |
| 25 | if [ ! -x "$base/node" ] && [ -f /etc/NIXOS ]; then |
| 26 | echo 'Installing the agent runtime…' |
| 27 | nix --extra-experimental-features 'nix-command flakes' build nixpkgs#nodejs_24 --out-link "$base/node-runtime" |
| 28 | ln -sf "$base/node-runtime/bin/node" "$base/node" |
| 29 | elif [ ! -x "$base/node" ]; then |
| 30 | echo 'Downloading the agent runtime…' |
| 31 | curl -fsSL https://nodejs.org/dist/latest-v24.x/SHASUMS256.txt -o "$stage/checksums" |
| 32 | archive=$(awk -v suffix="-$os-$arch.tar.gz" '$2 ~ /^node-v24\./ && substr($2, length($2)-length(suffix)+1) == suffix {print $2}' "$stage/checksums") |
| 33 | [ -n "$archive" ] || { echo 'No runtime download is available for this machine.' >&2; return 1; } |
| 34 | version=${archive#node-}; version=${version%%-$os-*} |
| 35 | curl -fsSL "https://nodejs.org/dist/$version/$archive" -o "$stage/$archive" |
| 36 | expected=$(awk -v file="$archive" '$2 == file {print $1}' "$stage/checksums") |
| 37 | if command -v sha256sum >/dev/null; then |
| 38 | actual=$(sha256sum "$stage/$archive"); actual=${actual%% *} |
| 39 | else |
| 40 | actual=$(shasum -a 256 "$stage/$archive"); actual=${actual%% *} |
| 41 | fi |
| 42 | [ "$actual" = "$expected" ] || { echo 'The runtime checksum did not match. Run the installer again.' >&2; return 1; } |
| 43 | tar -xzf "$stage/$archive" -C "$stage" |
| 44 | cp "$stage/${archive%.tar.gz}/bin/node" "$base/node" |
| 45 | chmod 700 "$base/node" |
| 46 | fi |
| 47 | curl -fsSL "$server/agent/relay.mjs" -o "$stage/relay.mjs" |
| 48 | curl -fsSL "$server/agent/setup.mjs" -o "$stage/setup.mjs" |
| 49 | "$base/node" "$stage/setup.mjs" install "$server" "$base" </dev/tty |
| 50 | } |
| 51 | |
| 52 | # The shell must read the whole script before the installer opens the terminal. |
| 53 | install_agent |