Files
pi-extensions/scripts/install-client.sh
T
shahondin1624 9e70e1bf23 Add midnight-orchid theme + wire it into install-client.sh
- themes/midnight-orchid.json: custom dark purple theme. Deep aubergine
  background (#1a1525), violet/magenta accents, sage/amber/cyan syntax
  for contrast. All 51 required color tokens defined.
- scripts/install-client.sh: adds a themes sync step that rsync's the
  repo's themes/ into ~/.pi/agent/themes/ on each new machine.

Activate with /settings in pi or by setting "theme": "midnight-orchid"
in ~/.pi/agent/settings.json.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 21:35:47 +02:00

129 lines
4.7 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# install-client.sh — Bootstrap a pi client machine for the ai-server extension.
#
# Run this from a checked-out copy of the pi-extensions repo. Idempotent:
# re-running only overwrites targets with --force.
#
# What it does:
# 1. Creates ~/.pi/agent/{certs,extensions} if missing.
# 2. Fetches client.crt, client.key, and root-ca.pem from the Caddy host
# via scp, installing them at the canonical paths the extension expects.
# 3. Rsync's this repo's ai-server/ and local-llama.ts into the extensions dir.
# 4. Ensures key-auth to the ai-server SSH target so admin slash commands work.
# 5. Probes the mTLS endpoint to confirm the full chain works.
#
# Usage:
# scripts/install-client.sh [options]
# --caddy-host USER@HOST default: shahondin1624@192.168.2.2
# --caddy-cert-dir PATH default: /mnt/ssdpool/@docker/caddy/certs
# --ai-server-host USER@HOST default: ai-server@192.168.2.3
# --pi-dir PATH default: $HOME/.pi/agent
# --no-ssh-setup skip ssh-copy-id to ai-server
# --no-certs skip cert fetch (useful if already present)
# --force overwrite existing cert files
# --help show this message and exit
set -euo pipefail
CADDY_HOST="${CADDY_HOST:-shahondin1624@192.168.2.2}"
CADDY_CERT_DIR="${CADDY_CERT_DIR:-/mnt/ssdpool/@docker/caddy/certs}"
AI_SERVER_HOST="${AI_SERVER_HOST:-ai-server@192.168.2.3}"
AI_SERVER_URL="${AI_SERVER_URL:-https://ai.shahondin1624.de}"
PI_DIR="${PI_DIR:-$HOME/.pi/agent}"
DO_SSH_SETUP=1
DO_CERTS=1
FORCE=0
usage() { sed -n '2,/^$/p' "$0" | sed 's/^#\{0,1\} \{0,1\}//'; exit 0; }
while [[ $# -gt 0 ]]; do
case "$1" in
--caddy-host) CADDY_HOST="$2"; shift 2 ;;
--caddy-cert-dir) CADDY_CERT_DIR="$2"; shift 2 ;;
--ai-server-host) AI_SERVER_HOST="$2"; shift 2 ;;
--pi-dir) PI_DIR="$2"; shift 2 ;;
--no-ssh-setup) DO_SSH_SETUP=0; shift ;;
--no-certs) DO_CERTS=0; shift ;;
--force) FORCE=1; shift ;;
-h|--help) usage ;;
*) echo "Unknown arg: $1" >&2; exit 1 ;;
esac
done
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"
[[ -d ai-server ]] || { echo "Run from a checked-out pi-extensions repo (ai-server/ not found)" >&2; exit 1; }
echo "==> pi-extensions client bootstrap"
echo " repo root: $REPO_ROOT"
echo " pi dir: $PI_DIR"
echo " caddy host: $CADDY_HOST"
echo " ai-server: $AI_SERVER_HOST"
mkdir -p "$PI_DIR/certs" "$PI_DIR/extensions"
chmod 700 "$PI_DIR/certs"
# 1) mTLS certs
if [[ $DO_CERTS -eq 1 ]]; then
echo; echo "==> Installing mTLS certs"
for pair in "client.crt:client.pem" "client.key:client-key.pem" "root-ca.pem:root-ca.pem"; do
src="${pair%%:*}"; dst="${pair##*:}"
target="$PI_DIR/certs/$dst"
if [[ -f "$target" && $FORCE -eq 0 ]]; then
echo " $dst already exists, skipping (--force to overwrite)"
continue
fi
echo " scp $CADDY_HOST:$CADDY_CERT_DIR/$src -> $target"
scp -q "$CADDY_HOST:$CADDY_CERT_DIR/$src" "$target"
done
chmod 600 "$PI_DIR"/certs/*.pem 2>/dev/null || true
fi
# 2) Extensions
echo; echo "==> Syncing extensions into $PI_DIR/extensions"
rsync -a --exclude='.git' ai-server "$PI_DIR/extensions/"
[[ -f local-llama.ts ]] && rsync -a local-llama.ts "$PI_DIR/extensions/"
echo " synced ai-server/ and local-llama.ts"
# 2b) Themes (if present in the repo)
if [[ -d themes ]]; then
echo; echo "==> Syncing themes into $PI_DIR/themes"
mkdir -p "$PI_DIR/themes"
rsync -a themes/ "$PI_DIR/themes/"
echo " $(ls themes/*.json 2>/dev/null | wc -l) theme file(s) installed"
fi
# 3) SSH key-auth to the ai-server host (for admin commands)
if [[ $DO_SSH_SETUP -eq 1 ]]; then
echo; echo "==> Checking SSH key-auth to $AI_SERVER_HOST"
if ssh -o BatchMode=yes -o ConnectTimeout=5 "$AI_SERVER_HOST" 'true' 2>/dev/null; then
echo " already have key-auth"
else
echo " no key-auth; attempting ssh-copy-id (will prompt for password)"
if [[ ! -f "$HOME/.ssh/id_ed25519.pub" && ! -f "$HOME/.ssh/id_rsa.pub" ]]; then
echo " no ssh key found locally; generating ed25519"
ssh-keygen -t ed25519 -N '' -f "$HOME/.ssh/id_ed25519"
fi
ssh-copy-id "$AI_SERVER_HOST"
fi
fi
# 4) Sanity check — mTLS handshake + router health
echo; echo "==> Verifying mTLS reachability"
if curl -sS --max-time 5 \
--cert "$PI_DIR/certs/client.pem" \
--key "$PI_DIR/certs/client-key.pem" \
--cacert "$PI_DIR/certs/root-ca.pem" \
"$AI_SERVER_URL/health" | grep -q '"ok"'; then
echo " ✓ mTLS handshake + /health OK"
else
echo " ✗ could not verify — check cert files and server reachability"
exit 1
fi
echo
echo "==> Done."
echo " Next: open pi and run /reload, then /ai-server-status to confirm."