Этот коммит содержится в:
stevefoxru
2025-04-22 18:28:26 +03:00
коммит произвёл GitHub
родитель 74a3028b67
Коммит 4ded31eb69
+142 -88
Просмотреть файл
@@ -1,3 +1,4 @@
cat << 'EOF' > /root/install.sh
#!/bin/bash
SERVICE_NAME="awg_bot"
@@ -16,10 +17,36 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SCRIPT_NAME="$(basename "$0")"
SCRIPT_PATH="$SCRIPT_DIR/$SCRIPT_NAME"
# Функция для вывода ошибок и завершения
error_exit() {
echo -e "${RED}Ошибка: $1${NC}" >&2
exit 1
}
# Функция запуска команд с индикатором
run_with_spinner() {
local description="$1"; shift
local cmd="$@"
if [ "$ENABLE_LOGS" = true ]; then
echo -e "${BLUE}${description}...${NC}"
eval "$cmd"
local stat=$?
if [ $stat -eq 0 ]; then echo -e "${GREEN}${description}... Done!${NC}\n"; else echo -e "${RED}${description}... Failed!${NC}\n"; error_exit "$cmd"; fi
else
local out=$(mktemp) err=$(mktemp)
eval "$cmd" >"$out" 2>"$err" & pid=$!
local spinner='|/-\\' i=0
while kill -0 "$pid" 2>/dev/null; do printf "\r${BLUE}${description}...${NC} ${spinner:i++%${#spinner}:1}"; sleep 0.1; done
wait "$pid"; stat=$?
if [ $stat -eq 0 ]; then printf "\r${BLUE}${description}...${NC} ${GREEN}Done!${NC}\n\n"; else printf "\r${BLUE}${description}...${NC} ${RED}Failed!${NC}\n\n"; echo -e "${RED}Ошибка: $cmd${NC}"; cat "$err"; rm -f "$out" "$err"; error_exit "$cmd"; fi
rm -f "$out" "$err"
fi
}
# Функция проверки обновлений на GitHub
check_github_updates() {
local current_sha local_sha latest_sha auto_mode="$1"
cd amnezia-bot || { echo -e "${RED}Каталог amnezia-bot не найден${NC}"; return 1; }
cd /root/amnezia-bot || { echo -e "${RED}Каталог amnezia-bot не найден${NC}"; return 1; }
# Получение текущего SHA коммита
local_sha=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
@@ -46,13 +73,12 @@ check_github_updates() {
run_with_spinner "Сброс локальных изменений" "git reset --hard && git clean -fd"
fi
run_with_spinner "Обновление репозитория" "git pull"
if [ $? -ne 0 ]; then
echo -e "${RED}Не удалось обновить репозиторий${NC}"
cd ..; return 1
fi
echo "$latest_sha" > "$LOCAL_VERSION_FILE"
check_script_update
run_with_spinner "Перезапуск службы" "sudo systemctl restart $SERVICE_NAME -q"
setup_python_env
check_config
create_service
run_with_spinner "Перезапуск службы" "systemctl restart $SERVICE_NAME"
else
echo -ne "${BLUE}1) Установить 2) Отменить: ${NC}"; read choice
if [[ "$choice" == "1" ]]; then
@@ -61,13 +87,12 @@ check_github_updates() {
run_with_spinner "Сброс локальных изменений" "git reset --hard && git clean -fd"
fi
run_with_spinner "Обновление репозитория" "git pull"
if [ $? -ne 0 ]; then
echo -e "${RED}Не удалось обновить репозиторий${NC}"
cd ..; return 1
fi
echo "$latest_sha" > "$LOCAL_VERSION_FILE"
check_script_update
run_with_spinner "Перезапуск службы" "sudo systemctl restart $SERVICE_NAME -q"
setup_python_env
check_config
create_service
run_with_spinner "Перезапуск службы" "systemctl restart $SERVICE_NAME"
else
echo -e "${YELLOW}Обновление отменено${NC}"
fi
@@ -77,7 +102,7 @@ check_github_updates() {
# Проверка и применение обновлений
check_updates() {
if [[ ! -d "amnezia-bot/.git" ]]; then
if [[ ! -d "/root/amnezia-bot/.git" ]]; then
echo -e "${RED}Репозиторий не найден. Пожалуйста, установите бот сначала.${NC}"
return 1
fi
@@ -99,31 +124,11 @@ while [[ "$#" -gt 0 ]]; do
shift
done
# Функция запуска команд с индикатором
run_with_spinner() {
local description="$1"; shift
local cmd="$@"
if [ "$ENABLE_LOGS" = true ]; then
echo -e "${BLUE}${description}...${NC}"
eval "$cmd"
local stat=$?
if [ $stat -eq 0 ]; then echo -e "${GREEN}${description}... Done!${NC}\n"; else echo -e "${RED}${description}... Failed!${NC}\n"; exit 1; fi
else
local out=$(mktemp) err=$(mktemp)
eval "$cmd" >"$out" 2>"$err" & pid=$!
local spinner='|/-\\' i=0
while kill -0 "$pid" 2>/dev/null; do printf "\r${BLUE}${description}...${NC} ${spinner:i++%${#spinner}:1}"; sleep 0.1; done
wait "$pid"; stat=$?
if [ $stat -eq 0 ]; then printf "\r${BLUE}${description}...${NC} ${GREEN}Done!${NC}\n\n"; else printf "\r${BLUE}${description}...${NC} ${RED}Failed!${NC}\n\n"; echo -e "${RED}Ошибка: $cmd${NC}"; cat "$err"; rm -f "$out" "$err"; exit 1; fi
rm -f "$out" "$err"
fi
}
# Проверка обновления самого скрипта
check_script_update() {
local temp_script=$(mktemp)
if [[ -f "amnezia-bot/install.sh" ]]; then
cp "amnezia-bot/install.sh" "$temp_script"
if [[ -f "/root/amnezia-bot/install.sh" ]]; then
cp "/root/amnezia-bot/install.sh" "$temp_script"
if ! cmp -s "$SCRIPT_PATH" "$temp_script"; then
echo -e "${YELLOW}Обнаружено обновление скрипта install.sh${NC}"
run_with_spinner "Обновление скрипта" "mv $temp_script $SCRIPT_PATH && chmod +x $SCRIPT_PATH"
@@ -133,8 +138,9 @@ check_script_update() {
rm -f "$temp_script"
fi
else
rm -f "$temp_script"
echo -e "${YELLOW}Скрипт install.sh не найден в репозитории${NC}"
echo -e "${YELLOW}Скрипт install.sh не найден в репозитории, копируем локальную версию${NC}"
cp "$SCRIPT_PATH" "/root/amnezia-bot/install.sh"
chmod +x "/root/amnezia-bot/install.sh"
fi
}
@@ -144,10 +150,9 @@ get_ubuntu_version() {
UBUNTU_VERSION=$(lsb_release -rs)
UBUNTU_CODENAME=$(lsb_release -cs)
DISTRIB_ID=$(lsb_release -is)
[[ "$DISTRIB_ID" != "Ubuntu" ]] && { echo -e "${RED}Скрипт поддерживает только Ubuntu. Обнаружена система: $DISTRIB_ID${NC}"; exit 1; }
[[ "$DISTRIB_ID" != "Ubuntu" ]] && error_exit "Скрипт поддерживает только Ubuntu. Обнаружена система: $DISTRIB_ID"
else
echo -e "${RED}lsb_release не установлен. Установите пакет lsb-release.${NC}"
exit 1
error_exit "lsb_release не установлен. Установите пакет lsb-release."
fi
}
@@ -156,75 +161,121 @@ update_and_clean_system() {
while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do
echo -e "${YELLOW}APT занят. Ждём...${NC}"; sleep 2
done
run_with_spinner "Обновление системы" "sudo apt-get update -qq && sudo apt-get upgrade -y -qq"
run_with_spinner "Очистка системы" "sudo apt-get autoclean -qq && sudo apt-get autoremove --purge -y -qq"
run_with_spinner "Обновление системы" "apt-get update -qq && apt-get upgrade -y -qq"
run_with_spinner "Очистка системы" "apt-get autoclean -qq && apt-get autoremove --purge -y -qq"
}
# Обязательная установка Python 3.11
check_python() {
if command -v python3.11 &>/dev/null; then
echo -e "\n${GREEN}Python 3.11 уже установлен${NC}"; return 0
echo -e "${GREEN}Python 3.11 уже установлен${NC}"
return 0
fi
echo -e "\n${YELLOW}Устанавливаю Python 3.11...${NC}"
echo -e "${YELLOW}Устанавливаю Python 3.11...${NC}"
if [[ "$UBUNTU_VERSION" == "24.04" ]]; then
local max=30 cnt=1
while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do
echo -e "${YELLOW}Ожидание dpkg lock ($cnt/$max)${NC}"; ((cnt++))
[ $cnt -gt $max ] && { echo -e "${RED}Таймаут ожидания dpkg lock${NC}"; exit 1; }
[ $cnt -gt $max ] && error_exit "Таймаут ожидания dpkg lock"
sleep 10
done
fi
run_with_spinner "Установка Python 3.11" "sudo apt-get install -y software-properties-common && sudo add-apt-repository -y ppa:deadsnakes/ppa && sudo apt-get update -qq && sudo apt-get install -y python3.11 python3.11-venv python3.11-dev -qq"
command -v python3.11 &>/dev/null || { echo -e "\n${RED}Не удалось установить Python 3.11${NC}"; exit 1; }
echo -e "\n${GREEN}Python 3.11 успешно установлен${NC}"
run_with_spinner "Установка Python 3.11" "apt-get install -y software-properties-common && add-apt-repository -y ppa:deadsnakes/ppa && apt-get update -qq && apt-get install -y python3.11 python3.11-venv python3.11-dev -qq"
command -v python3.11 &>/dev/null || error_exit "Не удалось установить Python 3.11"
echo -e "${GREEN}Python 3.11 успешно установлен${NC}"
}
# Установка зависимостей VPN-бота
install_dependencies() {
run_with_spinner "Установка зависимостей" "sudo apt-get install -y jq net-tools iptables resolvconf git curl -qq"
run_with_spinner "Установка зависимостей" "apt-get install -y jq net-tools iptables resolvconf git curl sqlite3 -qq"
}
# Установка и конфиг needrestart
# Установка и конфигурация needrestart
install_and_configure_needrestart() {
run_with_spinner "Установка needrestart" "sudo apt-get install -y needrestart -qq"
sudo sed -i 's/^#\?\(nrconf{restart} = \"\).*$/\1a\";/' /etc/needrestart/needrestart.conf
grep -q 'nrconf{restart} = "a";' /etc/needrestart/needrestart.conf || echo 'nrconf{restart} = "a";' | sudo tee -a /etc/needrestart/needrestart.conf >/dev/null
run_with_spinner "Установка needrestart" "apt-get install -y needrestart -qq"
sed -i 's/^#\?\(nrconf{restart} = \"\).*$/\1a\";/' /etc/needrestart/needrestart.conf
grep -q 'nrconf{restart} = "a";' /etc/needrestart/needrestart.conf || echo 'nrconf{restart} = "a";' >> /etc/needrestart/needrestart.conf
}
# Клонирование репозитория
clone_repository() {
if [[ -d ".git" ]]; then
cd /root
if [[ -d "amnezia-bot/.git" ]]; then
echo -e "${YELLOW}Репозиторий уже присутствует, пропускаем клонирование...${NC}"
return
fi
run_with_spinner "Клонирование репозитория" "git clone $REPO_URL -q"
cd amnezia-bot || { echo -e "${RED}Не удалось перейти в каталог amnezia-bot${NC}"; exit 1; }
cd amnezia-bot || error_exit "Не удалось перейти в каталог amnezia-bot"
}
# Настройка виртуального окружения
setup_venv() {
if [[ -d "myenv" ]]; then return; fi
setup_python_env() {
echo -e "${BLUE}Настройка Python окружения...${NC}"
if [[ -d "myenv" ]]; then
rm -rf myenv
fi
run_with_spinner "Создание virtualenv" "python3.11 -m venv myenv"
source myenv/bin/activate
run_with_spinner "Установка Python-зависимостей" "pip install --upgrade pip && pip install -r requirements.txt"
run_with_spinner "Установка Python-зависимостей" "pip install --upgrade pip"
if [[ -f "requirements.txt" ]]; then
run_with_spinner "Установка зависимостей из requirements.txt" "pip install -r requirements.txt"
else
echo -e "${YELLOW}Файл requirements.txt не найден. Устанавливаем минимальные зависимости...${NC}"
run_with_spinner "Установка минимальных зависимостей" "pip install aiogram==2.25.1 aiohttp==3.8.6 apscheduler==3.10.4 humanize==4.9.0 pytz==2023.3.post1"
fi
deactivate
echo -e "${GREEN}Настройка Python окружения... Done!${NC}"
}
# Проверка и создание конфигурации
check_config() {
cd awg || error_exit "Каталог awg не найден"
echo -e "${BLUE}Проверка конфигурации...${NC}"
if [[ ! -f "files/setting.ini" ]]; then
echo -e "${YELLOW}Файл setting.ini не найден. Запрашиваем конфигурацию...${NC}"
read -p "Введите токен Telegram бота: " bot_token
read -p "Введите Telegram ID администраторов через запятую (например, 12345,67890): " admin_ids
read -p "Введите endpoint VPN (например, vpn.example.com:51820): " endpoint
mkdir -p files || error_exit "Не удалось создать директорию files"
cat <<EOF > files/setting.ini
[Settings]
bot_token = \$bot_token
admin_ids = \$admin_ids
wg_config_file = /root/amnezia-bot/awg/files/wg0.conf
docker_container = amnezia-awg
endpoint = \$endpoint
EOF
echo -e "${GREEN}Конфигурация сохранена в files/setting.ini${NC}"
fi
if docker ps -q -f name=amnezia-awg >/dev/null; then
echo -e "${GREEN}Найден Docker-контейнер: amnezia-awg${NC}"
else
echo -e "${YELLOW}ВНИМАНИЕ: Docker-контейнер amnezia-awg не найден. Убедитесь, что он настроен.${NC}"
fi
if [[ ! -f "files/wg0.conf" ]]; then
echo -e "${YELLOW}ВНИМАНИЕ: Файл wg0.conf не найден. Убедитесь, что WireGuard настроен.${NC}"
fi
cd ..
echo -e "${GREEN}Проверка конфигурации... Done!${NC}"
}
# Права на скрипты
set_permissions() {
find . -type f -name "*.sh" -exec chmod +x {} \; || exit 1
find . -type f -name "*.sh" -exec chmod +x {} \; || error_exit "Не удалось установить права на скрипты"
}
# Инициализация бота для генерации config
initialize_bot() {
cd awg || exit 1
../myenv/bin/python3.11 bot_manager.py < /dev/tty &
local PID=$!
while [ ! -f "files/setting.ini" ]; do
sleep 2
kill -0 "$PID" 2>/dev/null || { echo -e "${RED}Ошибка инициализации бота${NC}"; exit 1; }
done
kill "$PID" && wait "$PID" 2>/dev/null
cd awg || error_exit "Каталог awg не найден"
if [[ ! -f "files/setting.ini" ]]; then
../myenv/bin/python3.11 bot_manager.py < /dev/tty &
local PID=\$!
while [[ ! -f "files/setting.ini" ]]; do
sleep 2
kill -0 "\$PID" 2>/dev/null || error_exit "Ошибка инициализации бота"
done
kill "\$PID" && wait "\$PID" 2>/dev/null
fi
cd ..
}
@@ -240,42 +291,43 @@ User=root
WorkingDirectory=/root/amnezia-bot/awg
ExecStart=/root/amnezia-bot/myenv/bin/python3.11 bot_manager.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
run_with_spinner "Установка службы" "sudo mv /tmp/service_file /etc/systemd/system/$SERVICE_NAME.service"
run_with_spinner "Обновление systemd" "sudo systemctl daemon-reload -q"
run_with_spinner "Запуск службы" "sudo systemctl start $SERVICE_NAME -q"
run_with_spinner "Включение автозапуска" "sudo systemctl enable $SERVICE_NAME -q"
run_with_spinner "Установка службы" "mv /tmp/service_file /etc/systemd/system/\$SERVICE_NAME.service"
run_with_spinner "Обновление systemd" "systemctl daemon-reload"
run_with_spinner "Запуск службы" "systemctl start \$SERVICE_NAME"
run_with_spinner "Включение автозапуска" "systemctl enable \$SERVICE_NAME"
}
# Удаление AmneziaWG
remove_amneziawg() {
echo -ne "${YELLOW}Удалить AmneziaWG? (y/n): ${NC}"; read ans
[[ "$ans" =~ ^[Yy]$ ]] || return
systemctl is-active --quiet "$SERVICE_NAME" && run_with_spinner "Остановка" "sudo systemctl stop $SERVICE_NAME -q"
[[ "\$ans" =~ ^[Yy]\$ ]] || return
systemctl is-active --quiet "\$SERVICE_NAME" && run_with_spinner "Остановка" "systemctl stop \$SERVICE_NAME"
run_with_spinner "Удаление контейнеров" "docker ps -aq -f name=amnezia-wg | xargs -r docker rm -f"
run_with_spinner "Удаление образов" "docker images -q amneziawg/amnezia-wg | uniq | xargs -r docker rmi -f"
run_with_spinner "Удаление конфигов" "rm -rf $(pwd)/awg/files"
run_with_spinner "Удаление конфигов" "rm -rf /root/amnezia-bot/awg/files"
}
# Меню управления службой
service_control_menu() {
while true; do
echo -e "\n${BLUE}Управление службой${NC}"
sudo systemctl status "$SERVICE_NAME" | grep -E "Active:|Loaded:"
systemctl status "\$SERVICE_NAME" | grep -E "Active:|Loaded:"
echo -e "1) Остановить 2) Перезапустить 3) Переустановить 4) Удалить службу 5) Удалить AmneziaWG 6) Проверить обновления 7) Назад"
echo -ne "${BLUE}Выберите: ${NC}"; read act
case $act in
1) run_with_spinner "Остановка" "sudo systemctl stop $SERVICE_NAME -q" ;;
2) run_with_spinner "Перезапуск" "sudo systemctl restart $SERVICE_NAME -q" ;;
case \$act in
1) run_with_spinner "Остановка" "systemctl stop \$SERVICE_NAME" ;;
2) run_with_spinner "Перезапуск" "systemctl restart \$SERVICE_NAME" ;;
3) reinstall_bot ;;
4) run_with_spinner "Удаление службы" "sudo systemctl disable $SERVICE_NAME -q && sudo rm /etc/systemd/system/$SERVICE_NAME.service && sudo systemctl daemon-reload -q" ;;
4) run_with_spinner "Удаление службы" "systemctl disable \$SERVICE_NAME && rm /etc/systemd/system/\$SERVICE_NAME.service && systemctl daemon-reload" ;;
5) remove_amneziawg ;;
6) check_updates ;;
7) break ;;
*) echo "Неверно" ;;
*) echo -e "${RED}Неверный выбор${NC}" ;;
esac
done
}
@@ -283,10 +335,10 @@ service_control_menu() {
# Переустановка бота
reinstall_bot() {
echo -ne "${YELLOW}Переустановить бота? (y/n): ${NC}"; read ans
[[ "$ans" =~ ^[Yy]$ ]] || return
systemctl is-active --quiet "$SERVICE_NAME" && run_with_spinner "Остановка" "sudo systemctl stop $SERVICE_NAME -q"
systemctl list-units --type=service --all | grep -q "$SERVICE_NAME.service" && run_with_spinner "Удаление службы" "sudo systemctl disable $SERVICE_NAME -q && sudo rm /etc/systemd/system/$SERVICE_NAME.service && sudo systemctl daemon-reload -q"
run_with_spinner "Удаление файлов" "rm -rf amnezia-bot"
[[ "\$ans" =~ ^[Yy]\$ ]] || return
systemctl is-active --quiet "\$SERVICE_NAME" && run_with_spinner "Остановка" "systemctl stop \$SERVICE_NAME"
systemctl list-units --type=service --all | grep -q "\$SERVICE_NAME.service" && run_with_spinner "Удаление службы" "systemctl disable \$SERVICE_NAME && rm /etc/systemd/system/\$SERVICE_NAME.service && systemctl daemon-reload"
run_with_spinner "Удаление файлов" "rm -rf /root/amnezia-bot"
install_bot
}
@@ -295,12 +347,12 @@ installed_menu() {
while true; do
echo -e "\n${GREEN}1) Проверить обновления 2) Управление службой 3) Переустановить 4) Выход${NC}"
echo -ne "${BLUE}Выберите: ${NC}"; read opt
case $opt in
case \$opt in
1) check_updates ;;
2) service_control_menu ;;
3) reinstall_bot ;;
4) exit 0 ;;
*) echo "Неверно" ;;
*) echo -e "${RED}Неверный выбор${NC}" ;;
esac
done
}
@@ -313,22 +365,24 @@ install_bot() {
install_dependencies
install_and_configure_needrestart
clone_repository
setup_venv
setup_python_env
set_permissions
initialize_bot
create_service
cp "\$SCRIPT_PATH" "/root/amnezia-bot/install.sh" && chmod +x "/root/amnezia-bot/install.sh"
echo -e "${GREEN}Установка завершена!${NC}"
}
# Точка входа
main() {
get_ubuntu_version
if systemctl list-units --type=service --all | grep -q "$SERVICE_NAME.service"; then
if systemctl list-units --type=service --all | grep -q "\$SERVICE_NAME.service"; then
installed_menu
else
install_bot
rm -- "$SCRIPT_PATH"
fi
}
main
EOF
chmod +x /root/install.sh