#!/usr/bin/env bash # Live end-to-end PULL over real HTTP between two THROWAWAY SQLite instances. # The SOURCE runs as a real `saltcorn serve` process; the TARGET is driven # in-process and pulls the source's design state over the wire. Never touches # Scott's instances or the shared plugins folder: all state, and the plugins folder # the by-location install copies into, live in one mktemp dir (see testEnv.sh). set -euo pipefail HERE="$(cd "$(dirname "$0")" && pwd)" PLUGIN="$(dirname "$HERE")" REPO="$(dirname "$PLUGIN")" SC_BIN="$REPO/saltcorn/packages/saltcorn-cli/bin/saltcorn" # shellcheck source=testEnv.sh . "$HERE/testEnv.sh" # SRC_PORT may be overridden; it must be free (never an existing instance's port). SRC_PORT="${SRC_PORT:-3016}" # One private state root per invocation, outside the plugin tree (see testEnv.sh). STATE="$(make_state_dir site-sync-live)" SRC_STATE="$STATE/src" TGT_STATE="$STATE/tgt" SRC_DB="$SRC_STATE/db.sqlite" TGT_DB="$TGT_STATE/db.sqlite" SHARED="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" NP="$REPO/saltcorn/node_modules" UP_WAIT_SECONDS=60 ROUTE_GRACE_SECONDS=2 ENV_ID_RE='^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' SRC_PID="" cleanup() { if [ -n "$SRC_PID" ]; then kill "$SRC_PID" 2>/dev/null || true wait "$SRC_PID" 2>/dev/null || true fi rm -rf "$STATE" } trap cleanup EXIT isolate_saltcorn_dirs "$STATE" if (echo >"/dev/tcp/127.0.0.1/$SRC_PORT") 2>/dev/null; then echo "FAILED: port $SRC_PORT is already in use (set SRC_PORT to a free port)" exit 1 fi mkdir -p "$SRC_STATE/files" "$TGT_STATE/files" srcRun() { env SQLITE_FILEPATH="$SRC_DB" SALTCORN_FILE_STORE="$SRC_STATE/files" SALTCORN_SESSION_SECRET="live-src-secret" SALTCORN_NWORKERS=1 NODE_PATH="$NP" "$@"; } tgtRun() { env SQLITE_FILEPATH="$TGT_DB" SALTCORN_FILE_STORE="$TGT_STATE/files" SALTCORN_SESSION_SECRET="live-tgt-secret" SALTCORN_NWORKERS=1 NODE_PATH="$NP" "$@"; } # grep the ENV_ID marker so the plugin's own onLoad stdout log never pollutes it. extractEnv() { grep -oE 'ENV_ID=[0-9a-f-]+' | tail -1 | cut -d= -f2; } requireEnvId() { if ! [[ "$2" =~ $ENV_ID_RE ]]; then echo "FAILED: could not read the $1 env_id (got '$2')" exit 1 fi } echo "# init schemas" srcRun node "$SC_BIN" reset-schema --force >/dev/null tgtRun node "$SC_BIN" reset-schema --force >/dev/null echo "# bootstrap target + source, pair" TGT_ENV="$(tgtRun node "$HERE/livePull.js" init-target | extractEnv)" requireEnvId target "$TGT_ENV" SRC_ENV="$(srcRun env TARGET_ENV="$TGT_ENV" SHARED="$SHARED" node "$HERE/livePull.js" init-source | extractEnv)" requireEnvId source "$SRC_ENV" tgtRun env SOURCE_ENV="$SRC_ENV" SOURCE_URL="http://127.0.0.1:$SRC_PORT" SHARED="$SHARED" node "$HERE/livePull.js" pair-target echo " source env_id=$SRC_ENV" echo " target env_id=$TGT_ENV" echo "# start SOURCE server on :$SRC_PORT" ( cd "$SRC_STATE" && exec env SQLITE_FILEPATH="$SRC_DB" SALTCORN_FILE_STORE="$SRC_STATE/files" SALTCORN_SESSION_SECRET="live-src-secret" SALTCORN_NWORKERS=1 NODE_PATH="$NP" node "$SC_BIN" serve -p "$SRC_PORT" ) >"$SRC_STATE/serve.log" 2>&1 & SRC_PID=$! echo -n " waiting for :$SRC_PORT " UP=0 for _ in $(seq 1 "$UP_WAIT_SECONDS"); do if (echo >"/dev/tcp/127.0.0.1/$SRC_PORT") 2>/dev/null; then UP=1 echo "up" break fi echo -n "." sleep 1 done if [ "$UP" != "1" ]; then echo " FAILED to come up; serve.log tail:" tail -20 "$SRC_STATE/serve.log" exit 1 fi # small grace period for plugin route mounting sleep "$ROUTE_GRACE_SECONDS" echo "# DRIVE pull (target in-process -> source over HTTP)" tgtRun env SOURCE_ENV="$SRC_ENV" SOURCE_URL="http://127.0.0.1:$SRC_PORT" node "$HERE/livePull.js" drive