Add EZ-Homelab Enhanced Setup System
- Complete modular bash-based setup system replacing Python TUI - Phase 1-4 implementation: Core Infrastructure, Configuration Management, Deployment Engine, Service Orchestration & Management - 9 production-ready scripts: preflight.sh, setup.sh, pre-deployment-wizard.sh, localize.sh, generalize.sh, validate.sh, deploy.sh, service.sh, monitor.sh, backup.sh, update.sh - Shared libraries: common.sh (utilities), ui.sh (text interface) - Template-based configuration system with environment variable substitution - Comprehensive documentation: PRD, standards, and quick reference guides - Automated backup, monitoring, and update management capabilities - Cross-platform compatibility with robust error handling and logging
This commit is contained in:
372
scripts/enhanced-setup/pre-deployment-wizard.sh
Executable file
372
scripts/enhanced-setup/pre-deployment-wizard.sh
Executable file
@@ -0,0 +1,372 @@
|
||||
#!/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"
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user