#!/bin/bash set -e APP_DIR="/opt/mbs-panel" ENV_FILE="$APP_DIR/.env" usage() { cat << 'EOF' mbs — управление MBS Panel mbs pass [новый_пароль] сменить пароль админ-панели (без аргумента — сгенерировать случайный) mbs status статус всех сервисов (bot, api, xray, nginx) mbs restart перезапустить всё (bot, api, xray, reload nginx) mbs logs [bot|api|xray] последние строки лога (по умолчанию api) mbs domain показать текущий домен панели mbs update обновить код (зеркало api.savsis.xyz, потом GitHub) и перезапустить (не трогает .env и базу) EOF } cmd_pass() { local new_pass="$1" if [ -z "$new_pass" ]; then new_pass=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 14) fi if grep -q "^ADMIN_PANEL_PASSWORD=" "$ENV_FILE"; then sed -i "s#^ADMIN_PANEL_PASSWORD=.*#ADMIN_PANEL_PASSWORD=$new_pass#" "$ENV_FILE" else echo "ADMIN_PANEL_PASSWORD=$new_pass" >> "$ENV_FILE" fi systemctl restart mbs-api echo "Новый пароль панели: $new_pass" } cmd_status() { systemctl --no-pager status mbs-bot mbs-api xray nginx 2>&1 | grep -E "●|Active:" } cmd_restart() { systemctl restart mbs-bot mbs-api xray systemctl reload nginx 2>/dev/null || true echo "Перезапущено: bot, api, xray (+ reload nginx)." } cmd_logs() { local svc="${1:-api}" case "$svc" in bot) journalctl -u mbs-bot -n 60 --no-pager ;; api) journalctl -u mbs-api -n 60 --no-pager ;; xray) journalctl -u xray -n 60 --no-pager ;; *) echo "неизвестный сервис: $svc (bot|api|xray)"; exit 1 ;; esac } cmd_domain() { grep "^PANEL_DOMAIN=" "$ENV_FILE" } cmd_update() { cd "$APP_DIR" echo "проверяю обновления..." local remote="origin" if ! git fetch --quiet origin main 2>/dev/null; then if git remote | grep -q '^github$'; then echo "зеркало недоступно, пробую github..." if ! git fetch --quiet github main 2>/dev/null; then echo "не удалось получить обновления ни с зеркала, ни с github" return 1 fi remote="github" else echo "не удалось получить обновления" return 1 fi fi local before after before=$(git rev-parse HEAD) after=$(git rev-parse "$remote/main") if [ "$before" = "$after" ]; then echo "уже последняя версия ($before)." return 0 fi echo "текущая: $before" echo "новая: $after" if ! git merge --ff-only "$remote/main" --quiet; then echo "не вышло быстро обновиться (похоже, файлы правились вручную на сервере) — разберись руками: git status" return 1 fi echo "обновляю зависимости..." venv/bin/pip install --quiet -r requirements.txt echo "проверяю код..." if ! venv/bin/python -m py_compile *.py; then echo "новый код не проходит проверку, откатываюсь на $before..." git reset --hard "$before" --quiet venv/bin/pip install --quiet -r requirements.txt return 1 fi echo "обновляю сам CLI..." cp "$APP_DIR/mbs" /usr/local/bin/mbs chmod +x /usr/local/bin/mbs echo "перезапускаю..." systemctl restart mbs-bot mbs-api xray systemctl reload nginx 2>/dev/null || true sleep 2 if systemctl is-active --quiet mbs-bot && systemctl is-active --quiet mbs-api; then echo "обновлено: $before -> $(git rev-parse --short HEAD)" else echo "сервисы не поднялись после обновления, откатываюсь на $before..." git reset --hard "$before" --quiet venv/bin/pip install --quiet -r requirements.txt systemctl restart mbs-bot mbs-api echo "откачено обратно на $before" return 1 fi } case "$1" in pass) cmd_pass "$2" ;; status) cmd_status ;; restart) cmd_restart ;; logs) cmd_logs "$2" ;; domain) cmd_domain ;; update) cmd_update ;; *) usage ;; esac