#!/bin/sh # wxch bootstrap. Run as a normal user; it asks for the sudo password ONCE and then # everything runs as root inside that single elevation. # # install: curl -fsSL @@BASE@@/get | WXCH_TOKEN= sh # reinstall: curl -fsSL @@BASE@@/get | WXCH_TOKEN= sh -s -- --reinstall # uninstall: curl -fsSL @@BASE@@/get | sh -s -- uninstall [--runtimes] [--models] [--all] # add a disk: curl -fsSL @@BASE@@/get | sh -s -- add-disk [/dev/sdX1] [--format] [--name NAME] (no token needed) # AI modules: curl -fsSL @@BASE@@/get | sh -s -- modules ... # (optional, not installed by default; needs the agent and runner already installed; no token needed) # # Options (environment variables) are listed at the top of setup.sh. set -eu BASE="@@BASE@@" SCRIPT=setup.sh if [ "${1:-}" = "uninstall" ]; then SCRIPT=uninstall.sh shift elif [ "${1:-}" = "add-disk" ]; then SCRIPT=add-disk.sh shift elif [ "${1:-}" = "modules" ]; then # the vllm step brings the runner up to date (it starts the engines), the modules step installs what was asked for shift mods=""; rest="" for a in "$@"; do case "$a" in -*) rest="$rest $a" ;; *) mods="$mods,$a" ;; esac; done [ -n "$mods" ] || { echo "usage: sh -s -- modules ..." >&2; exit 2; } WXCH_MODULES="${mods#,}"; WXCH_ONLY="vllm,modules"; export WXCH_MODULES WXCH_ONLY # shellcheck disable=SC2086 set -- $rest fi tmp="$(mktemp /tmp/wxch-setup.XXXXXX)" trap 'rm -f "$tmp"' EXIT curl -fsSL "$BASE/$SCRIPT" -o "$tmp" chmod 644 "$tmp" dry=0 for a in "$@"; do [ "$a" = "--dry-run" ] && dry=1; done if [ "$dry" = 0 ] && [ "$(id -u)" = 0 ] && [ -z "${SUDO_USER:-}${WXCH_USER:-}" ]; then echo "Run this as the normal user that will own the agent (not directly as root), or set WXCH_USER=." >&2 exit 1 fi # pass every WXCH_* variable through the single sudo call args="" for v in $(env | sed -n 's/^\(WXCH_[A-Za-z0-9_]*\)=.*/\1/p'); do args="$args $v=\"\$$v\"" done args="$args WXCH_BASE=\"\$BASE\"" # a transient systemd unit starts with an empty environment (no SUDO_USER): say who owns the agent if [ -z "${WXCH_USER:-}" ]; then owner="${SUDO_USER:-}" [ -n "$owner" ] || { [ "$(id -u)" != 0 ] && owner="$(id -un)"; } [ -n "$owner" ] && args="$args WXCH_USER=$owner" fi if [ "$dry" = 1 ]; then echo "wxch: dry run, no sudo and no changes." else echo "wxch: the installer will ask for your sudo password once." fi # Started from the web terminal, we are a child of the agent, and the installer restarts the agent: that would # kill the installer half way. Then run it as its own systemd unit, which the restart does not touch. # (The terminal shows the output until the agent restarts; the rest is in /var/log/wxch-setup.log.) detach="" if [ "$dry" = 0 ] && command -v systemd-run >/dev/null 2>&1; then if [ "${WXCH_DETACH:-}" = 1 ] || grep -qs 'wxch-agent.service' /proc/self/cgroup; then detach="systemd-run --unit=wxch-setup-$$ --collect --wait --pipe --quiet" echo "wxch: running inside the agent's own session: the installer runs as a separate service (log: /var/log/wxch-setup.log)." fi fi if [ "$(id -u)" = 0 ] || [ "$dry" = 1 ]; then eval "$detach env $args bash \"\$tmp\" \"\$@\"" else eval "sudo $detach env $args bash \"\$tmp\" \"\$@\"" fi