Files
EZ-Homelab/scripts/enhanced-setup/pre-deployment-wizard.sh
Kelin 8b89575bbb Fix pre-deployment wizard execution and return handling
- Changed menu to run wizard as subprocess instead of exec
- Removed wizard's exec of menu since it now returns naturally
- Wizard now properly returns to menu on completion or error
- Prevents terminal freezing when wizard crashes
2026-01-29 22:41:25 -05:00

375 lines
10 KiB
Bash
Executable File

#!/bin/bash
# EZ-Homelab Enhanced Setup Scripts - Pre-Deployment Configuration Wizard
# Interactive setup of deployment options and environment configuration
SCRIPT_NAME="pre-deployment-wizard"
SCRIPT_VERSION="1.0.0"
# Load common library
source "$(dirname "${BASH_SOURCE[0]}")/lib/common.sh"
source "$(dirname "${BASH_SOURCE[0]}")/lib/ui.sh"
# =============================================================================
# SCRIPT CONFIGURATION
# =============================================================================
# Default values
DEFAULT_DOMAIN="example.duckdns.org"
DEFAULT_TIMEZONE="America/New_York"
DEFAULT_PUID=1000
DEFAULT_PGID=1000
# Service stacks
CORE_STACKS=("duckdns" "traefik" "authelia" "gluetun" "sablier")
INFRA_STACKS=("dockge" "pihole")
DASHBOARD_STACKS=("homepage" "homarr")
MEDIA_STACKS=("plex" "jellyfin" "calibre-web" "qbittorrent")
MEDIA_MGMT_STACKS=("sonarr" "radarr" "bazarr" "lidarr" "readarr" "prowlarr")
HOME_STACKS=("homeassistant" "nodered" "zigbee2mqtt")
PRODUCTIVITY_STACKS=("nextcloud" "gitea" "bookstack")
MONITORING_STACKS=("grafana" "prometheus" "uptimekuma")
UTILITY_STACKS=("duplicati" "freshrss" "wallabag")
# =============================================================================
# CONFIGURATION FUNCTIONS
# =============================================================================
# Create required Docker networks
create_docker_networks() {
print_info "Creating required Docker networks..."
local networks=("traefik-network" "homelab-network")
for network in "${networks[@]}"; do
if ! docker network ls --format "{{.Name}}" | grep -q "^${network}$"; then
docker network create "$network" || {
print_error "Failed to create network: $network"
return 1
}
print_success "Created network: $network"
else
print_info "Network already exists: $network"
fi
done
return 0
}
# Generate .env file
generate_env_file() {
local domain="$1"
local timezone="$2"
local puid="$3"
local pgid="$4"
local deployment_type="$5"
print_info "Generating .env file..."
local env_file="$EZ_HOME/.env"
local temp_file
temp_file=$(mktemp)
# Generate secrets
local jwt_secret
jwt_secret=$(openssl rand -hex 64 2>/dev/null || echo "change-me-jwt-secret")
local session_secret
session_secret=$(openssl rand -hex 64 2>/dev/null || echo "change-me-session-secret")
local encryption_key
encryption_key=$(openssl rand -hex 64 2>/dev/null || echo "change-me-encryption-key")
local duckdns_token="your-duckdns-token-here"
# Write environment variables
cat > "$temp_file" << EOF
# EZ-Homelab Environment Configuration
# Generated by pre-deployment-wizard.sh on $(date)
# Domain and Networking
DOMAIN=$domain
TZ=$timezone
PUID=$puid
PGID=$pgid
# DuckDNS Configuration
DUCKDNS_TOKEN=$duckdns_token
# Authelia Secrets (Change these in production!)
JWT_SECRET=$jwt_secret
SESSION_SECRET=$session_secret
ENCRYPTION_KEY=$encryption_key
# Deployment Configuration
DEPLOYMENT_TYPE=$deployment_type
SERVER_HOSTNAME=$(hostname)
# Docker Configuration
DOCKER_SOCKET_PATH=/var/run/docker.sock
# Default Credentials (Change these!)
AUTHELIA_ADMIN_PASSWORD=admin
AUTHELIA_ADMIN_EMAIL=admin@example.com
# Service-specific settings
PLEX_CLAIM_TOKEN=your-plex-claim-token
EOF
# Backup existing .env if it exists
if [[ -f "$env_file" ]]; then
backup_file "$env_file"
fi
# Move to final location
mv "$temp_file" "$env_file"
chmod 600 "$env_file"
print_success ".env file created at $env_file"
print_warning "IMPORTANT: Edit the .env file to set your actual secrets and tokens!"
}
# Get service selection based on deployment type
get_service_selection() {
local deployment_type="$1"
local selected_services=()
case "$deployment_type" in
"core")
selected_services=("${CORE_STACKS[@]}")
;;
"single")
# Show all categories for single server
local all_services=(
"${CORE_STACKS[@]}"
"${INFRA_STACKS[@]}"
"${DASHBOARD_STACKS[@]}"
"${MEDIA_STACKS[@]}"
"${MEDIA_MGMT_STACKS[@]}"
"${HOME_STACKS[@]}"
"${PRODUCTIVITY_STACKS[@]}"
"${MONITORING_STACKS[@]}"
"${UTILITY_STACKS[@]}"
)
selected_services=("${all_services[@]}")
;;
"remote")
# Remote servers get infrastructure + services (no core)
local remote_services=(
"${INFRA_STACKS[@]}"
"${DASHBOARD_STACKS[@]}"
"${MEDIA_STACKS[@]}"
"${MEDIA_MGMT_STACKS[@]}"
"${HOME_STACKS[@]}"
"${PRODUCTIVITY_STACKS[@]}"
"${MONITORING_STACKS[@]}"
"${UTILITY_STACKS[@]}"
)
selected_services=("${remote_services[@]}")
;;
esac
echo "${selected_services[@]}"
}
# Validate configuration
validate_configuration() {
local domain="$1"
local deployment_type="$2"
print_info "Validating configuration..."
# Validate domain format
if [[ ! "$domain" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
print_error "Invalid domain format: $domain"
return 1
fi
# Validate deployment type
case "$deployment_type" in
"core"|"single"|"remote")
;;
*)
print_error "Invalid deployment type: $deployment_type"
return 1
;;
esac
print_success "Configuration validation passed"
return 0
}
# =============================================================================
# UI FUNCTIONS
# =============================================================================
# Show welcome screen
show_welcome() {
ui_msgbox "Welcome to EZ-Homelab Setup Wizard!
This wizard will help you configure your EZ-Homelab deployment by:
• Setting up Docker networks
• Configuring environment variables
• Selecting services to deploy
• Generating configuration files
Press OK to continue or ESC to cancel."
}
# Get domain configuration
get_domain_config() {
local domain
domain=$(ui_inputbox "Enter your domain (e.g., yourname.duckdns.org):" "$DEFAULT_DOMAIN")
[[ -z "$domain" ]] && return 1
echo "$domain"
}
# Get timezone
get_timezone() {
local timezone
timezone=$(ui_inputbox "Enter your timezone (e.g., America/New_York):" "$DEFAULT_TIMEZONE")
[[ -z "$timezone" ]] && return 1
echo "$timezone"
}
# Get PUID/PGID
get_user_ids() {
local puid pgid
puid=$(ui_inputbox "Enter PUID (User ID for Docker containers):" "$DEFAULT_PUID")
[[ -z "$puid" ]] && return 1
pgid=$(ui_inputbox "Enter PGID (Group ID for Docker containers):" "$DEFAULT_PGID")
[[ -z "$pgid" ]] && return 1
echo "$puid $pgid"
}
# Get deployment type
get_deployment_type() {
ui_select_deployment_type
}
# Confirm configuration
confirm_configuration() {
local domain="$1"
local timezone="$2"
local puid="$3"
local pgid="$4"
local deployment_type="$5"
local services="$6"
local message="Configuration Summary:
Domain: $domain
Timezone: $timezone
PUID/PGID: $puid/$pgid
Deployment Type: $deployment_type
Services: $services
Do you want to proceed with this configuration?"
ui_yesno "$message"
}
# =============================================================================
# MAIN FUNCTION
# =============================================================================
main() {
local non_interactive=false
local verbose=false
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
ui_show_help "$SCRIPT_NAME"
exit 0
;;
--no-ui)
non_interactive=true
;;
-v|--verbose)
verbose=true
;;
*)
print_error "Unknown option: $1"
echo "Use --help for usage information"
exit 1
;;
esac
shift
done
# Initialize script
init_script "$SCRIPT_NAME"
if $verbose; then
set -x
fi
print_info "Starting EZ-Homelab pre-deployment configuration wizard..."
# Check if running interactively
if ! ui_available || $non_interactive; then
print_error "This script requires an interactive terminal with dialog/whiptail"
print_error "Run without --no-ui or in a proper terminal"
exit 1
fi
# Show welcome screen
show_welcome || exit 1
# Get configuration interactively
local domain
domain=$(get_domain_config) || exit 1
local timezone
timezone=$(get_timezone) || exit 1
local puid pgid
read -r puid pgid <<< "$(get_user_ids)" || exit 1
local deployment_type
deployment_type=$(get_deployment_type) || exit 1
# Get service selection
local services
services=$(get_service_selection "$deployment_type")
# Confirm configuration
if ! confirm_configuration "$domain" "$timezone" "$puid" "$pgid" "$deployment_type" "$services"; then
print_info "Configuration cancelled by user"
exit 0
fi
# Validate configuration
if ! validate_configuration "$domain" "$deployment_type"; then
print_error "Configuration validation failed"
exit 1
fi
# Create Docker networks
if ! create_docker_networks; then
print_error "Failed to create Docker networks"
exit 1
fi
# Generate .env file
if ! generate_env_file "$domain" "$timezone" "$puid" "$pgid" "$deployment_type"; then
print_error "Failed to generate .env file"
exit 1
fi
echo ""
print_success "EZ-Homelab configuration complete!"
print_info "Next steps:"
print_info "1. Edit $EZ_HOME/.env to set your actual secrets"
print_info "2. Run: ./validate.sh"
print_info "3. Run: ./localize.sh"
print_info "4. Run: ./deploy.sh core"
echo ""
print_info "Returning to EZ-Homelab menu..."
exit 0
}
# Run main function
main "$@"