feat(usable): package gui-host validation snapshot
Some checks failed
release-smoke / macos-13 / x86_64-apple-darwin (push) Has been cancelled
release-smoke / ubuntu-latest / x86_64-unknown-linux-gnu (push) Has been cancelled
release-smoke / windows-latest / x86_64-pc-windows-msvc (push) Has been cancelled

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Paperclip CTO
2026-03-31 10:21:36 +00:00
parent 19aeb7784b
commit a28dab4cd9
47 changed files with 6894 additions and 771 deletions

155
scripts/tui/demo-stack.sh Executable file
View File

@@ -0,0 +1,155 @@
#!/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_USER=dbtool \
-e POSTGRES_PASSWORD=dbtool \
--health-cmd 'pg_isready -U dbtool -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