#!/usr/bin/env bash # # setup.sh — one-shot bootstrap for the Pi workstation harness. # # Downloads the private Gitea repo `snowspeeder/harness` and runs its # install.sh, which rebuilds the whole Pi agent environment (agents, # skills, plugins, settings) and points Pi at the LAN Qwen model. # # Works on macOS and Linux (bash 3.2+, curl, tar). # # Interactive (prompts for the Gitea username and password): # # curl -fsSL https://git.srmr.xyz/snowspeeder/scripts/raw/branch/main/setup.sh | bash # # Non-interactive (credentials from the environment): # # GITEA_USER=you GITEA_PASS=token \ # curl -fsSL https://git.srmr.xyz/snowspeeder/scripts/raw/branch/main/setup.sh | bash # # Extra arguments are passed through to the harness install.sh: # # curl -fsSL .../setup.sh | bash -s -- --dry-run # # Environment: # GITEA_URL Gitea host (default: https://git.srmr.xyz) # GITEA_USER username (skips the prompt when set) # GITEA_PASS password or application token (skips the prompt when set) # HARNESS_REPO owner/repo (default: snowspeeder/harness) # HARNESS_BRANCH branch to fetch (default: main) set -euo pipefail GITEA_URL="${GITEA_URL:-https://git.srmr.xyz}" HARNESS_REPO="${HARNESS_REPO:-snowspeeder/harness}" HARNESS_BRANCH="${HARNESS_BRANCH:-main}" log() { printf '[setup] %s\n' "$*"; } die() { printf '[setup] error: %s\n' "$*" >&2; exit 1; } usage() { cat <<'EOF' setup.sh — download the harness repo from Gitea and run its install.sh Usage: curl -fsSL https://git.srmr.xyz/snowspeeder/scripts/raw/branch/main/setup.sh | bash ./setup.sh [install.sh options...] extra options pass through to install.sh The Gitea username and password are prompted for during installation (unless GITEA_USER / GITEA_PASS are already set in the environment). Options: -h, --help Show this help (everything else is passed to install.sh) Environment: GITEA_URL Gitea host (default: https://git.srmr.xyz) GITEA_USER username (skips the prompt when set) GITEA_PASS password or application token (skips the prompt when set) HARNESS_REPO owner/repo (default: snowspeeder/harness) HARNESS_BRANCH branch to fetch (default: main) EOF } for arg in "$@"; do case "$arg" in -h|--help) usage; exit 0 ;; esac done # When the script arrives through a pipe (curl ... | bash), stdin is the # pipe itself and already consumed. Reattach it to the controlling # terminal so the credential prompts can read from the keyboard. # Probe in a subshell first: if /dev/tty cannot be opened (no controlling # terminal), keep the pipe stdin and fall back to the environment. if [ ! -t 0 ]; then if ( : 0/dev/null; then exec 0&2 IFS= read -r GITEA_USER else die "no Gitea username: set GITEA_USER or run interactively" fi fi if [ -z "${GITEA_PASS:-}" ]; then if [ -t 0 ]; then printf 'Gitea password (or application token) for %s: ' "$GITEA_USER" >&2 IFS= read -rs GITEA_PASS printf '\n' >&2 else die "no Gitea password: set GITEA_PASS or run interactively" fi fi log "verifying credentials against $GITEA_URL" curl -fsS -m 30 -u "$GITEA_USER:$GITEA_PASS" "$GITEA_URL/api/v1/user" >/dev/null \ || die "authentication failed for '$GITEA_USER' against $GITEA_URL" # --- download the harness archive ---------------------------------------------- WORK_DIR="$(mktemp -d "${TMPDIR:-/tmp}/harness-setup.XXXXXX")" trap 'rm -rf "$WORK_DIR"' EXIT ARCHIVE_URL="$GITEA_URL/$HARNESS_REPO/archive/refs/heads/$HARNESS_BRANCH.tar.gz" log "downloading $ARCHIVE_URL" curl -fsSL -m 600 -u "$GITEA_USER:$GITEA_PASS" "$ARCHIVE_URL" | tar xz -C "$WORK_DIR" \ || die "download or extraction failed" REPO_DIR="$(find "$WORK_DIR" -maxdepth 1 -mindepth 1 -type d -print -quit)" [ -n "$REPO_DIR" ] || die "the archive extracted to nothing" [ -f "$REPO_DIR/install.sh" ] || die "install.sh not found in $REPO_DIR" chmod +x "$REPO_DIR/install.sh" # --- run the harness installer --------------------------------------------------- log "running install.sh --yes $*" # Keep the credentials out of the child process environment. unset GITEA_USER GITEA_PASS "$REPO_DIR/install.sh" --yes "$@" log "harness setup complete"