diff --git a/deploy.sh b/deploy.sh index 43364c3..cc9d4bd 100644 --- a/deploy.sh +++ b/deploy.sh @@ -88,6 +88,7 @@ download_code() { log_info "Код успешно загружен (релиз: $release)" log_info "Текущая ветка: $(git branch --show-current)" + log_info "Последний коммит: $(git log --oneline -1)" } # Функция настройки виртуального окружения @@ -109,41 +110,56 @@ setup_venv() { # Обновление pip pip install --upgrade pip - # Обновляем requirements.txt перед установкой - + # Проверка наличия requirements.txt if [ -f "requirements.txt" ]; then log_info "Установка зависимостей из requirements.txt..." - pip install -r requirements.txt + if pip install -r requirements.txt; then + log_info "Все зависимости успешно установлены" + else + log_error "Ошибка при установке зависимостей из requirements.txt" + log_warn "Попытка установки базовых зависимостей..." + pip install requests pandas numpy + fi else log_warn "Файл requirements.txt не найден, устанавливаем базовые зависимости..." - pip install streamlit requests pandas numpy plotly watchdog pillow streamlit_autorefresh + pip install requests pandas numpy fi - - log_info "Проверка установленных пакетов:" + # Проверка основных пакетов + log_info "Проверка установки основных пакетов..." python -c " -import streamlit, requests, pandas, numpy, plotly, streamlit_autorefresh -print('✓ Все основные пакеты успешно импортируются') +try: + import requests, pandas, numpy + print('✓ Все основные пакеты успешно импортируются') +except ImportError as e: + print(f'✗ Ошибка импорта: {e}') + exit(1) " log_info "Установленные пакеты:" - pip list --format=columns | grep -E "(streamlit|requests|pandas|numpy|plotly|autorefresh)" + pip list --format=columns } -# Функция создания systemd сервисов -create_systemd_services() { +# Функция создания systemd сервиса +create_systemd_service() { local team="$1" local league="$2" - log_info "Создание отдельных systemd сервисов для команды: $team" + log_info "Создание systemd сервиса для команды: $team" if [ -n "$league" ]; then log_info "Лига: $league" fi - # Останавливаем и отключаем старые сервисы если они есть - systemctl is-active --quiet rfb-data.service; then + + # Останавливаем и отключаем старый сервис если он есть + if systemctl is-active --quiet rfb-data.service; then log_info "Остановка rfb-data.service..." systemctl stop rfb-data.service - done + fi + + if systemctl is-enabled --quiet rfb-data.service; then + log_info "Отключение rfb-data.service..." + systemctl disable rfb-data.service + fi # Формируем команду для data сервиса local data_command="/root/RFB/.venv/bin/python3 /root/RFB/get_data.py --team \"$team\"" @@ -151,10 +167,11 @@ create_systemd_services() { data_command="$data_command --league \"$league\"" fi - # Сервис для data + # Создаем сервисный файл local data_service_file="/etc/systemd/system/rfb-data.service" - cat > rfb-data.service << EOF + log_info "Создание файла сервиса: $data_service_file" + cat > "$data_service_file" << EOF [Unit] Description=RFB Data Service After=network.target @@ -175,13 +192,13 @@ WantedBy=multi-user.target EOF # Настройка прав - chmod 644 rfb-data.service + chmod 644 "$data_service_file" - log_info "Перезагрузка systemd демонов..." + log_info "Перезагрузка systemd демона..." systemctl daemon-reload - log_info "Включение сервисов..." - systemctl enable rfb-data.service rfb-visual.service + log_info "Включение сервиса rfb-data.service..." + systemctl enable rfb-data.service } # Функция проверки файлов @@ -190,14 +207,13 @@ check_required_files() { cd $target_dir local missing_files=() + local required_files=("get_data.py") - if [ ! -f "visual.py" ]; then - missing_files+=("visual.py") - fi - - if [ ! -f "get_data.py" ]; then - missing_files+=("get_data.py") - fi + 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[*]}" @@ -207,6 +223,11 @@ check_required_files() { 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" + fi } # Функция определения IP и команды @@ -215,7 +236,9 @@ detect_team() { # Определение IP адреса if [[ "$(uname -s)" == "Linux" ]]; then - ip_address=$(ip a 2>/dev/null | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -n1) + ip_address=$(ip route get 1 2>/dev/null | awk '{print $7; exit}' || + ip a 2>/dev/null | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | + grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -n1) else log_error "Скрипт работает только на Linux" exit 1 @@ -256,7 +279,6 @@ detect_team() { exit 1 fi - # Возвращаем только чистую строку с названием команды echo "$final_team" } @@ -265,13 +287,13 @@ setup_firewall() { log_info "Настройка firewall (открытие порта 8000)..." # Проверяем наличие ufw - if command -v ufw &> /dev/null; then + if command -v ufw &> /dev/null && systemctl is-active --quiet ufw; then ufw allow 8000/tcp log_info "Порт 8000 открыт в ufw" fi # Для firewalld (CentOS/RHEL) - if command -v firewall-cmd &> /dev/null; then + if command -v firewall-cmd &> /dev/null && systemctl is-active --quiet firewalld; then firewall-cmd --permanent --add-port=8000/tcp firewall-cmd --reload log_info "Порт 8000 открыт в firewalld" @@ -281,11 +303,15 @@ setup_firewall() { # Функция проверки порта check_port() { local port=8000 - if command -v netstat &> /dev/null && netstat -tuln | grep ":$port " > /dev/null; then - log_warn "Порт $port уже занят. Возможно, приложение уже запущено." - return 1 + local occupied=false + + if command -v netstat &> /dev/null && netstat -tuln 2>/dev/null | grep ":$port " > /dev/null; then + occupied=true + elif command -v ss &> /dev/null && ss -tuln 2>/dev/null | grep ":$port " > /dev/null; then + occupied=true fi - if command -v ss &> /dev/null && ss -tuln | grep ":$port " > /dev/null; then + + if [ "$occupied" = true ]; then log_warn "Порт $port уже занят. Возможно, приложение уже запущено." return 1 fi @@ -298,35 +324,61 @@ manage_services() { case $action in "start") - log_info "Запуск сервисов..." + log_info "Запуск сервиса rfb-data.service..." systemctl start rfb-data.service ;; "restart") - log_info "Перезапуск сервисов..." + log_info "Перезапуск сервиса rfb-data.service..." systemctl restart rfb-data.service ;; "stop") - log_info "Остановка сервисов..." + log_info "Остановка сервиса rfb-data.service..." systemctl stop rfb-data.service ;; esac - # Даем время сервисам на запуск/остановку + # Даем время сервису на запуск/остановку sleep 3 } -# Функция проверки статуса сервисов -check_services_status() { - log_info "Статус сервисов:" - echo "=== RFB Data Service ===" - systemctl status rfb-data.service --no-pager +# Функция проверки статуса сервиса +check_service_status() { + log_info "Статус сервиса rfb-data.service:" + if systemctl is-active rfb-data.service; then + systemctl status rfb-data.service --no-pager -l + else + log_warn "Сервис rfb-data.service не запущен" + fi +} + +# Функция проверки системы +check_system() { + log_info "Проверка системы..." + + # Проверка дистрибутива + if [ -f /etc/os-release ]; then + source /etc/os-release + log_info "Дистрибутив: $PRETTY_NAME" + fi + + # Проверка свободного места + local available_space=$(df /root --output=avail | tail -1) + if [ "$available_space" -lt 1048576 ]; then # Меньше 1GB + log_warn "Мало свободного места: $((available_space / 1024)) MB" + else + log_info "Свободное место: $((available_space / 1024 / 1024)) GB" + fi + + # Проверка памяти + local total_mem=$(grep MemTotal /proc/meminfo | awk '{print $2}') + log_info "Оперативная память: $((total_mem / 1024)) MB" } # Основная функция main() { local team="" local release="main" # значение по умолчанию - local league="" # новая переменная для лиги + local league="" # переменная для лиги # Обработка аргументов командной строки while getopts "t:r:l:h" opt; do @@ -339,7 +391,13 @@ main() { esac done - log_info "Начало установки RFB Stat..." + # Проверка обязательных аргументов + if [ -z "$team" ] && [ -z "$release" ]; then + log_error "Необходимо указать команду (-t) и релиз (-r)" + show_help + fi + + log_info "Начало установки RFB Data Service..." log_info "Команда: $team, Релиз: $release" if [ -n "$league" ]; then log_info "Лига: $league" @@ -353,48 +411,49 @@ main() { exit 1 fi + # Проверка системы + check_system + # Установка пакетов install_packages # Загрузка кода download_code "$release" + # Проверка файлов + check_required_files + # Настройка виртуального окружения setup_venv - # Определение команды - ВАЖНО: используем временный файл для чистого вывода - local temp_team_file=$(mktemp) - final_team=$(detect_team "$team" | tail -1) - rm -f "$temp_team_file" - + # Определение команды + final_team=$(detect_team "$team") log_info "Финальная команда: $final_team" - # Проверка файлов - check_required_files - # Настройка firewall setup_firewall # Проверка порта check_port - # Создание systemd сервисов - create_systemd_services "$final_team" "$league" + # Создание systemd сервиса + create_systemd_service "$final_team" "$league" log_info "Настройка завершена!" - # Запуск сервисов + # Запуск сервиса manage_services "start" # Проверка статуса - check_services_status + check_service_status - # Получаем IP еще раз для вывода - ip_address=$(ip a 2>/dev/null | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -n1) + # Получаем IP для вывода + ip_address=$(ip route get 1 2>/dev/null | awk '{print $7; exit}' || + ip a 2>/dev/null | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | + grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -n1) log_info "==================================================" log_info "Установка завершена успешно!" - log_info "Приложение должно быть доступно по адресу: http://${ip_address}:8000" log_info "Команда: $final_team" if [ -n "$league" ]; then log_info "Лига: $league" @@ -402,15 +461,22 @@ main() { log_info "Режим: $release" log_info "" log_info "Для просмотра логов:" - log_info " Данные: journalctl -u rfb-data.service -f" - log_info " Визуал: journalctl -u rfb-visual.service -f" + log_info " journalctl -u rfb-data.service -f" log_info "" - log_info "Управление сервисами:" - log_info " Перезапуск всех: systemctl restart rfb-data.service rfb-visual.service" - log_info " Остановка всех: systemctl stop rfb-data.service rfb-visual.service" - log_info " Статус: systemctl status rfb-data.service rfb-visual.service" + 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 "" + log_info "Проверка работы:" + log_info " Проверить процессы: ps aux | grep get_data.py" + log_info " Проверить логи: tail -f /root/RFB/logs/*.log" log_info "==================================================" } +# Обработка прерывания +trap 'log_error "Прервано пользователем"; exit 1' INT TERM + # Запуск основной функции main "$@" \ No newline at end of file