commit 4f95edd7855f17f137f4e13b269cbef645521b30 Author: Shane Maynard Date: Sun Oct 11 07:02:24 2026 -0400 Add harness bootstrap: setup.sh + README setup.sh is a curl-able one-shot installer for the Pi workstation harness (snowspeeder/harness): prompts for the Gitea username and password (or reads GITEA_USER/GITEA_PASS), verifies them, downloads the harness archive and runs its install.sh --yes. Portable across macOS and Linux (bash 3.2+); reattaches stdin to /dev/tty so the prompts work even when piped via curl | bash. Extra arguments pass through to install.sh. diff --git a/README.md b/README.md new file mode 100644 index 0000000..dd89291 --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# scripts + +Bootstrap scripts for the Pi workstation. + +## Harness setup + +Installs the [harness](https://git.srmr.xyz/snowspeeder/harness) repo — a +portable Pi workstation that rebuilds the whole agent environment (agents, +skills, plugins, settings) and points Pi at the LAN Qwen model. + +### macOS / Linux + +```bash +curl -fsSL https://git.srmr.xyz/snowspeeder/scripts/raw/branch/main/setup.sh | bash +``` + +The script asks for your Gitea **username and password**, verifies them, +downloads the harness archive, and runs its `install.sh`. + +Non-interactive (headless servers): + +```bash +GITEA_USER=you GITEA_PASS=token \ + curl -fsSL https://git.srmr.xyz/snowspeeder/scripts/raw/branch/main/setup.sh | bash +``` + +Extra options are passed through to the harness `install.sh` (see +`install.sh --help` in the harness repo for the full list): + +```bash +curl -fsSL https://git.srmr.xyz/snowspeeder/scripts/raw/branch/main/setup.sh | bash -s -- --dry-run +``` + +### Environment overrides + +| Variable | Meaning | Default | +| --- | --- | --- | +| `GITEA_URL` | Gitea host | `https://git.srmr.xyz` | +| `GITEA_USER` | username (skips the prompt) | — | +| `GITEA_PASS` | password / application token (skips the prompt) | — | +| `HARNESS_REPO` | owner/repo to install | `snowspeeder/harness` | +| `HARNESS_BRANCH` | branch to fetch | `main` | diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..f518b00 --- /dev/null +++ b/setup.sh @@ -0,0 +1,124 @@ +#!/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"