diff --git a/deploy.sh b/deploy.sh index b7364c7..ef38980 100755 --- a/deploy.sh +++ b/deploy.sh @@ -4,8 +4,15 @@ RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' +BLUE='\033[0;34m' NC='\033[0m' # No Color +# Конфигурация +REPO_URL="https://git.tvstart.ru/ychernenko/RFB.git" +TARGET_DIR="/root/RFB" +SERVICE_NAME="rfb-data.service" +TARGET_ENV="/mnt/rfb/.env" + show_help() { echo "Использование: $0 -t <домашняя команда> -r <релиз> [-l <лига>]" echo " -t Домашняя команда" @@ -33,13 +40,41 @@ log_error() { echo -e "${RED}[ERROR]${NC} $1" >&2 } +log_debug() { + echo -e "${BLUE}[DEBUG]${NC} $1" >&2 +} + +# Функция проверки зависимостей системы +check_dependencies() { + local deps=("git" "python3" "pip3" "netstat" "systemctl") + local missing=() + + for dep in "${deps[@]}"; do + if ! command -v "$dep" &> /dev/null; then + missing+=("$dep") + fi + done + + if [ ${#missing[@]} -ne 0 ]; then + log_warn "Отсутствуют некоторые команды: ${missing[*]}" + return 1 + fi + return 0 +} + # Функция проверки и установки пакетов install_packages() { log_info "Обновление списка пакетов..." - apt-get update + if ! apt-get update; then + log_error "Ошибка при обновлении списка пакетов" + exit 1 + fi log_info "Установка необходимых пакетов..." - apt-get install -y python3 python3-pip python3-venv git net-tools + if ! apt-get install -y python3 python3-pip python3-venv git net-tools; then + log_error "Ошибка при установке пакетов" + exit 1 + fi # Проверка установки if ! command -v python3 &> /dev/null; then @@ -58,32 +93,36 @@ install_packages() { # Функция загрузки кода download_code() { - local repo_url="https://git.tvstart.ru/ychernenko/RFB.git" local release="$1" - local target_dir="/root/RFB" + local target_dir="$TARGET_DIR" log_info "Создание рабочей директории $target_dir..." - mkdir -p $target_dir + mkdir -p "$target_dir" if [ -d "$target_dir/.git" ]; then log_info "Обновление существующего репозитория..." - cd $target_dir + cd "$target_dir" || exit 1 git fetch --all - git checkout $release - git pull origin $release + if ! git checkout "$release"; then + log_error "Не удалось переключиться на релиз $release" + log_info "Доступные ветки:" + git branch -r + exit 1 + fi + git pull origin "$release" else - log_info "Клонирование репозитория $repo_url..." - git clone $repo_url $target_dir - cd $target_dir - git checkout $release - fi - - # Проверка успешности checkout - if [ $? -ne 0 ]; then - log_error "Не удалось переключиться на релиз $release" - log_error "Доступные ветки:" - git branch -r - exit 1 + log_info "Клонирование репозитория $REPO_URL..." + if ! git clone "$REPO_URL" "$target_dir"; then + log_error "Ошибка при клонировании репозитория" + exit 1 + fi + cd "$target_dir" || exit 1 + if ! git checkout "$release"; then + log_error "Не удалось переключиться на релиз $release" + log_info "Доступные ветки:" + git branch -r + exit 1 + fi fi log_info "Код успешно загружен (релиз: $release)" @@ -93,11 +132,20 @@ download_code() { # Функция настройки виртуального окружения setup_venv() { - local target_dir="/root/RFB" - cd $target_dir + local target_dir="$TARGET_DIR" + cd "$target_dir" || exit 1 + + # Удаляем существующее виртуальное окружение для чистоты + if [ -d ".venv" ]; then + log_info "Удаление существующего виртуального окружения..." + rm -rf .venv + fi log_info "Создание виртуального окружения..." - python3 -m venv .venv + if ! python3 -m venv .venv; then + log_error "Не удалось создать виртуальное окружение" + exit 1 + fi if [ ! -f ".venv/bin/activate" ]; then log_error "Не удалось создать виртуальное окружение" @@ -107,43 +155,62 @@ setup_venv() { log_info "Активация виртуального окружения и установка зависимостей..." source .venv/bin/activate - # Обновление pip - pip install --upgrade pip + # Обновление pip3 + if ! pip3 install --upgrade pip3; then + log_warn "Не удалось обновить pip3" + fi # Проверка наличия requirements.txt if [ -f "requirements.txt" ]; then log_info "Установка зависимостей из requirements.txt..." - if pip install -r requirements.txt; then + if pip3 install -r requirements.txt; then log_info "Все зависимости успешно установлены" else log_error "Ошибка при установке зависимостей из requirements.txt" - log_warn "Попытка установки базовых зависимостей..." - pip install requests pandas numpy + exit 1 fi else log_warn "Файл requirements.txt не найден, устанавливаем базовые зависимости..." - pip install requests pandas numpy + if ! pip3 install requests pandas numpy fastapi uvicorn python-telegram-handler python-dotenv; then + log_error "Ошибка при установке базовых зависимостей" + exit 1 + fi fi # Проверка основных пакетов log_info "Проверка установки основных пакетов..." - python -c " + if ! python -c " try: import requests, pandas, numpy print('✓ Все основные пакеты успешно импортируются') except ImportError as e: print(f'✗ Ошибка импорта: {e}') exit(1) -" +"; then + log_error "Ошибка при проверке пакетов" + exit 1 + fi log_info "Установленные пакеты:" - pip list --format=columns + pip3 list --format=columns } - # Функция создания systemd сервиса create_systemd_service() { + log_info "Создание systemd сервиса" local team="$1" local league="$2" + + # Останавливаем и отключаем старый сервис если он есть + if systemctl is-active --quiet "$SERVICE_NAME"; then + log_info "Остановка $SERVICE_NAME..." + systemctl stop "$SERVICE_NAME" + fi + + if systemctl is-enabled --quiet "$SERVICE_NAME"; then + log_info "Отключение $SERVICE_NAME..." + systemctl disable "$SERVICE_NAME" + fi + log_info "Создание systemd сервиса для команды: $team" if [ -n "$league" ]; then @@ -162,30 +229,45 @@ create_systemd_service() { fi # Формируем команду для data сервиса - local data_command="/root/RFB/.venv/bin/python3 /root/RFB/get_data.py --team \"$team\"" + local data_command="python3 $TARGET_DIR/get_data.py --team \"$team\"" if [ -n "$league" ]; then data_command="$data_command --league \"$league\"" fi - # Создаем сервисный файл в правильной директории - local data_service_file="/etc/systemd/system/rfb-data.service" + log_info "Создание файла сервиса: $SERVICE_NAME" + # Формируем команду для data сервиса + local data_service_file="/etc/systemd/system/$SERVICE_NAME" log_info "Создание файла сервиса: $data_service_file" cat > "$data_service_file" << EOF [Unit] -Description=RFB Data Service +Description=KHL Data Service +Documentation=https://git.tvstart.ru/ychernenko/RFB After=network.target +Wants=network.target [Service] Type=simple User=root -WorkingDirectory=/root/RFB -Environment=PATH=/root/RFB/.venv/bin +WorkingDirectory=$TARGET_DIR +Environment=PATH=$TARGET_DIR/.venv/bin +EnvironmentFile=$TARGET_ENV ExecStart=$data_command -Restart=always -RestartSec=30 + +# Лимиты ресурсов +MemoryMax=1G +CPUQuota=80% + +# Логирование StandardOutput=journal StandardError=journal +SyslogIdentifier=RFB + +# Поведение при перезапуске +Restart=always +RestartSec=10 +StartLimitInterval=300 +StartLimitBurst=5 [Install] WantedBy=multi-user.target @@ -195,38 +277,15 @@ EOF chmod 644 "$data_service_file" log_info "Перезагрузка systemd демона..." - systemctl daemon-reload - - log_info "Включение сервиса rfb-data.service..." - systemctl enable rfb-data.service -} - -# Функция проверки файлов -check_required_files() { - local target_dir="/root/RFB" - cd $target_dir - - local missing_files=() - local required_files=("get_data.py") - - for file in "${required_files[@]}"; do - if [ ! -f "$file" ]; then - missing_files+=("$file") - fi - done - - if [ ${#missing_files[@]} -ne 0 ]; then - log_error "Отсутствуют необходимые файлы: ${missing_files[*]}" - log_error "Содержимое директории $target_dir:" - ls -la + if ! systemctl daemon-reload; then + log_error "Ошибка при перезагрузке systemd демона" exit 1 fi - log_info "Все необходимые файлы присутствуют" - - # Дополнительная проверка на исполняемость Python файла - if ! python3 -c "import ast; ast.parse(open('get_data.py').read())" 2>/dev/null; then - log_warn "Файл get_data.py содержит синтаксические ошибки Python" + log_info "Включение сервиса $SERVICE_NAME..." + if ! systemctl enable "$SERVICE_NAME"; then + log_error "Ошибка при включении сервиса" + exit 1 fi } @@ -325,30 +384,42 @@ manage_services() { case $action in "start") - log_info "Запуск сервиса rfb-data.service..." - systemctl start rfb-data.service + log_info "Запуск сервиса $SERVICE_NAME..." + if ! systemctl start "$SERVICE_NAME"; then + log_error "Ошибка при запуске сервиса" + return 1 + fi ;; "restart") - log_info "Перезапуск сервиса rfb-data.service..." - systemctl restart rfb-data.service + log_info "Перезапуск сервиса $SERVICE_NAME..." + if ! systemctl restart "$SERVICE_NAME"; then + log_error "Ошибка при перезапуске сервиса" + return 1 + fi ;; "stop") - log_info "Остановка сервиса rfb-data.service..." - systemctl stop rfb-data.service + log_info "Остановка сервиса $SERVICE_NAME..." + if ! systemctl stop "$SERVICE_NAME"; then + log_error "Ошибка при остановке сервиса" + return 1 + fi ;; esac # Даем время сервису на запуск/остановку sleep 3 + return 0 } # Функция проверки статуса сервиса check_service_status() { - log_info "Статус сервиса rfb-data.service:" - if systemctl is-active rfb-data.service; then - systemctl status rfb-data.service --no-pager -l + log_info "Статус сервиса $SERVICE_NAME:" + if systemctl is-active "$SERVICE_NAME" &>/dev/null; then + systemctl status "$SERVICE_NAME" --no-pager -l + return 0 else - log_warn "Сервис rfb-data.service не запущен" + log_warn "Сервис $SERVICE_NAME не запущен" + return 1 fi } @@ -375,9 +446,20 @@ check_system() { log_info "Оперативная память: $((total_mem / 1024)) MB" } +# Функция очистки при прерывании +cleanup() { + log_info "Очистка..." + if [ -f "/etc/systemd/system/$SERVICE_NAME" ]; then + manage_services "stop" + systemctl disable "$SERVICE_NAME" 2>/dev/null || true + rm -f "/etc/systemd/system/$SERVICE_NAME" + systemctl daemon-reload + fi +} + # Основная функция main() { - local team="" + local team="" # переменная для команды local release="main" # значение по умолчанию local league="" # переменная для лиги @@ -415,6 +497,9 @@ main() { # Проверка системы check_system + # Проверка зависимостей + check_dependencies + # Установка пакетов install_packages @@ -427,7 +512,7 @@ main() { # Настройка виртуального окружения setup_venv - # Определение команды - ТЕПЕРЬ БЕЗ временного файла + # Определение команды final_team=$(detect_team "$team") log_info "Финальная команда: '$final_team'" @@ -448,8 +533,13 @@ main() { log_info "Настройка завершена!" - # Запуск сервиса - manage_services "start" + # Запуск сервиса + if manage_services "start"; then + log_info "Сервис успешно запущен" + else + log_error "Не удалось запустить сервис" + exit 1 + fi # Проверка статуса check_service_status @@ -461,29 +551,28 @@ main() { log_info "==================================================" log_info "Установка завершена успешно!" + log_info "Релиз: $release" + log_info "Рабочая директория: $TARGET_DIR" log_info "Команда: $final_team" if [ -n "$league" ]; then log_info "Лига: $league" fi - log_info "Режим: $release" log_info "" log_info "Для просмотра логов:" - log_info " journalctl -u rfb-data.service -f" + log_info " journalctl -u $SERVICE_NAME -f" + log_info " journalctl -t KHL -f" log_info "" log_info "Управление сервисом:" - log_info " Перезапуск: systemctl restart rfb-data.service" - log_info " Остановка: systemctl stop rfb-data.service" - log_info " Статус: systemctl status rfb-data.service" - log_info " Логи: journalctl -u rfb-data.service" + log_info " Перезапуск: systemctl restart $SERVICE_NAME" + log_info " Остановка: systemctl stop $SERVICE_NAME" + log_info " Статус: systemctl status $SERVICE_NAME" + log_info " Логи: journalctl -u $SERVICE_NAME" log_info "" log_info "Проверка работы:" log_info " Проверить процессы: ps aux | grep get_data.py" - log_info " Проверить логи: tail -f /root/RFB/logs/*.log 2>/dev/null || echo 'Директория логов не найдена'" + log_info " Проверить логи: tail -f $TARGET_DIR/logs/*.log 2>/dev/null || echo 'Директория логов не найдена'" log_info "==================================================" } -# Обработка прерывания -trap 'log_error "Прервано пользователем"; exit 1' INT TERM - # Запуск основной функции main "$@" \ No newline at end of file