diff --git a/scripts/network-manager.sh b/scripts/network-manager.sh index 5981901..3352b2c 100755 --- a/scripts/network-manager.sh +++ b/scripts/network-manager.sh @@ -57,13 +57,14 @@ detect_network_mode() { } list_available_networks() { - info "Listing available Docker networks..." + info "Listing available Docker networks..." >&2 local networks=$(docker network ls --format '{{.Name}}' | grep -v '^bridge$\|^host$\|^none$' || true) if [ -z "$networks" ]; then - warning "No custom Docker networks found" - echo "0. Create new isolated network" + warning "No custom Docker networks found" >&2 + echo "0. Create new isolated network" >&2 + echo "0" return 0 fi @@ -72,31 +73,31 @@ list_available_networks() { count=$((count + 1)) local subnet=$(docker network inspect "$network" --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}' 2>/dev/null || echo "N/A") local driver=$(docker network inspect "$network" --format '{{.Driver}}' 2>/dev/null || echo "N/A") - echo "$count. $network ($subnet, $driver)" + echo "$count. $network ($subnet, $driver)" >&2 done <<< "$networks" - echo "$((count + 1)). Create new isolated network" + echo "$((count + 1)). Create new isolated network" >&2 - success "Found $count existing network(s)" + success "Found $count existing network(s)" >&2 echo "$count" } prompt_network_selection() { - info "Select network mode:" - echo "" + info "Select network mode:" >&2 + echo "" >&2 local count=$(list_available_networks) local networks=$(docker network ls --format '{{.Name}}' | grep -v '^bridge$\|^host$\|^none$' || true) - echo "" - echo "Options:" + echo "" >&2 + echo "Options:" >&2 if [ "$count" -gt 0 ]; then - echo " 1-${count}. Use existing network" - echo " $((count + 1)). Create new isolated network" + echo " 1-${count}. Use existing network" >&2 + echo " $((count + 1)). Create new isolated network" >&2 else - echo " 1. Create new isolated network" + echo " 1. Create new isolated network" >&2 fi - echo "" + echo "" >&2 local max_choice=$((count + 1)) read -p "Your choice [1-${max_choice}]: " choice @@ -106,6 +107,16 @@ prompt_network_selection() { return 1 fi + if ! [[ "$choice" =~ ^[0-9]+$ ]]; then + error "Invalid choice: must be a number" + return 1 + fi + + if [ "$choice" -lt 1 ] || [ "$choice" -gt "$max_choice" ]; then + error "Invalid choice: must be between 1 and $max_choice" + return 1 + fi + if [ "$choice" -le "$count" ] && [ "$count" -gt 0 ]; then local selected=$(echo "$networks" | sed -n "${choice}p") echo "shared|$selected" @@ -117,32 +128,32 @@ prompt_network_selection() { validate_subnet() { local subnet="$1" - info "Validating subnet: $subnet" + info "Validating subnet: $subnet" >&2 local used_subnets=$(docker network inspect $(docker network ls -q) --format '{{range .IPAM.Config}}{{.Subnet}}{{"\n"}}{{end}}' 2>/dev/null | grep -v '^$' || true) if echo "$used_subnets" | grep -q "^${subnet}$"; then - error "Subnet $subnet is already in use" + error "Subnet $subnet is already in use" >&2 return 1 fi - success "Subnet $subnet is available" + success "Subnet $subnet is available" >&2 return 0 } find_free_subnet() { - info "Searching for free subnet in range 172.24-31.0.0/16..." + info "Searching for free subnet in range 172.24-31.0.0/16..." >&2 for i in {24..31}; do local subnet="172.${i}.0.0/16" - if validate_subnet "$subnet" 2>/dev/null; then - success "Found free subnet: $subnet" + if validate_subnet "$subnet" &>/dev/null; then + success "Found free subnet: $subnet" >&2 echo "$subnet" return 0 fi done - error "No free subnets available in range 172.24-31.0.0/16" + error "No free subnets available in range 172.24-31.0.0/16" >&2 return 1 } @@ -151,32 +162,32 @@ create_network() { local subnet="${2:-}" if [ -z "$subnet" ]; then - info "Subnet not specified, auto-detecting..." + info "Subnet not specified, auto-detecting..." >&2 subnet=$(find_free_subnet) if [ $? -ne 0 ]; then - error "Failed to find free subnet" + error "Failed to find free subnet" >&2 return 1 fi fi local gateway=$(echo "$subnet" | sed 's|0/16|1|') - info "Creating Docker network: $network_name" - info " Subnet: $subnet" - info " Gateway: $gateway" + info "Creating Docker network: $network_name" >&2 + info " Subnet: $subnet" >&2 + info " Gateway: $gateway" >&2 if docker network create \ --driver bridge \ --subnet "$subnet" \ --gateway "$gateway" \ "$network_name" &> /dev/null; then - success "Network created successfully" + success "Network created successfully" >&2 echo "Network: $network_name" echo "Subnet: $subnet" echo "Gateway: $gateway" return 0 else - error "Failed to create network $network_name" + error "Failed to create network $network_name" >&2 return 1 fi } @@ -265,4 +276,7 @@ main() { esac } -main "$@" +# Execute main only when script is run directly (not when sourced) +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main "$@" +fi diff --git a/scripts/nginx-setup.sh b/scripts/nginx-setup.sh index 53ca25f..174739a 100755 --- a/scripts/nginx-setup.sh +++ b/scripts/nginx-setup.sh @@ -93,21 +93,21 @@ generate_nginx_config() { } detect_nginx_containers() { - info "Detecting nginx containers..." + info "Detecting nginx containers..." >&2 local nginx_containers=$(docker ps --format '{{.Names}}' | grep -i nginx || true) if [ -z "$nginx_containers" ]; then - info "No nginx containers found" + info "No nginx containers found" >&2 return 1 fi - info "Found nginx containers:" + info "Found nginx containers:" >&2 local count=0 while IFS= read -r container; do count=$((count + 1)) local network=$(docker inspect "$container" --format '{{range $net, $conf := .NetworkSettings.Networks}}{{$net}} {{end}}' 2>/dev/null | awk '{print $1}') - echo "$count. $container (network: $network)" + echo "$count. $container (network: $network)" >&2 done <<< "$nginx_containers" return 0 @@ -119,7 +119,7 @@ prompt_nginx_selection() { return 0 fi - echo "" + echo "" >&2 read -p "Use existing nginx container? [y/N]: " use_existing if [[ "$use_existing" =~ ^[Yy]$ ]]; then @@ -133,15 +133,15 @@ prompt_nginx_selection() { read -p "Enter nginx container name: " selected_nginx fi - echo "" - info "Detecting nginx config directory for: $selected_nginx" + echo "" >&2 + info "Detecting nginx config directory for: $selected_nginx" >&2 local detected_config_dir=$(docker inspect "$selected_nginx" \ --format '{{range .Mounts}}{{if eq .Destination "/etc/nginx"}}{{.Source}}{{end}}{{end}}' \ 2>/dev/null || echo "") if [ -n "$detected_config_dir" ]; then - info "Auto-detected config directory: $detected_config_dir" + info "Auto-detected config directory: $detected_config_dir" >&2 read -p "Use this directory? [Y/n]: " use_detected if [[ ! "$use_detected" =~ ^[Nn]$ ]]; then echo "${selected_nginx}|${detected_config_dir}" @@ -149,33 +149,33 @@ prompt_nginx_selection() { fi fi - echo "" - warning "Cannot auto-detect nginx config directory" - echo "Please specify the directory where nginx configs should be placed:" - echo " - For Docker nginx: volume mount path (e.g., /opt/nginx/conf.d)" - echo " - For systemd nginx: /etc/nginx/sites-available or /etc/nginx/conf.d" - echo "" + echo "" >&2 + warning "Cannot auto-detect nginx config directory" >&2 + echo "Please specify the directory where nginx configs should be placed:" >&2 + echo " - For Docker nginx: volume mount path (e.g., /opt/nginx/conf.d)" >&2 + echo " - For systemd nginx: /etc/nginx/sites-available or /etc/nginx/conf.d" >&2 + echo "" >&2 read -p "Nginx config directory: " config_dir if [ -z "$config_dir" ]; then - error "Config directory cannot be empty" + error "Config directory cannot be empty" >&2 echo "none||" return 1 fi if docker exec "$selected_nginx" test -d "$config_dir" 2>/dev/null; then - success "Directory verified: $config_dir" + success "Directory verified: $config_dir" >&2 echo "${selected_nginx}|${config_dir}" elif [ -d "$config_dir" ]; then - success "Directory verified: $config_dir" + success "Directory verified: $config_dir" >&2 echo "${selected_nginx}|${config_dir}" else - warning "Directory not found: $config_dir" + warning "Directory not found: $config_dir" >&2 read -p "Create this directory? [y/N]: " create_dir if [[ "$create_dir" =~ ^[Yy]$ ]]; then echo "${selected_nginx}|${config_dir}|CREATE" else - error "Cannot proceed without valid config directory" + error "Cannot proceed without valid config directory" >&2 echo "none||" return 1 fi diff --git a/scripts/ufw-setup.sh b/scripts/ufw-setup.sh index 9fd3782..51bf429 100755 --- a/scripts/ufw-setup.sh +++ b/scripts/ufw-setup.sh @@ -381,4 +381,7 @@ main() { fi } -main "$@" +# Execute main only when script is run directly (not when sourced) +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main "$@" +fi diff --git a/setup.sh b/setup.sh index 6355d97..114566c 100755 --- a/setup.sh +++ b/setup.sh @@ -611,11 +611,82 @@ main() { setup_backup_cron fi - success "Setup completed successfully!" echo "" - info "Next steps:" - echo " 1. Review configuration: cat $ENV_FILE" - echo " 2. Deploy notes: ./deploy.sh" + echo "" + success "╔════════════════════════════════════════════════════════════════════╗" + success "║ ✅ УСТАНОВКА ЗАВЕРШЕНА УСПЕШНО ║" + success "╚════════════════════════════════════════════════════════════════════╝" + echo "" + + echo "📋 ИТОГОВЫЕ ПАРАМЕТРЫ:" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + echo " 🌐 Network:" + echo " Mode: $NETWORK_MODE" + echo " Name: $NETWORK_NAME" + [ -n "$NETWORK_SUBNET" ] && echo " Subnet: $NETWORK_SUBNET" + echo "" + echo " 🔧 Nginx:" + echo " Container: $NGINX_CONTAINER_NAME" + echo " Config dir: $NGINX_CONFIG_DIR" + echo " Deploy own: $DEPLOY_OWN_NGINX" + echo "" + echo " 💾 CouchDB:" + echo " Container: $COUCHDB_CONTAINER_NAME" + echo " User: admin" + echo " Password: [generated - 64 chars]" + echo " Port: 5984 (localhost only)" + echo "" + echo " 🌍 Domain & SSL:" + echo " Domain: $NOTES_DOMAIN" + echo " Email: $CERTBOT_EMAIL" + echo " SSL: Let's Encrypt (автообновление каждые 60 дней)" + echo "" + + if [[ -n "${S3_ACCESS_KEY_ID:-}" ]]; then + echo " ☁️ S3 Backup:" + echo " Bucket: $S3_BUCKET_NAME" + echo " Endpoint: $S3_ENDPOINT_URL" + echo " Region: $S3_REGION" + echo "" + fi + + if [[ "$SCHEDULER_CHOICE" == "2" ]]; then + echo " 🕐 Backup Schedule:" + echo " Type: Systemd timer" + echo " Schedule: Daily at 3:00 AM" + echo "" + else + echo " 🕐 Backup Schedule:" + echo " Type: Cron" + echo " Schedule: Daily at 3:00 AM" + echo "" + fi + + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + echo "📁 КОНФИГУРАЦИЯ СОХРАНЕНА:" + echo " $ENV_FILE" + echo "" + warning "⚠️ ВАЖНО: Храните $ENV_FILE в безопасности!" + warning "⚠️ Файл содержит пароли и секретные ключи." + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + info "🚀 СЛЕДУЮЩИЕ ШАГИ:" + echo "" + echo " 1. Проверьте конфигурацию:" + echo " cat $ENV_FILE" + echo "" + echo " 2. Запустите deploy:" + echo " sudo ./deploy.sh" + echo "" + echo " 3. После успешного deploy:" + echo " - Откройте https://$NOTES_DOMAIN" + echo " - Настройте Obsidian Self-hosted LiveSync plugin" + echo " - Используйте credentials из $ENV_FILE" + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" }