#!/usr/bin/env bash # Portico installer bootstrap. # # curl -fsSL https://porticofamily.com/install.sh | bash # # Downloads the Portico server from porticofamily.com, checks its integrity, and # hands off to the package's own setup.sh — which creates your config, generates a # private alert topic, checks which helpers you have, runs the safety tests, and # stops. It starts nothing and changes no system files. # # The checksum comes from the same host as the package, so it catches corruption # and truncation, not a compromised host. If you want provenance, read this file # before piping it and the package's setup.sh after it downloads. Both are short, # and that is on purpose. set -euo pipefail BASE="${PORTICO_BASE_URL:-https://porticofamily.com}" PKG="portico.tar.gz" DEST="${PORTICO_DIR:-$HOME/portico}" say() { printf '\n\033[1;32m==>\033[0m %s\n' "$*"; } command -v curl >/dev/null 2>&1 || { echo "!! curl is required" >&2; exit 1; } command -v tar >/dev/null 2>&1 || { echo "!! tar is required" >&2; exit 1; } command -v node >/dev/null 2>&1 || { echo "!! Node.js is required. On a Pi or Debian:" >&2 echo " sudo apt-get update && sudo apt-get install -y nodejs" >&2 exit 1; } sha_check() { if command -v sha256sum >/dev/null 2>&1; then sha256sum -c "$1" elif command -v shasum >/dev/null 2>&1; then shasum -a 256 -c "$1" else echo "!! no sha256sum or shasum; cannot verify the download" >&2; exit 1; fi } WORK="$(mktemp -d)"; trap 'rm -rf "$WORK"' EXIT cd "$WORK" say "downloading $BASE/get/$PKG" # Accept-Encoding pinned to identity: a CDN will otherwise transcode the gzip body # in flight and the checksum can never match the published one. curl -fsSL -H 'Accept-Encoding: identity' "$BASE/get/$PKG" -o "$PKG" curl -fsSL -H 'Accept-Encoding: identity' "$BASE/get/$PKG.sha256" -o "$PKG.sha256" say "verifying checksum" sha_check "$PKG.sha256" tar -xzf "$PKG" say "version $(cat portico/VERSION 2>/dev/null || echo unknown)" if [ -e "$DEST" ]; then say "$DEST already exists — updating code, keeping your config and ledger" # Never touch what is yours: config, family, device tokens, the ledger. rsync -a --exclude 'portico.config.json' --exclude 'family.json' \ --exclude 'portico.state.json' --exclude 'ledger/' --exclude 'scratch/' \ portico/ "$DEST/" 2>/dev/null || cp -R portico/. "$DEST/" else mkdir -p "$(dirname "$DEST")" cp -R portico "$DEST" say "installed to $DEST" fi cd "$DEST" exec bash setup.sh "$@"