#!/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 <релиз>" echo " -t Домашняя команда" echo " -r Релиз (тег или ветка в git)" echo " -h Показать эту справку" echo "" echo "Пример: $0 -t cska -r main" echo "Пример: $0 -t zenit -r Barabanov_TEST" 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 systemd 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 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 fi # Установка дополнительных зависимостей которые могут понадобиться pip install watchdog pillow streamlit_autorefresh # Проверка установки streamlit if ! [ -f ".venv/bin/streamlit" ]; then log_error "Streamlit не установлен в виртуальном окружении" exit 1 fi log_info "Установленные пакеты:" pip list --format=columns } # Функция создания systemd сервиса create_systemd_service() { local team="$1" local service_file="/etc/systemd/system/rfb-stat.service" log_info "Создание systemd сервиса для команды: $team..." # Останавливаем сервис если он уже запущен if systemctl is-active --quiet rfb-stat.service; then log_info "Остановка работающего сервиса..." systemctl stop rfb-stat.service fi # Отключаем сервис если он включен if systemctl is-enabled --quiet rfb-stat.service; then log_info "Отключение сервиса..." systemctl disable rfb-stat.service fi # Создаем запускаемый скрипт для избежания проблем с кавычками local startup_script="/root/RFB/start_rfb.sh" cat > $startup_script << EOF #!/bin/bash cd /root/RFB source /root/RFB/.venv/bin/activate python3 get_data.py --team $team & streamlit run visual.py --server.port 8501 --server.address 0.0.0.0 EOF chmod +x $startup_script cat > $service_file << EOF [Unit] Description=RFB Stat v.1.0 After=network.target [Service] Type=simple User=root WorkingDirectory=/root/RFB ExecStart=$startup_script Restart=always RestartSec=3 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target EOF # Настройка прав chmod 644 $service_file log_info "Перезагрузка systemd демонов..." systemctl daemon-reload log_info "Включение сервиса..." systemctl enable rfb-stat.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 "Все необходимые файлы присутствуют" # Проверка прав на выполнение chmod +x visual.py get_data.py } # Функция определения 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"]="Kuban" ["10.10.35.23"]="uralmash" ["10.10.35.24"]="betcity" ["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 (открытие порта 8501)..." # Проверяем наличие ufw if command -v ufw &> /dev/null; then ufw allow 8501/tcp log_info "Порт 8501 открыт в ufw" fi # Для firewalld (CentOS/RHEL) if command -v firewall-cmd &> /dev/null; then firewall-cmd --permanent --add-port=8501/tcp firewall-cmd --reload log_info "Порт 8501 открыт в firewalld" fi } # Функция проверки порта check_port() { local port=8501 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_service() { local action="$1" case $action in "start") log_info "Запуск сервиса..." systemctl start rfb-stat.service ;; "restart") log_info "Перезапуск сервиса..." systemctl restart rfb-stat.service ;; "stop") log_info "Остановка сервиса..." systemctl stop rfb-stat.service ;; esac # Даем время сервису на запуск/остановку sleep 2 } # Основная функция main() { local team="" local release="main" # значение по умолчанию # Обработка аргументов командной строки while getopts "t:r:h" opt; do case $opt in t) team="$OPTARG" ;; r) release="$OPTARG" ;; h) show_help ;; *) log_error "Неверный аргумент"; exit 1 ;; esac done log_info "Начало установки RFB Stat..." log_info "Команда: $team, Релиз: $release" # Проверка прав root if [[ $EUID -ne 0 ]]; then log_error "Этот скрипт должен запускаться с правами root" exit 1 fi # Установка пакетов install_packages # Загрузка кода download_code "$release" # Настройка виртуального окружения setup_venv # Определение команды final_team=$(detect_team "$team") # Проверка файлов check_required_files # Настройка firewall setup_firewall # Проверка порта check_port # Создание systemd сервиса create_systemd_service "$final_team" log_info "Настройка завершена!" # Запуск сервиса manage_service "start" # Проверка статуса sleep 3 log_info "Статус сервиса:" systemctl status rfb-stat.service --no-pager # Получаем 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}:8501" log_info "Команда: $final_team" log_info "Режим: $release" log_info "" log_info "Для просмотра логов: journalctl -u rfb-stat.service -f" log_info "Для перезапуска: systemctl restart rfb-stat.service" log_info "Для остановки: systemctl stop rfb-stat.service" log_info "==================================================" } # Запуск основной функции main "$@"