Files
weichen b812d1d30f feat(dev): single-binary no-docker runtime with managed localpg
Embed web/dist, run events in-process, manage brew PG18+pgvector, add PI host sidecar and launch --no-docker; unify MiniMax-M2.7-highspeed pins and record dev acceptance.
2026-09-24 15:53:50 +00:00

103 lines
4.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# migrate-dev-db.sh — dump container system-db → brew localpg (PG18) on :5433
#
# Prerequisites:
# - LOCALPG_MODE=managed server once started (or this script can start pg via pg_ctl)
# - container shuimu-context-pg-dev healthy
# - brew postgresql@18 + pgvector installed
#
# Does NOT delete the docker volume (rollback: compose up system-db).
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
PG_BIN="${LOCALPG_BIN:-/home/linuxbrew/.linuxbrew/opt/postgresql@18/bin}"
DATA_DIR="${DATA_DIR:-$ROOT/data/dev}"
PGDATA="${PGDATA:-$DATA_DIR/pg}"
PORT="${CONTEXT_DB_PORT:-5433}"
DB_USER="${CONTEXT_DB_USER:-app}"
DB_PASS="${CONTEXT_DB_PASSWORD:-dev_secret_db_pass}"
DB_NAME="${CONTEXT_DB_NAME:-agent_system_dev}"
CONTAINER="${DEV_PG_CONTAINER:-shuimu-context-pg-dev}"
DUMP="${DUMP_PATH:-$ROOT/.tmp/dev-pg-migrate.dump}"
info() { printf '\033[1;34m[migrate-dev-db]\033[0m %s\n' "$*"; }
fail() { printf '\033[1;31m[migrate-dev-db]\033[0m %s\n' "$*"; exit 1; }
[[ -x "$PG_BIN/pg_ctl" ]] || fail "pg_ctl not found at $PG_BIN (set LOCALPG_BIN)"
docker inspect "$CONTAINER" >/dev/null 2>&1 || fail "container $CONTAINER not found"
info "dumping $CONTAINER → $DUMP"
docker exec "$CONTAINER" pg_dump -U "${SYSTEM_DB_USER:-app}" -d "${SYSTEM_DB_NAME:-agent_system_dev}" -Fc -f /tmp/dev.dump
docker cp "$CONTAINER:/tmp/dev.dump" "$DUMP"
# Free :5433 for localpg (do not remove volume — rollback via compose up).
if docker inspect "$CONTAINER" --format '{{.State.Running}}' 2>/dev/null | grep -qi true; then
info "stopping container $CONTAINER to free port $PORT (volume kept)"
docker stop "$CONTAINER" >/dev/null
fi
SOCK="${PG_SOCKET_DIR:-${LOCALPG_SOCKET_DIR:-${XDG_RUNTIME_DIR:-/tmp}/as-pg-$PORT}}"
mkdir -p "$(dirname "$DUMP")" "$SOCK"
# Ensure local PG is up via pg_ctl (avoid agent-server migrations before restore).
if ! "$PG_BIN/pg_isready" -h 127.0.0.1 -p "$PORT" >/dev/null 2>&1; then
info "local PG not ready on :$PORT — initdb/pg_ctl bootstrap..."
mkdir -p "$ROOT/.tmp/launch"
if [[ ! -f "$PGDATA/PG_VERSION" ]]; then
rm -rf "$PGDATA"
mkdir -p "$PGDATA"
"$PG_BIN/initdb" -D "$PGDATA" --locale=C --encoding=UTF8 --auth-local=trust --auth-host=scram-sha-256 -U postgres
{
echo "listen_addresses = '127.0.0.1'"
echo "port = $PORT"
echo "unix_socket_directories = '$SOCK'"
} >>"$PGDATA/postgresql.conf"
cat >"$PGDATA/pg_hba.conf" <<'HBA'
# TYPE DATABASE USER ADDRESS METHOD
local all all trust
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
HBA
fi
"$PG_BIN/pg_ctl" -D "$PGDATA" -l "$PGDATA/pg.log" -o "-p $PORT -k $SOCK" start
for ((i = 0; i < 60; i++)); do
"$PG_BIN/pg_isready" -h 127.0.0.1 -p "$PORT" >/dev/null 2>&1 && break
sleep 1
done
"$PG_BIN/pg_isready" -h 127.0.0.1 -p "$PORT" >/dev/null 2>&1 || fail "local PG still not listening after bootstrap"
# Ensure app role exists before CREATE DATABASE OWNER.
"$PG_BIN/psql" -h "$SOCK" -p "$PORT" -U postgres -v ON_ERROR_STOP=1 <<SQL
DO \$\$ BEGIN
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '$DB_USER') THEN
CREATE ROLE $DB_USER LOGIN PASSWORD '$DB_PASS';
ELSE
ALTER ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';
END IF;
END \$\$;
SQL
fi
info "dropping & recreating local database $DB_NAME (owner $DB_USER)"
"$PG_BIN/psql" -h "$SOCK" -p "$PORT" -U postgres -v ON_ERROR_STOP=1 <<SQL
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '$DB_NAME' AND pid <> pg_backend_pid();
DROP DATABASE IF EXISTS $DB_NAME;
CREATE DATABASE $DB_NAME OWNER $DB_USER;
\\c $DB_NAME
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS pg_trgm;
GRANT ALL ON SCHEMA public TO $DB_USER;
SQL
info "restoring dump into local $DB_NAME"
"$PG_BIN/pg_restore" -h "$SOCK" -p "$PORT" -U postgres -d "$DB_NAME" --no-owner --role="$DB_USER" --verbose "$DUMP" \
|| info "pg_restore exited non-zero (often OK with extension noise); verify goose version next"
info "goose version on local:"
export PGPASSWORD="$DB_PASS"
"$PG_BIN/psql" -h 127.0.0.1 -p "$PORT" -U "$DB_USER" -d "$DB_NAME" -c \
"SELECT COALESCE(MAX(version_id),0) AS goose_version FROM goose_db_version;" || true
info "done. Next: docker compose -f docker-compose.dev.yml -p agent-dev stop system-db"
info "Rollback: docker compose -f docker-compose.dev.yml -p agent-dev up -d system-db"