diff --git a/start.sh b/start.sh index 7813f83..88897f8 100755 --- a/start.sh +++ b/start.sh @@ -108,15 +108,50 @@ detect_os() { ;; *) log_warn "Операционная система может быть не полностью поддержана" - read -p "Продолжить установку? [y/N]: " -n 1 -r - echo - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - exit 1 + if check_interactive; then + echo -n "Продолжить установку? [y/N]: " >&2 + read -r REPLY < /dev/tty + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi + else + log_info "Неинтерактивный режим: продолжаем с неподдерживаемой ОС" fi ;; esac } +# Проверка доступности TTY для интерактивного ввода +check_interactive() { + if [ -t 0 ] && [ -t 1 ]; then + return 0 # TTY доступен + else + return 1 # TTY недоступен + fi +} + +# Безопасное чтение ввода +safe_read() { + local prompt="$1" + local default="$2" + local var_name="$3" + + if check_interactive; then + # Интерактивный режим - используем /dev/tty + echo -n "$prompt" >&2 + read -r input < /dev/tty + if [ -n "$input" ]; then + eval "$var_name='$input'" + else + eval "$var_name='$default'" + fi + else + # Неинтерактивный режим - используем значения по умолчанию + log_info "Неинтерактивный режим: $prompt -> используется значение по умолчанию: $default" + eval "$var_name='$default'" + fi +} + # Интерактивная настройка interactive_setup() { echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" @@ -124,31 +159,47 @@ interactive_setup() { echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo "" + # Проверяем режим + if ! check_interactive; then + log_warn "Обнаружен неинтерактивный режим (curl | bash)" + log_info "Используются настройки по умолчанию. Для интерактивной настройки скачайте и запустите скрипт локально:" + log_info "wget https://git.projscale.dev/my-dev/uploader-bot/raw/branch/main/start.sh && chmod +x start.sh && sudo ./start.sh" + echo "" + fi + # 1. Тип сети echo -e "${PURPLE}❓ Выберите режим работы сети:${NC}" echo " 1) Создать новую сеть (Bootstrap нода)" echo " 2) Подключиться к существующей сети" echo "" - while true; do - read -p "Введите номер [1-2]: " network_choice - case $network_choice in - 1) - NETWORK_MODE="bootstrap" - NODE_TYPE="bootstrap" - log_info "Режим: Создание новой сети (Bootstrap нода)" - break - ;; - 2) - NETWORK_MODE="existing" - log_info "Режим: Подключение к существующей сети" - break - ;; - *) - log_error "Неверный выбор. Введите 1 или 2." - ;; - esac - done + if check_interactive; then + while true; do + echo -n "Введите номер [1-2]: " >&2 + read -r network_choice < /dev/tty + case $network_choice in + 1) + NETWORK_MODE="bootstrap" + NODE_TYPE="bootstrap" + log_info "Режим: Создание новой сети (Bootstrap нода)" + break + ;; + 2) + NETWORK_MODE="existing" + log_info "Режим: Подключение к существующей сети" + break + ;; + *) + log_error "Неверный выбор. Введите 1 или 2." + ;; + esac + done + else + # Неинтерактивный режим - создаем новую сеть по умолчанию + NETWORK_MODE="bootstrap" + NODE_TYPE="bootstrap" + log_info "Неинтерактивный режим: используется режим создания новой сети (Bootstrap нода)" + fi # 2. Тип ноды (если подключаемся к существующей) if [ "$NETWORK_MODE" = "existing" ]; then @@ -158,26 +209,34 @@ interactive_setup() { echo " 2) Приватная нода (только исходящие соединения)" echo "" - while true; do - read -p "Введите номер [1-2]: " node_choice - case $node_choice in - 1) - NODE_TYPE="public" - ALLOW_INCOMING="true" - log_info "Тип ноды: Публичная (открытые порты)" - break - ;; - 2) - NODE_TYPE="private" - ALLOW_INCOMING="false" - log_info "Тип ноды: Приватная (закрытые порты)" - break - ;; - *) - log_error "Неверный выбор. Введите 1 или 2." - ;; - esac - done + if check_interactive; then + while true; do + echo -n "Введите номер [1-2]: " >&2 + read -r node_choice < /dev/tty + case $node_choice in + 1) + NODE_TYPE="public" + ALLOW_INCOMING="true" + log_info "Тип ноды: Публичная (открытые порты)" + break + ;; + 2) + NODE_TYPE="private" + ALLOW_INCOMING="false" + log_info "Тип ноды: Приватная (закрытые порты)" + break + ;; + *) + log_error "Неверный выбор. Введите 1 или 2." + ;; + esac + done + else + # Неинтерактивный режим - публичная нода по умолчанию + NODE_TYPE="public" + ALLOW_INCOMING="true" + log_info "Неинтерактивный режим: используется публичная нода по умолчанию" + fi else ALLOW_INCOMING="true" # Bootstrap нода всегда принимает подключения fi @@ -189,7 +248,14 @@ interactive_setup() { log_info "Bootstrap нода будет создавать новую сеть" BOOTSTRAP_CONFIG="new" else - read -p "Путь до bootstrap.json [Enter для дефолтного]: " custom_bootstrap + if check_interactive; then + echo -n "Путь до bootstrap.json [Enter для дефолтного]: " >&2 + read -r custom_bootstrap < /dev/tty + else + custom_bootstrap="" + log_info "Неинтерактивный режим: используется дефолтный bootstrap.json" + fi + if [ -n "$custom_bootstrap" ] && [ -f "$custom_bootstrap" ]; then BOOTSTRAP_CONFIG="$custom_bootstrap" log_success "Использован кастомный bootstrap.json: $custom_bootstrap" @@ -202,7 +268,14 @@ interactive_setup() { # 4. Docker socket echo "" echo -e "${PURPLE}❓ Настройка Docker для конвертации:${NC}" - read -p "Путь до docker.sock [$DOCKER_SOCK_PATH]: " custom_docker_sock + if check_interactive; then + echo -n "Путь до docker.sock [$DOCKER_SOCK_PATH]: " >&2 + read -r custom_docker_sock < /dev/tty + else + custom_docker_sock="" + log_info "Неинтерактивный режим: используется дефолтный путь $DOCKER_SOCK_PATH" + fi + if [ -n "$custom_docker_sock" ]; then DOCKER_SOCK_PATH="$custom_docker_sock" fi @@ -217,7 +290,14 @@ interactive_setup() { # 5. Настройка веб-клиента echo "" echo -e "${PURPLE}❓ Настройка веб-интерфейса:${NC}" - read -p "Развернуть веб-клиент для управления нодой? [Y/n]: " web_choice + if check_interactive; then + echo -n "Развернуть веб-клиент для управления нодой? [Y/n]: " >&2 + read -r web_choice < /dev/tty + else + web_choice="Y" + log_info "Неинтерактивный режим: веб-клиент включен по умолчанию" + fi + if [[ ! $web_choice =~ ^[Nn]$ ]]; then ENABLE_WEB_CLIENT="true" log_success "Веб-клиент будет развернут" @@ -230,11 +310,20 @@ interactive_setup() { if [ "$ALLOW_INCOMING" = "true" ] && [ "$ENABLE_WEB_CLIENT" = "true" ]; then echo "" echo -e "${PURPLE}❓ Настройка SSL сертификата:${NC}" - read -p "Настроить SSL сертификат? [y/N]: " ssl_choice + if check_interactive; then + echo -n "Настроить SSL сертификат? [y/N]: " >&2 + read -r ssl_choice < /dev/tty + else + ssl_choice="N" + log_info "Неинтерактивный режим: SSL отключен (требует ручной настройки)" + fi + if [[ $ssl_choice =~ ^[Yy]$ ]]; then - read -p "Доменное имя: " DOMAIN + echo -n "Доменное имя: " >&2 + read -r DOMAIN < /dev/tty if [ -n "$DOMAIN" ]; then - read -p "Email для уведомлений SSL: " EMAIL + echo -n "Email для уведомлений SSL: " >&2 + read -r EMAIL < /dev/tty if [ -n "$EMAIL" ]; then ENABLE_SSL="true" log_success "SSL будет настроен для домена: $DOMAIN" @@ -252,11 +341,22 @@ interactive_setup() { # 7. Telegram API ключи echo "" echo -e "${PURPLE}❓ Настройка Telegram ботов (необязательно):${NC}" - read -p "TELEGRAM_API_KEY (основной бот) [Enter для пропуска]: " TELEGRAM_API_KEY + if check_interactive; then + echo -n "TELEGRAM_API_KEY (основной бот) [Enter для пропуска]: " >&2 + read -r TELEGRAM_API_KEY < /dev/tty + else + TELEGRAM_API_KEY="" + log_info "Неинтерактивный режим: Telegram боты отключены" + fi if [ -n "$TELEGRAM_API_KEY" ]; then log_success "TELEGRAM_API_KEY настроен" - read -p "CLIENT_TELEGRAM_API_KEY (клиентский бот) [Enter для пропуска]: " CLIENT_TELEGRAM_API_KEY + if check_interactive; then + echo -n "CLIENT_TELEGRAM_API_KEY (клиентский бот) [Enter для пропуска]: " >&2 + read -r CLIENT_TELEGRAM_API_KEY < /dev/tty + else + CLIENT_TELEGRAM_API_KEY="" + fi if [ -n "$CLIENT_TELEGRAM_API_KEY" ]; then log_success "CLIENT_TELEGRAM_API_KEY настроен" @@ -284,11 +384,16 @@ interactive_setup() { echo -e "${WHITE}Telegram клиентский:${NC} $([ -n "$CLIENT_TELEGRAM_API_KEY" ] && echo "настроен" || echo "отключен")" echo "" - read -p "Продолжить установку с этими настройками? [Y/n]: " -n 1 -r - echo - if [[ $REPLY =~ ^[Nn]$ ]]; then - log_info "Установка отменена пользователем" - exit 0 + if check_interactive; then + echo -n "Продолжить установку с этими настройками? [Y/n]: " >&2 + read -r REPLY < /dev/tty + if [[ $REPLY =~ ^[Nn]$ ]]; then + log_info "Установка отменена пользователем" + exit 0 + fi + else + log_info "Неинтерактивный режим: продолжаем установку с настройками по умолчанию" + sleep 3 fi } @@ -1004,9 +1109,15 @@ install_ssl_certificates() { if ! host "$DOMAIN" > /dev/null 2>&1; then log_warn "DNS запись для $DOMAIN не найдена" log_info "Убедитесь что домен указывает на этот сервер" - read -p "Продолжить установку SSL? [y/N]: " ssl_continue - if [[ ! $ssl_continue =~ ^[Yy]$ ]]; then - log_info "Установка SSL пропущена" + if check_interactive; then + echo -n "Продолжить установку SSL? [y/N]: " >&2 + read -r ssl_continue < /dev/tty + if [[ ! $ssl_continue =~ ^[Yy]$ ]]; then + log_info "Установка SSL пропущена" + return 0 + fi + else + log_info "Неинтерактивный режим: пропускаем SSL (требует ручной настройки)" return 0 fi fi