Files
michaelschiemer/deployment/setup-wizard.sh
Michael Schiemer 9b74ade5b0 feat: Fix discovery system critical issues
Resolved multiple critical discovery system issues:

## Discovery System Fixes
- Fixed console commands not being discovered on first run
- Implemented fallback discovery for empty caches
- Added context-aware caching with separate cache keys
- Fixed object serialization preventing __PHP_Incomplete_Class

## Cache System Improvements
- Smart caching that only caches meaningful results
- Separate caches for different execution contexts (console, web, test)
- Proper array serialization/deserialization for cache compatibility
- Cache hit logging for debugging and monitoring

## Object Serialization Fixes
- Fixed DiscoveredAttribute serialization with proper string conversion
- Sanitized additional data to prevent object reference issues
- Added fallback for corrupted cache entries

## Performance & Reliability
- All 69 console commands properly discovered and cached
- 534 total discovery items successfully cached and restored
- No more __PHP_Incomplete_Class cache corruption
- Improved error handling and graceful fallbacks

## Testing & Quality
- Fixed code style issues across discovery components
- Enhanced logging for better debugging capabilities
- Improved cache validation and error recovery

Ready for production deployment with stable discovery system.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-13 12:04:17 +02:00

528 lines
17 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Interactive Setup Wizard for Custom PHP Framework Deployment
# Provides step-by-step guided configuration for production-ready deployments
# Domain: michaelschiemer.de | Email: kontakt@michaelschiemer.de | PHP: 8.4
set -euo pipefail
# Script configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../" && pwd)"
DEPLOYMENT_DIR="${SCRIPT_DIR}"
# Configuration state
CURRENT_STEP=1
TOTAL_STEPS=8
ENVIRONMENT=""
DOMAIN=""
EMAIL=""
SERVER_IP=""
SSH_KEY_PATH=""
# Configuration storage
declare -A CONFIG_VALUES
declare -A PASSWORD_STORE
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[1;37m'
NC='\033[0m'
# Enhanced logging functions
log() { echo -e "${GREEN}[$(date +'%H:%M:%S')] ✅ $1${NC}"; }
warn() { echo -e "${YELLOW}[$(date +'%H:%M:%S')] ⚠️ $1${NC}"; }
error() { echo -e "${RED}[$(date +'%H:%M:%S')] ❌ $1${NC}"; }
info() { echo -e "${BLUE}[$(date +'%H:%M:%S')] $1${NC}"; }
success() { echo -e "${WHITE}[$(date +'%H:%M:%S')] 🎉 $1${NC}"; }
# Progress indicator
show_progress() {
local step=$1
local total=$2
local description="$3"
local progress=$((step * 100 / total))
local bars=$((progress / 5))
local spaces=$((20 - bars))
printf "\n${PURPLE}[Step %d/%d] ${WHITE}%s${NC}\n" "$step" "$total" "$description"
printf "${CYAN}Progress: [${GREEN}"
printf "█%.0s" $(seq 1 $bars)
printf "${CYAN}"
printf "░%.0s" $(seq 1 $spaces)
printf "${CYAN}] %d%%${NC}\n\n" "$progress"
}
# Welcome screen
show_welcome() {
clear
cat << 'EOF'
███████╗███████╗████████╗██╗ ██╗██████╗
██╔════╝██╔════╝╚══██╔══╝██║ ██║██╔══██╗
███████╗█████╗ ██║ ██║ ██║██████╔╝
╚════██║██╔══╝ ██║ ██║ ██║██╔═══╝
███████║███████╗ ██║ ╚██████╔╝██║
╚══════╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝
EOF
cat << EOF
${WHITE}Custom PHP Framework Deployment Setup Wizard${NC}
${CYAN}Domain: michaelschiemer.de | Email: kontakt@michaelschiemer.de | PHP: 8.4${NC}
${GREEN}This wizard will guide you through setting up a production-ready deployment:${NC}
✅ Environment configuration with secure defaults
✅ Automatic password generation and validation
✅ SSH key setup and server connectivity testing
✅ SSL/TLS certificate configuration
✅ Docker and Ansible integration
✅ Complete deployment validation
${YELLOW}Prerequisites:${NC} Internet connection, sudo access (if needed)
${YELLOW}Time Required:${NC} 10-15 minutes
${YELLOW}What You'll Need:${NC} Server details and domain information
${WHITE}Press Enter to start, or Ctrl+C to exit...${NC}
EOF
read -r
}
# Step 1: Environment Selection
step_environment_selection() {
show_progress $CURRENT_STEP $TOTAL_STEPS "Environment Selection"
cat << EOF
${WHITE}Select Deployment Environment${NC}
${CYAN}Available environments:${NC}
1) ${GREEN}Development${NC} - Local development with debug enabled
2) ${YELLOW}Staging${NC} - Pre-production testing environment
3) ${RED}Production${NC} - Live production environment (recommended)
${WHITE}Which environment would you like to configure?${NC}
EOF
while true; do
printf "${CYAN}Enter choice (1-3): ${NC}"
read -r choice
case $choice in
1)
ENVIRONMENT="development"
DOMAIN="dev.michaelschiemer.de"
info "Selected: Development environment"
break
;;
2)
ENVIRONMENT="staging"
DOMAIN="staging.michaelschiemer.de"
info "Selected: Staging environment"
break
;;
3)
ENVIRONMENT="production"
DOMAIN="michaelschiemer.de"
info "Selected: Production environment"
break
;;
*)
error "Invalid choice. Please enter 1, 2, or 3."
;;
esac
done
CONFIG_VALUES[ENVIRONMENT]=$ENVIRONMENT
CONFIG_VALUES[DOMAIN]=$DOMAIN
}
# Step 2: Domain and Contact Configuration
step_domain_configuration() {
show_progress $CURRENT_STEP $TOTAL_STEPS "Domain and Contact Information"
cat << EOF
${WHITE}Domain and Contact Configuration${NC}
Current settings:
• Environment: ${GREEN}${ENVIRONMENT}${NC}
• Suggested domain: ${GREEN}${DOMAIN}${NC}
• Contact email: ${GREEN}kontakt@michaelschiemer.de${NC}
EOF
printf "\n${CYAN}Is this domain correct? [Y/n]: ${NC}"
read -r confirm
if [[ $confirm =~ ^[Nn]$ ]]; then
printf "${CYAN}Enter your domain name: ${NC}"
read -r custom_domain
if [[ -n "$custom_domain" ]]; then
DOMAIN="$custom_domain"
CONFIG_VALUES[DOMAIN]="$custom_domain"
info "Domain updated to: $custom_domain"
fi
fi
EMAIL="kontakt@michaelschiemer.de"
printf "${CYAN}Contact email for SSL certificates [${EMAIL}]: ${NC}"
read -r custom_email
if [[ -n "$custom_email" ]]; then
EMAIL="$custom_email"
fi
CONFIG_VALUES[EMAIL]=$EMAIL
success "Domain configuration completed"
}
# Step 3: Server Configuration
step_server_configuration() {
show_progress $CURRENT_STEP $TOTAL_STEPS "Server Configuration"
cat << EOF
${WHITE}Server Configuration${NC}
Enter your deployment server details:
EOF
while true; do
printf "${CYAN}Server IP address or hostname: ${NC}"
read -r server_ip
if [[ -n "$server_ip" ]]; then
if [[ $server_ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] || [[ $server_ip =~ ^[a-zA-Z0-9.-]+$ ]]; then
SERVER_IP="$server_ip"
CONFIG_VALUES[SERVER_IP]="$server_ip"
break
else
error "Invalid IP address or hostname format"
fi
else
error "Server IP/hostname is required"
fi
done
printf "${CYAN}SSH username [root]: ${NC}"
read -r ssh_user
ssh_user=${ssh_user:-root}
CONFIG_VALUES[SSH_USER]="$ssh_user"
printf "${CYAN}SSH port [22]: ${NC}"
read -r ssh_port
ssh_port=${ssh_port:-22}
CONFIG_VALUES[SSH_PORT]="$ssh_port"
info "Server: ${ssh_user}@${SERVER_IP}:${ssh_port}"
success "Server configuration completed"
}
# Step 4: SSH Key Setup
step_ssh_key_setup() {
show_progress $CURRENT_STEP $TOTAL_STEPS "SSH Key Configuration"
cat << EOF
${WHITE}SSH Key Setup${NC}
We need SSH access to your server for deployment.
EOF
local default_key="$HOME/.ssh/production"
printf "${CYAN}SSH private key path [${default_key}]: ${NC}"
read -r key_path
SSH_KEY_PATH=${key_path:-$default_key}
if [[ ! -f "$SSH_KEY_PATH" ]]; then
warn "SSH key not found: $SSH_KEY_PATH"
printf "${CYAN}Generate new SSH key pair? [Y/n]: ${NC}"
read -r generate_key
if [[ ! $generate_key =~ ^[Nn]$ ]]; then
info "Generating SSH key pair..."
mkdir -p "$(dirname "$SSH_KEY_PATH")"
ssh-keygen -t ed25519 -C "deploy@${DOMAIN}" -f "$SSH_KEY_PATH" -N ""
success "SSH key pair generated:"
info "Private key: $SSH_KEY_PATH"
info "Public key: ${SSH_KEY_PATH}.pub"
cat << EOF
${YELLOW}📋 COPY THIS PUBLIC KEY TO YOUR SERVER:${NC}
$(cat "${SSH_KEY_PATH}.pub")
${YELLOW}Add this key to ~/.ssh/authorized_keys on your server.${NC}
EOF
printf "${CYAN}Press Enter when you've added the key to your server...${NC}"
read -r
fi
else
success "Found existing SSH key: $SSH_KEY_PATH"
fi
CONFIG_VALUES[SSH_KEY_PATH]="$SSH_KEY_PATH"
}
# Step 5: Test Server Connectivity
step_test_connectivity() {
show_progress $CURRENT_STEP $TOTAL_STEPS "Server Connectivity Test"
cat << EOF
${WHITE}Testing Server Connectivity${NC}
Testing SSH connection to ${CONFIG_VALUES[SSH_USER]}@${CONFIG_VALUES[SERVER_IP]}...
EOF
if ssh -i "$SSH_KEY_PATH" -p "${CONFIG_VALUES[SSH_PORT]}" \
-o ConnectTimeout=10 -o BatchMode=yes \
"${CONFIG_VALUES[SSH_USER]}@${CONFIG_VALUES[SERVER_IP]}" \
"echo 'Connection successful'" 2>/dev/null; then
success "SSH connection test passed"
info "Testing server requirements..."
local server_info
server_info=$(ssh -i "$SSH_KEY_PATH" -p "${CONFIG_VALUES[SSH_PORT]}" \
"${CONFIG_VALUES[SSH_USER]}@${CONFIG_VALUES[SERVER_IP]}" \
"uname -a && free -h && df -h /" 2>/dev/null)
echo -e "${BLUE}Server Information:${NC}"
echo "$server_info"
else
error "SSH connection failed"
cat << EOF
${YELLOW}Troubleshooting tips:${NC}
1. Verify the server IP and SSH port
2. Ensure your SSH public key is in ~/.ssh/authorized_keys on the server
3. Check if SSH service is running on the server
4. Verify firewall allows SSH connections
EOF
printf "${CYAN}Continue anyway? [y/N]: ${NC}"
read -r continue_anyway
if [[ ! $continue_anyway =~ ^[Yy]$ ]]; then
error "Setup cancelled due to connectivity issues"
exit 1
fi
fi
}
# Step 6: Secure Password Generation
step_password_generation() {
show_progress $CURRENT_STEP $TOTAL_STEPS "Secure Credential Generation"
cat << EOF
${WHITE}Generating Secure Credentials${NC}
Creating secure passwords and keys for your deployment...
EOF
if ! command -v openssl >/dev/null 2>&1; then
error "OpenSSL not found. Please install OpenSSL first."
exit 1
fi
info "Generating database passwords..."
PASSWORD_STORE[DB_PASSWORD]=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
PASSWORD_STORE[DB_ROOT_PASSWORD]=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
info "Generating Redis password..."
PASSWORD_STORE[REDIS_PASSWORD]=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
info "Generating application key..."
PASSWORD_STORE[APP_KEY]=$(openssl rand -base64 32)
if [[ "$ENVIRONMENT" == "production" ]]; then
info "Generating monitoring passwords..."
PASSWORD_STORE[GRAFANA_ADMIN_PASSWORD]=$(openssl rand -base64 16 | tr -d "=+/" | cut -c1-16)
fi
success "All credentials generated securely"
# Show password strength
cat << EOF
${CYAN}Password Strength Summary:${NC}
• Database passwords: 25 characters, alphanumeric
• Redis password: 25 characters, alphanumeric
• Application key: 32 characters, base64 encoded
• All passwords cryptographically secure
EOF
}
# Step 7: Configuration File Creation
step_create_configuration() {
show_progress $CURRENT_STEP $TOTAL_STEPS "Configuration File Creation"
cat << EOF
${WHITE}Creating Configuration Files${NC}
Building environment configuration for ${ENVIRONMENT}...
EOF
local env_file="${DEPLOYMENT_DIR}/applications/environments/.env.${ENVIRONMENT}"
local template_file="${env_file}.template"
if [[ ! -f "$template_file" ]]; then
error "Template file not found: $template_file"
exit 1
fi
info "Creating .env.${ENVIRONMENT} from template..."
cp "$template_file" "$env_file"
# Apply configurations
info "Applying domain and email settings..."
sed -i "s|DOMAIN_NAME=.*|DOMAIN_NAME=${CONFIG_VALUES[DOMAIN]}|g" "$env_file"
sed -i "s|MAIL_FROM_ADDRESS=.*|MAIL_FROM_ADDRESS=${CONFIG_VALUES[EMAIL]}|g" "$env_file"
# Apply generated passwords
info "Applying secure credentials..."
for key in "${!PASSWORD_STORE[@]}"; do
local value="${PASSWORD_STORE[$key]}"
sed -i "s|${key}=\*\*\* REQUIRED \*\*\*|${key}=${value}|g" "$env_file"
sed -i "s|${key}=changeme|${key}=${value}|g" "$env_file"
done
# Environment-specific settings
if [[ "$ENVIRONMENT" == "production" ]]; then
sed -i 's|APP_DEBUG=.*|APP_DEBUG=false|g' "$env_file"
sed -i 's|LOG_LEVEL=.*|LOG_LEVEL=warning|g' "$env_file"
fi
# Set secure permissions
chmod 600 "$env_file"
success "Configuration file created: $env_file"
# Update Ansible inventory
info "Updating Ansible inventory..."
local inventory_file="${DEPLOYMENT_DIR}/infrastructure/inventories/${ENVIRONMENT}/hosts.yml"
if [[ -f "$inventory_file" ]]; then
# Backup original
cp "$inventory_file" "${inventory_file}.backup"
# Update server details
sed -i "s|ansible_host:.*|ansible_host: ${CONFIG_VALUES[SERVER_IP]}|g" "$inventory_file"
sed -i "s|ansible_user:.*|ansible_user: ${CONFIG_VALUES[SSH_USER]}|g" "$inventory_file"
sed -i "s|ansible_port:.*|ansible_port: ${CONFIG_VALUES[SSH_PORT]}|g" "$inventory_file"
sed -i "s|ansible_ssh_private_key_file:.*|ansible_ssh_private_key_file: ${CONFIG_VALUES[SSH_KEY_PATH]}|g" "$inventory_file"
success "Ansible inventory updated: $inventory_file"
else
warn "Ansible inventory not found: $inventory_file"
fi
}
# Step 8: Final Validation and Summary
step_final_validation() {
show_progress $CURRENT_STEP $TOTAL_STEPS "Final Validation"
cat << EOF
${WHITE}Final Validation and Summary${NC}
Running configuration validation...
EOF
# Validate configuration
local env_file="${DEPLOYMENT_DIR}/applications/environments/.env.${ENVIRONMENT}"
info "Validating environment configuration..."
if grep -q "\*\*\* REQUIRED \*\*\*" "$env_file" 2>/dev/null; then
error "Some required fields are still unfilled:"
grep "\*\*\* REQUIRED \*\*\*" "$env_file"
exit 1
fi
success "All required fields are configured"
# Test Docker Compose configuration
info "Validating Docker Compose configuration..."
cd "$PROJECT_ROOT"
if docker-compose -f docker-compose.yml -f "deployment/applications/docker-compose.${ENVIRONMENT}.yml" config >/dev/null 2>&1; then
success "Docker Compose configuration is valid"
else
warn "Docker Compose validation failed - may need manual review"
fi
# Show summary
cat << EOF
${WHITE}🎉 SETUP WIZARD COMPLETED SUCCESSFULLY! 🎉${NC}
${CYAN}Configuration Summary:${NC}
• Environment: ${WHITE}${ENVIRONMENT}${NC}
• Domain: ${WHITE}${CONFIG_VALUES[DOMAIN]}${NC}
• Server: ${WHITE}${CONFIG_VALUES[SSH_USER]}@${CONFIG_VALUES[SERVER_IP]}:${CONFIG_VALUES[SSH_PORT]}${NC}
• SSH Key: ${WHITE}${CONFIG_VALUES[SSH_KEY_PATH]}${NC}
• Configuration: ${WHITE}.env.${ENVIRONMENT}${NC}
${CYAN}Generated Secure Credentials:${NC}
• Database passwords: ${GREEN}Generated${NC}
• Redis password: ${GREEN}Generated${NC}
• Application key: ${GREEN}Generated${NC}
EOF
if [[ "$ENVIRONMENT" == "production" ]]; then
echo "• Monitoring passwords: ${GREEN}Generated${NC}"
fi
cat << EOF
${CYAN}Files Created/Updated:${NC}
• ${YELLOW}deployment/applications/environments/.env.${ENVIRONMENT}${NC}
• ${YELLOW}deployment/infrastructure/inventories/${ENVIRONMENT}/hosts.yml${NC}
• ${YELLOW}${CONFIG_VALUES[SSH_KEY_PATH]} (if generated)${NC}
${CYAN}Next Steps:${NC}
1. Review configuration: ${YELLOW}less deployment/applications/environments/.env.${ENVIRONMENT}${NC}
2. Test deployment: ${YELLOW}./deployment/deploy.sh ${ENVIRONMENT} --dry-run${NC}
3. Deploy: ${YELLOW}./deployment/deploy.sh ${ENVIRONMENT}${NC}
${GREEN}Your Custom PHP Framework is ready for deployment!${NC}
${CYAN}Domain: ${CONFIG_VALUES[DOMAIN]} | Environment: ${ENVIRONMENT}${NC}
EOF
}
# Main wizard flow
main() {
show_welcome
# Execute wizard steps
CURRENT_STEP=1; step_environment_selection; ((CURRENT_STEP++))
CURRENT_STEP=2; step_domain_configuration; ((CURRENT_STEP++))
CURRENT_STEP=3; step_server_configuration; ((CURRENT_STEP++))
CURRENT_STEP=4; step_ssh_key_setup; ((CURRENT_STEP++))
CURRENT_STEP=5; step_test_connectivity; ((CURRENT_STEP++))
CURRENT_STEP=6; step_password_generation; ((CURRENT_STEP++))
CURRENT_STEP=7; step_create_configuration; ((CURRENT_STEP++))
CURRENT_STEP=8; step_final_validation; ((CURRENT_STEP++))
success "Setup wizard completed successfully!"
}
# Error handling
cleanup() {
local exit_code=$?
if [ $exit_code -ne 0 ]; then
error "Setup wizard failed with exit code: $exit_code"
echo
echo -e "${RED}If you need help, check the troubleshooting guide or start over.${NC}"
fi
}
trap cleanup EXIT
# Execute if run directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi