#!/bin/bash # Настройка цветов для вывода RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color show_help() { echo "Использование: $0 -t <домашняя команда> -r <релиз> [-l <лига>]" echo " -t Домашняя команда" echo " -r Релиз (тег или ветка в git)" echo " -l Лига (опционально)" echo " -h Показать эту справку" echo "" echo "Пример: $0 -t cska -r main" echo "Пример: $0 -t zenit -r Barabanov_TEST -l vtb" echo "Пример: $0 -t avtodor -r main" echo "" exit 0 } # Функция для вывода цветных сообщений log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # Функция проверки и установки пакетов install_packages() { log_info "Обновление списка пакетов..." apt-get update log_info "Установка необходимых пакетов..." apt-get install -y python3 python3-pip python3-venv git net-tools # Проверка установки if ! command -v python3 &> /dev/null; then log_error "Python3 не установлен!" exit 1 fi if ! command -v pip3 &> /dev/null; then log_error "pip3 не установлен!" exit 1 fi log_info "Версия Python: $(python3 --version)" log_info "Версия pip: $(pip3 --version)" } # Функция загрузки кода download_code() { local repo_url="https://git.tvstart.ru/ychernenko/RFB.git" local release="$1" local target_dir="/root/RFB" log_info "Создание рабочей директории $target_dir..." mkdir -p $target_dir if [ -d "$target_dir/.git" ]; then log_info "Обновление существующего репозитория..." cd $target_dir git fetch --all git checkout $release 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 fi log_info "Код успешно загружен (релиз: $release)" log_info "Текущая ветка: $(git branch --show-current)" } # Функция настройки виртуального окружения setup_venv() { local target_dir="/root/RFB" cd $target_dir log_info "Создание виртуального окружения..." python3 -m venv .venv if [ ! -f ".venv/bin/activate" ]; then log_error "Не удалось создать виртуальное окружение" exit 1 fi log_info "Активация виртуального окружения и установка зависимостей..." source .venv/bin/activate # Обновление pip pip install --upgrade pip # Обновляем requirements.txt перед установкой if [ -f "requirements.txt" ]; then log_info "Установка зависимостей из requirements.txt..." pip install -r requirements.txt else log_warn "Файл requirements.txt не найден, устанавливаем базовые зависимости..." pip install streamlit requests pandas numpy plotly watchdog pillow streamlit_autorefresh fi log_info "Проверка установленных пакетов:" python -c " import streamlit, requests, pandas, numpy, plotly, streamlit_autorefresh print('✓ Все основные пакеты успешно импортируются') " log_info "Установленные пакеты:" pip list --format=columns | grep -E "(streamlit|requests|pandas|numpy|plotly|autorefresh)" } # Функция создания systemd сервисов create_systemd_services() { local team="$1" local league="$2" log_info "Создание отдельных systemd сервисов для команды: $team" if [ -n "$league" ]; then log_info "Лига: $league" fi # Останавливаем и отключаем старые сервисы если они есть systemctl is-active --quiet rfb-data.service; then log_info "Остановка rfb-data.service..." systemctl stop rfb-data.service done # Формируем команду для data сервиса local data_command="/root/RFB/.venv/bin/python3 /root/RFB/get_data.py --team \"$team\"" if [ -n "$league" ]; then data_command="$data_command --league \"$league\"" fi # Сервис для data local data_service_file="/etc/systemd/system/rfb-data.service" cat > rfb-data.service << EOF [Unit] Description=RFB Data Service After=network.target [Service] Type=simple User=root WorkingDirectory=/root/RFB Environment=PATH=/root/RFB/.venv/bin ExecStart=$data_command Restart=always RestartSec=30 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target EOF # Настройка прав chmod 644 rfb-data.service log_info "Перезагрузка systemd демонов..." systemctl daemon-reload log_info "Включение сервисов..." systemctl enable rfb-data.service rfb-visual.service } # Функция проверки файлов check_required_files() { local target_dir="/root/RFB" cd $target_dir local missing_files=() if [ ! -f "visual.py" ]; then missing_files+=("visual.py") fi if [ ! -f "get_data.py" ]; then missing_files+=("get_data.py") fi if [ ${#missing_files[@]} -ne 0 ]; then log_error "Отсутствуют необходимые файлы: ${missing_files[*]}" log_error "Содержимое директории $target_dir:" ls -la exit 1 fi log_info "Все необходимые файлы присутствуют" } # Функция определения IP и команды detect_team() { local team_arg="$1" # Определение 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) else log_error "Скрипт работает только на Linux" exit 1 fi log_info "Определен IP адрес: $ip_address" # База данных хостов в виде пар IP-команда declare -A hosts=( ["10.10.35.21"]="cska" ["10.10.35.22"]="Lokomotiv Kuban" ["10.10.35.23"]="uralmash" ["10.10.35.24"]="betcity parma" ["10.10.35.25"]="avtodor" ["10.10.35.26"]="zenit" ["10.10.35.27"]="samara" ["10.10.35.28"]="mba-mai" ["10.10.35.29"]="Pari Nizhny Novgorod" ["10.10.35.30"]="unics" ) # Определение команды по IP detected_team="${hosts[$ip_address]}" # Определение финальной команды (приоритет у аргумента, затем у автоопределения) if [[ -n "$team_arg" ]]; then final_team="$team_arg" log_info "Используется команда из аргумента: $final_team" elif [[ -n "$detected_team" ]]; then final_team="$detected_team" log_info "Используется автоопределенная команда: $final_team" else log_error "Не удалось определить команду. Укажите явно через -t" echo "Доступные команды:" for ip in "${!hosts[@]}"; do echo " $ip: ${hosts[$ip]}" done exit 1 fi # Возвращаем только чистую строку с названием команды echo "$final_team" } # Функция настройки firewall setup_firewall() { log_info "Настройка firewall (открытие порта 8000)..." # Проверяем наличие ufw if command -v ufw &> /dev/null; then ufw allow 8000/tcp log_info "Порт 8000 открыт в ufw" fi # Для firewalld (CentOS/RHEL) if command -v firewall-cmd &> /dev/null; then firewall-cmd --permanent --add-port=8000/tcp firewall-cmd --reload log_info "Порт 8000 открыт в firewalld" fi } # Функция проверки порта check_port() { local port=8000 if command -v netstat &> /dev/null && netstat -tuln | grep ":$port " > /dev/null; then log_warn "Порт $port уже занят. Возможно, приложение уже запущено." return 1 fi if command -v ss &> /dev/null && ss -tuln | grep ":$port " > /dev/null; then log_warn "Порт $port уже занят. Возможно, приложение уже запущено." return 1 fi return 0 } # Функция управления сервисами manage_services() { local action="$1" case $action in "start") log_info "Запуск сервисов..." systemctl start rfb-data.service ;; "restart") log_info "Перезапуск сервисов..." systemctl restart rfb-data.service ;; "stop") log_info "Остановка сервисов..." systemctl stop rfb-data.service ;; esac # Даем время сервисам на запуск/остановку sleep 3 } # Функция проверки статуса сервисов check_services_status() { log_info "Статус сервисов:" echo "=== RFB Data Service ===" systemctl status rfb-data.service --no-pager } # Основная функция main() { local team="" local release="main" # значение по умолчанию local league="" # новая переменная для лиги # Обработка аргументов командной строки while getopts "t:r:l:h" opt; do case $opt in t) team="$OPTARG" ;; r) release="$OPTARG" ;; l) league="$OPTARG" ;; h) show_help ;; *) log_error "Неверный аргумент"; exit 1 ;; esac done log_info "Начало установки RFB Stat..." log_info "Команда: $team, Релиз: $release" if [ -n "$league" ]; then log_info "Лига: $league" else log_info "Лига: не указана (будет использовано значение по умолчанию)" fi # Проверка прав root if [[ $EUID -ne 0 ]]; then log_error "Этот скрипт должен запускаться с правами root" exit 1 fi # Установка пакетов install_packages # Загрузка кода download_code "$release" # Настройка виртуального окружения setup_venv # Определение команды - ВАЖНО: используем временный файл для чистого вывода local temp_team_file=$(mktemp) final_team=$(detect_team "$team" | tail -1) rm -f "$temp_team_file" log_info "Финальная команда: $final_team" # Проверка файлов check_required_files # Настройка firewall setup_firewall # Проверка порта check_port # Создание systemd сервисов create_systemd_services "$final_team" "$league" log_info "Настройка завершена!" # Запуск сервисов manage_services "start" # Проверка статуса check_services_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) log_info "==================================================" log_info "Установка завершена успешно!" log_info "Приложение должно быть доступно по адресу: http://${ip_address}:8000" 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 rfb-visual.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 "==================================================" } # Запуск основной функции main "$@"