155 lines
3.8 KiB
Bash
Executable File
155 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
COMPOSE_FILE="${COMPOSE_FILE:-$ROOT_DIR/docker-compose.demo.yml}"
|
|
POSTGRES_CONTAINER_NAME="${POSTGRES_CONTAINER_NAME:-dbtool-cli-v1-postgres-1}"
|
|
MYSQL_CONTAINER_NAME="${MYSQL_CONTAINER_NAME:-dbtool-cli-v1-mysql-1}"
|
|
DEMO_NETWORK_NAME="${DEMO_NETWORK_NAME:-dbtool-cli-v1_default}"
|
|
|
|
usage() {
|
|
echo "usage: scripts/tui/demo-stack.sh <up|down|seed|reset|status>" >&2
|
|
exit 2
|
|
}
|
|
|
|
docker_compose_available() {
|
|
docker compose version >/dev/null 2>&1
|
|
}
|
|
|
|
container_exists() {
|
|
local container_name="$1"
|
|
docker container inspect "$container_name" >/dev/null 2>&1
|
|
}
|
|
|
|
container_running() {
|
|
local container_name="$1"
|
|
[ "$(docker inspect -f '{{.State.Running}}' "$container_name" 2>/dev/null || true)" = "true" ]
|
|
}
|
|
|
|
ensure_network() {
|
|
if ! docker network inspect "$DEMO_NETWORK_NAME" >/dev/null 2>&1; then
|
|
docker network create "$DEMO_NETWORK_NAME" >/dev/null
|
|
fi
|
|
}
|
|
|
|
wait_for_health() {
|
|
local container_name="$1"
|
|
local max_attempts="${2:-60}"
|
|
local attempt=1
|
|
while [ "$attempt" -le "$max_attempts" ]; do
|
|
local health
|
|
health="$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}running{{end}}' "$container_name" 2>/dev/null || true)"
|
|
if [ "$health" = "healthy" ] || [ "$health" = "running" ]; then
|
|
return 0
|
|
fi
|
|
sleep 2
|
|
attempt=$((attempt + 1))
|
|
done
|
|
echo "error: container did not become healthy: $container_name" >&2
|
|
docker logs --tail 50 "$container_name" >&2 || true
|
|
exit 1
|
|
}
|
|
|
|
run_postgres_container() {
|
|
if container_exists "$POSTGRES_CONTAINER_NAME"; then
|
|
if ! container_running "$POSTGRES_CONTAINER_NAME"; then
|
|
docker start "$POSTGRES_CONTAINER_NAME" >/dev/null
|
|
fi
|
|
return
|
|
fi
|
|
|
|
ensure_network
|
|
docker run -d \
|
|
--name "$POSTGRES_CONTAINER_NAME" \
|
|
--network "$DEMO_NETWORK_NAME" \
|
|
-p 55432:5432 \
|
|
-e POSTGRES_DB=dbtool_demo \
|
|
-e POSTGRES_PASSWORD=dbtoolroot \
|
|
--health-cmd 'pg_isready -U postgres -d dbtool_demo' \
|
|
--health-interval 5s \
|
|
--health-timeout 5s \
|
|
--health-retries 20 \
|
|
postgres:16 >/dev/null
|
|
}
|
|
|
|
run_mysql_container() {
|
|
if container_exists "$MYSQL_CONTAINER_NAME"; then
|
|
if ! container_running "$MYSQL_CONTAINER_NAME"; then
|
|
docker start "$MYSQL_CONTAINER_NAME" >/dev/null
|
|
fi
|
|
return
|
|
fi
|
|
|
|
ensure_network
|
|
docker run -d \
|
|
--name "$MYSQL_CONTAINER_NAME" \
|
|
--network "$DEMO_NETWORK_NAME" \
|
|
-p 53306:3306 \
|
|
-e MYSQL_DATABASE=dbtool_demo \
|
|
-e MYSQL_USER=dbtool \
|
|
-e MYSQL_PASSWORD=dbtool \
|
|
-e MYSQL_ROOT_PASSWORD=dbtoolroot \
|
|
--health-cmd 'mysqladmin ping -uroot -pdbtoolroot' \
|
|
--health-interval 5s \
|
|
--health-timeout 5s \
|
|
--health-retries 30 \
|
|
mysql:8.4 \
|
|
mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci >/dev/null
|
|
}
|
|
|
|
up_stack() {
|
|
if docker_compose_available; then
|
|
docker compose -f "$COMPOSE_FILE" up -d postgres mysql
|
|
else
|
|
run_postgres_container
|
|
run_mysql_container
|
|
fi
|
|
wait_for_health "$POSTGRES_CONTAINER_NAME"
|
|
wait_for_health "$MYSQL_CONTAINER_NAME"
|
|
echo "Demo stack is ready."
|
|
}
|
|
|
|
down_stack() {
|
|
if docker_compose_available; then
|
|
docker compose -f "$COMPOSE_FILE" down -v
|
|
return
|
|
fi
|
|
|
|
docker rm -f "$POSTGRES_CONTAINER_NAME" "$MYSQL_CONTAINER_NAME" >/dev/null 2>&1 || true
|
|
}
|
|
|
|
seed_stack() {
|
|
"$ROOT_DIR/examples/scripts/bootstrap-postgres.sh"
|
|
"$ROOT_DIR/examples/scripts/bootstrap-mysql.sh"
|
|
}
|
|
|
|
status_stack() {
|
|
docker ps --filter "name=$POSTGRES_CONTAINER_NAME" --filter "name=$MYSQL_CONTAINER_NAME" \
|
|
--format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
|
|
}
|
|
|
|
command="${1:-}"
|
|
|
|
case "$command" in
|
|
up)
|
|
up_stack
|
|
;;
|
|
down)
|
|
down_stack
|
|
;;
|
|
seed)
|
|
seed_stack
|
|
;;
|
|
reset)
|
|
down_stack
|
|
up_stack
|
|
seed_stack
|
|
;;
|
|
status)
|
|
status_stack
|
|
;;
|
|
*)
|
|
usage
|
|
;;
|
|
esac
|