#!/usr/bin/env bash # Управление: PostgreSQL + Login/Game (Essence 520, profile l2). set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' ENV_FILE="$SCRIPT_DIR/.env" PROFILE_L2=(--profile l2) PG_CONTAINER="l2_postgres" LOGIN_CONTAINER="l2_login" GAME_CONTAINER="l2_game" read_env_val() { local key="$1" grep -m1 "^${key}=" "$ENV_FILE" | sed "s/^${key}=//" } ask_yes_no() { local prompt="$1" local default="${2:-n}" local hint="[y/N]" [[ "$default" == "y" ]] && hint="[Y/n]" while true; do read -r -p "$prompt $hint: " ans ans="${ans:-$default}" case "$ans" in [Yy]|[Yy][Ee][Ss]) return 0 ;; [Nn]|[Nn][Oo]) return 1 ;; *) echo "Введите y или n." ;; esac done } info() { echo -e "${GREEN}[*]${NC} $*"; } warn() { echo -e "${YELLOW}[!]${NC} $*"; } err() { echo -e "${RED}[x]${NC} $*" >&2; } step_header() { echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo " $1" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" } ensure_docker() { if ! command -v docker >/dev/null 2>&1 || ! docker compose version >/dev/null 2>&1; then err "Нужны Docker и docker compose. Запустите ./install.sh" exit 1 fi if ! docker info >/dev/null 2>&1; then err "Docker недоступен." exit 1 fi } ensure_env() { if [[ ! -f "$ENV_FILE" ]]; then err "Нет .env. Сначала ./install.sh" exit 1 fi } container_running() { [[ "$(docker inspect -f '{{.State.Running}}' "$1" 2>/dev/null || echo false)" == "true" ]] } postgres_running() { container_running "$PG_CONTAINER"; } login_running() { container_running "$LOGIN_CONTAINER"; } game_running() { container_running "$GAME_CONTAINER"; } step_header "Шаг 0 — Essence 520 (PostgreSQL + Login/Game)" if ! ask_yes_no "Продолжить?" "y"; then exit 0 fi ensure_docker ensure_env step_header "Шаг 1 — Статус" if ask_yes_no "Показать docker compose ps?" "y"; then docker compose ps -a || true docker compose "${PROFILE_L2[@]}" ps -a 2>/dev/null || true fi step_header "Шаг 2 — Остановка" if ask_yes_no "Остановить game и login (profile l2)?" "n"; then docker compose "${PROFILE_L2[@]}" stop game login 2>/dev/null || true fi if ask_yes_no "Остановить PostgreSQL?" "n"; then docker compose stop postgres 2>/dev/null || true fi if ask_yes_no "docker compose down (все сервисы, том БД сохраняется)?" "n"; then docker compose "${PROFILE_L2[@]}" down docker compose down fi if ask_yes_no "Удалить том БД (down -v)? ОПАСНО." "n"; then if ask_yes_no "Точно удалить?" "n"; then docker compose "${PROFILE_L2[@]}" down -v docker compose down -v fi fi step_header "Шаг 3 — Запуск" if ask_yes_no "Запустить PostgreSQL?" "n"; then docker compose up -d postgres EV_USER="$(read_env_val POSTGRES_USER)" EV_DB="$(read_env_val POSTGRES_DB)" for _ in $(seq 1 60); do docker compose exec -T postgres pg_isready -U "$EV_USER" -d "$EV_DB" >/dev/null 2>&1 && break sleep 1 done fi if ask_yes_no "Запустить login + game (profile l2)?" "n"; then if postgres_running; then docker compose "${PROFILE_L2[@]}" up -d login game else warn "Сначала поднимите postgres." fi fi step_header "Шаг 4 — Перезапуск" if ask_yes_no "Перезапустить PostgreSQL?" "n"; then if postgres_running; then docker compose restart postgres else docker compose up -d postgres fi fi if ask_yes_no "Перезапустить login?" "n"; then login_running && docker compose "${PROFILE_L2[@]}" restart login || warn "login не запущен." fi if ask_yes_no "Перезапустить game?" "n"; then game_running && docker compose "${PROFILE_L2[@]}" restart game || warn "game не запущен." fi if ask_yes_no "Полный перезапуск: down → postgres → login → game?" "n"; then docker compose "${PROFILE_L2[@]}" down docker compose down docker compose up -d postgres sleep 3 docker compose "${PROFILE_L2[@]}" up -d login game fi step_header "Готово" if ask_yes_no "Показать статус?" "y"; then docker compose ps -a docker compose "${PROFILE_L2[@]}" ps -a 2>/dev/null || true fi info "Логи: docker compose logs -f login game postgres"