#!/usr/bin/env bash # Clawmates air-gapped installer. Verifies the signed bundle FULLY OFFLINE # (ed25519 signature over sha256 checksums) before anything is loaded; # a failed verification aborts with nothing touched. # # Usage: # ./install.sh [--verify-only] # # The bundle layout (produced by clawmates-bundler assemble): # bin/clawmates-bundler verifier binary # images/*.tar docker image tarballs # compose/ docker-compose.yml + clawmates.toml + .env.example # checksums.txt + checksums.sig + manifest.json set -euo pipefail BUNDLE="${1:?usage: install.sh [--verify-only]}" PUBKEY="${2:?usage: install.sh [--verify-only]}" MODE="${3:-install}" BUNDLER="$BUNDLE/bin/clawmates-bundler" if [ ! -x "$BUNDLER" ]; then echo "install.sh: verifier missing at $BUNDLER" >&2 exit 1 fi echo "Verifying bundle signature and checksums (offline)…" "$BUNDLER" verify "$BUNDLE" "$PUBKEY" if [ "$MODE" = "--verify-only" ]; then echo "Verification complete; skipping install (--verify-only)." exit 0 fi echo "Loading container images…" for tarball in "$BUNDLE"/images/*.tar; do docker load --input "$tarball" done echo "Installing compose deployment…" TARGET="${CLAWMATES_HOME:-/opt/clawmates}" mkdir -p "$TARGET" cp -R "$BUNDLE/compose/." "$TARGET/" if [ ! -f "$TARGET/.env" ]; then cp "$TARGET/.env.example" "$TARGET/.env" echo "Edit $TARGET/.env (set POSTGRES_PASSWORD), then run:" echo " docker compose --project-directory $TARGET up -d" exit 0 fi docker compose --project-directory "$TARGET" up -d echo "Clawmates is starting; the server self-migrates on boot."