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>
This commit is contained in:
2025-08-13 12:04:17 +02:00
parent 66f7efdcfc
commit 9b74ade5b0
494 changed files with 764014 additions and 1127382 deletions

628
deployment/setup.sh Executable file
View File

@@ -0,0 +1,628 @@
#!/bin/bash
# First-time Setup Script for Custom PHP Framework Deployment
# Domain: michaelschiemer.de | Email: kontakt@michaelschiemer.de | PHP: 8.4
# Usage: ./setup.sh [options]
set -euo pipefail
# Script configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../" && pwd)"
DEPLOYMENT_DIR="${SCRIPT_DIR}"
# Default configuration
INSTALL_DEPENDENCIES=true
SETUP_CONFIGS=true
GENERATE_KEYS=true
VERBOSE=false
SKIP_PROMPTS=false
# 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' # No Color
# Logging functions
log() {
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] ✅ INFO: $1${NC}"
}
warn() {
echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] ⚠️ WARN: $1${NC}"
}
error() {
echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ❌ ERROR: $1${NC}"
}
debug() {
if [ "$VERBOSE" = true ]; then
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')] 🔍 DEBUG: $1${NC}"
fi
}
success() {
echo -e "${WHITE}[$(date +'%Y-%m-%d %H:%M:%S')] 🎉 SUCCESS: $1${NC}"
}
section() {
echo -e "\n${PURPLE}================================${NC}"
echo -e "${PURPLE}$1${NC}"
echo -e "${PURPLE}================================${NC}\n"
}
# Usage information
show_usage() {
cat << EOF
${WHITE}Custom PHP Framework Deployment Setup${NC}
${CYAN}Domain: michaelschiemer.de | Email: kontakt@michaelschiemer.de | PHP: 8.4${NC}
${WHITE}Usage:${NC} $0 [options]
${WHITE}Options:${NC}
${YELLOW}--skip-dependencies${NC} Skip dependency installation
${YELLOW}--skip-configs${NC} Skip configuration setup
${YELLOW}--skip-keys${NC} Skip SSH key generation
${YELLOW}--skip-prompts${NC} Skip interactive prompts (use defaults)
${YELLOW}--verbose${NC} Enable verbose output
${YELLOW}-h, --help${NC} Show this help message
${WHITE}What this script does:${NC}
• Installs required dependencies (Docker, Ansible, etc.)
• Sets up configuration files from templates
• Generates SSH keys for deployment
• Validates the deployment environment
• Prepares the system for first deployment
${WHITE}Examples:${NC}
${CYAN}$0${NC} # Full setup with prompts
${CYAN}$0 --skip-prompts${NC} # Automated setup
${CYAN}$0 --skip-dependencies --verbose${NC} # Setup configs only with debug output
EOF
}
# Parse command line arguments
parse_arguments() {
while [[ $# -gt 0 ]]; do
case $1 in
--skip-dependencies)
INSTALL_DEPENDENCIES=false
shift
;;
--skip-configs)
SETUP_CONFIGS=false
shift
;;
--skip-keys)
GENERATE_KEYS=false
shift
;;
--skip-prompts)
SKIP_PROMPTS=true
shift
;;
--verbose)
VERBOSE=true
shift
;;
-h|--help)
show_usage
exit 0
;;
*)
error "Unknown argument: $1"
show_usage
exit 1
;;
esac
done
}
# Detect operating system
detect_os() {
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
if command -v apt-get >/dev/null 2>&1; then
OS="ubuntu"
elif command -v yum >/dev/null 2>&1; then
OS="centos"
else
OS="linux"
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
OS="macos"
else
OS="unknown"
fi
debug "Detected OS: $OS"
}
# Check if running as root
check_root() {
if [[ $EUID -eq 0 ]]; then
warn "Running as root. Some operations may require different permissions."
fi
}
# Install dependencies based on OS
install_dependencies() {
if [ "$INSTALL_DEPENDENCIES" = false ]; then
debug "Skipping dependency installation"
return 0
fi
section "INSTALLING DEPENDENCIES"
log "Installing required dependencies for $OS"
case $OS in
ubuntu)
log "Updating package lists"
sudo apt-get update
log "Installing required packages"
sudo apt-get install -y \
curl \
wget \
git \
python3 \
python3-pip \
software-properties-common \
apt-transport-https \
ca-certificates \
gnupg \
lsb-release
# Install Docker
if ! command -v docker >/dev/null 2>&1; then
log "Installing Docker"
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Add user to docker group
sudo usermod -aG docker "$USER"
warn "You need to log out and back in for Docker permissions to take effect"
else
debug "Docker already installed"
fi
# Install Docker Compose (standalone)
if ! command -v docker-compose >/dev/null 2>&1; then
log "Installing Docker Compose"
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
else
debug "Docker Compose already installed"
fi
# Install Ansible
if ! command -v ansible-playbook >/dev/null 2>&1; then
log "Installing Ansible"
sudo apt-get install -y ansible
else
debug "Ansible already installed"
fi
;;
centos)
log "Installing required packages for CentOS/RHEL"
sudo yum update -y
sudo yum install -y curl wget git python3 python3-pip
# Install Docker
if ! command -v docker >/dev/null 2>&1; then
log "Installing Docker"
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker "$USER"
else
debug "Docker already installed"
fi
# Install Ansible
if ! command -v ansible-playbook >/dev/null 2>&1; then
log "Installing Ansible"
sudo yum install -y epel-release
sudo yum install -y ansible
else
debug "Ansible already installed"
fi
;;
macos)
if ! command -v brew >/dev/null 2>&1; then
error "Homebrew not found. Please install Homebrew first:"
error "https://brew.sh/"
exit 1
fi
log "Installing required packages for macOS"
# Install Docker Desktop
if ! command -v docker >/dev/null 2>&1; then
log "Installing Docker Desktop"
brew install --cask docker
warn "Please start Docker Desktop application manually"
else
debug "Docker already installed"
fi
# Install Docker Compose
if ! command -v docker-compose >/dev/null 2>&1; then
log "Installing Docker Compose"
brew install docker-compose
else
debug "Docker Compose already installed"
fi
# Install Ansible
if ! command -v ansible-playbook >/dev/null 2>&1; then
log "Installing Ansible"
brew install ansible
else
debug "Ansible already installed"
fi
;;
*)
error "Unsupported operating system: $OS"
error "Please install dependencies manually:"
error "- Docker (docker.com)"
error "- Docker Compose"
error "- Ansible (ansible.com)"
exit 1
;;
esac
success "Dependencies installation completed"
}
# Verify installations
verify_dependencies() {
section "VERIFYING DEPENDENCIES"
local all_good=true
# Check Docker
if command -v docker >/dev/null 2>&1; then
local docker_version=$(docker --version)
log "✓ Docker: $docker_version"
# Test Docker without sudo
if docker ps >/dev/null 2>&1; then
debug "✓ Docker permissions configured correctly"
else
warn "Docker requires sudo. You may need to log out and back in."
fi
else
error "❌ Docker not found"
all_good=false
fi
# Check Docker Compose
if command -v docker-compose >/dev/null 2>&1; then
local compose_version=$(docker-compose --version)
log "✓ Docker Compose: $compose_version"
else
error "❌ Docker Compose not found"
all_good=false
fi
# Check Ansible
if command -v ansible-playbook >/dev/null 2>&1; then
local ansible_version=$(ansible --version | head -n1)
log "✓ Ansible: $ansible_version"
else
error "❌ Ansible not found"
all_good=false
fi
# Check Python
if command -v python3 >/dev/null 2>&1; then
local python_version=$(python3 --version)
log "✓ Python: $python_version"
else
warn "Python3 not found (may be required for some Ansible modules)"
fi
if [ "$all_good" = false ]; then
error "Some dependencies are missing. Please install them and run setup again."
exit 1
fi
success "All dependencies verified"
}
# Setup configuration files
setup_configuration() {
if [ "$SETUP_CONFIGS" = false ]; then
debug "Skipping configuration setup"
return 0
fi
section "SETTING UP CONFIGURATION"
# Create environment files from templates
log "Creating environment configuration files"
local environments=("development" "staging" "production")
for env in "${environments[@]}"; do
local env_file="${DEPLOYMENT_DIR}/applications/environments/.env.${env}"
local template_file="${env_file}.template"
if [[ -f "$template_file" ]]; then
if [[ ! -f "$env_file" ]]; then
log "Creating .env.${env} from template"
cp "$template_file" "$env_file"
# Basic substitutions
if [ "$SKIP_PROMPTS" = false ]; then
echo -e "${CYAN}Configuring $env environment:${NC}"
# Domain configuration
if [ "$env" = "production" ]; then
sed -i 's/your-domain\.com/michaelschiemer.de/g' "$env_file"
sed -i 's/your-email@example\.com/kontakt@michaelschiemer.de/g' "$env_file"
else
read -p "Domain for $env (default: ${env}.michaelschiemer.de): " domain
domain=${domain:-"${env}.michaelschiemer.de"}
sed -i "s/your-domain\.com/$domain/g" "$env_file"
sed -i 's/your-email@example\.com/kontakt@michaelschiemer.de/g' "$env_file"
fi
# Generate random passwords
if command -v openssl >/dev/null 2>&1; then
local db_password=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
local app_key=$(openssl rand -base64 32)
sed -i "s/changeme/$db_password/g" "$env_file"
sed -i "s/*** REQUIRED - Generate random key ***/$app_key/g" "$env_file"
debug "Generated secure passwords for $env"
fi
else
# Non-interactive: use defaults
if [ "$env" = "production" ]; then
sed -i 's/your-domain\.com/michaelschiemer.de/g' "$env_file"
else
sed -i "s/your-domain\.com/${env}.michaelschiemer.de/g" "$env_file"
fi
sed -i 's/your-email@example\.com/kontakt@michaelschiemer.de/g' "$env_file"
warn "Using default configuration for $env. Review and update manually."
fi
else
debug ".env.${env} already exists"
fi
else
warn "Template not found: $template_file"
fi
done
# Set proper permissions
log "Setting configuration file permissions"
find "${DEPLOYMENT_DIR}/applications/environments" -name ".env.*" -type f -exec chmod 600 {} \;
# Create necessary directories
log "Creating necessary directories"
mkdir -p "${PROJECT_ROOT}/storage/backups"
mkdir -p "${PROJECT_ROOT}/storage/logs"
mkdir -p "${DEPLOYMENT_DIR}/infrastructure/logs"
success "Configuration setup completed"
}
# Generate SSH keys for deployment
generate_ssh_keys() {
if [ "$GENERATE_KEYS" = false ]; then
debug "Skipping SSH key generation"
return 0
fi
section "SETTING UP SSH KEYS"
local ssh_dir="$HOME/.ssh"
local key_name="michaelschiemer_deploy"
local private_key="${ssh_dir}/${key_name}"
local public_key="${private_key}.pub"
if [[ ! -f "$private_key" ]]; then
log "Generating SSH key pair for deployment"
mkdir -p "$ssh_dir"
chmod 700 "$ssh_dir"
ssh-keygen -t ed25519 -C "deployment@michaelschiemer.de" -f "$private_key" -N ""
log "SSH key pair generated:"
log "Private key: $private_key"
log "Public key: $public_key"
echo -e "\n${YELLOW}📋 IMPORTANT: Add the following public key to your deployment servers:${NC}\n"
cat "$public_key"
echo -e "\n${YELLOW}Copy this key to ~/.ssh/authorized_keys on your deployment servers${NC}"
if [ "$SKIP_PROMPTS" = false ]; then
echo
read -p "Press Enter when you have added the public key to your servers..."
fi
else
debug "SSH key already exists: $private_key"
log "Using existing SSH key: $private_key"
fi
# Add to SSH agent if running
if pgrep -x "ssh-agent" > /dev/null; then
log "Adding SSH key to agent"
ssh-add "$private_key" 2>/dev/null || debug "Key may already be in agent"
fi
success "SSH key setup completed"
}
# Test deployment environment
test_environment() {
section "TESTING DEPLOYMENT ENVIRONMENT"
log "Running environment validation tests"
# Test Docker
log "Testing Docker functionality"
if docker run --rm hello-world >/dev/null 2>&1; then
log "✓ Docker test passed"
else
warn "Docker test failed - you may need to start Docker or check permissions"
fi
# Test Docker Compose
log "Testing Docker Compose functionality"
cd "$PROJECT_ROOT"
if docker-compose config >/dev/null 2>&1; then
log "✓ Docker Compose configuration valid"
else
warn "Docker Compose configuration test failed"
fi
# Test Ansible
log "Testing Ansible functionality"
if ansible --version >/dev/null 2>&1; then
log "✓ Ansible test passed"
else
warn "Ansible test failed"
fi
# Test project structure
log "Validating project structure"
local required_files=(
"docker-compose.yml"
"deployment/deploy.sh"
"deployment/Makefile"
"deployment/applications/docker-compose.production.yml"
"deployment/infrastructure/site.yml"
)
local missing_files=()
for file in "${required_files[@]}"; do
if [[ ! -f "${PROJECT_ROOT}/${file}" ]]; then
missing_files+=("$file")
fi
done
if [ ${#missing_files[@]} -eq 0 ]; then
log "✓ All required project files found"
else
warn "Missing files:"
for file in "${missing_files[@]}"; do
warn " - $file"
done
fi
success "Environment testing completed"
}
# Show setup summary
show_setup_summary() {
section "SETUP SUMMARY"
cat << EOF
${WHITE}🎉 Custom PHP Framework Deployment Setup Complete! 🎉${NC}
${CYAN}What was configured:${NC}
EOF
if [ "$INSTALL_DEPENDENCIES" = true ]; then
echo "• ✅ Dependencies installed (Docker, Ansible, etc.)"
fi
if [ "$SETUP_CONFIGS" = true ]; then
echo "• ✅ Configuration files created from templates"
fi
if [ "$GENERATE_KEYS" = true ]; then
echo "• ✅ SSH keys generated for deployment"
fi
cat << EOF
${CYAN}Next Steps:${NC}
1. Review and customize environment configurations:
${YELLOW}• deployment/applications/environments/.env.development${NC}
${YELLOW}• deployment/applications/environments/.env.staging${NC}
${YELLOW}• deployment/applications/environments/.env.production${NC}
2. Configure your deployment servers:
${YELLOW}• Add your SSH public key to authorized_keys${NC}
${YELLOW}• Update Ansible inventory files if needed${NC}
3. Test your deployment:
${YELLOW}make deploy-dry ENV=development${NC}
4. Deploy to staging when ready:
${YELLOW}make deploy-staging${NC}
${CYAN}Useful Commands:${NC}
• ${YELLOW}make help${NC} # Show all available commands
• ${YELLOW}make status ENV=staging${NC} # Check deployment status
• ${YELLOW}make deploy-dry ENV=production${NC} # Test production deployment
• ${YELLOW}make info${NC} # Show deployment information
${GREEN}🌟 Your Custom PHP Framework deployment system is ready!${NC}
${CYAN}Domain: michaelschiemer.de | Email: kontakt@michaelschiemer.de | PHP: 8.4${NC}
EOF
}
# Error handling
cleanup() {
local exit_code=$?
if [ $exit_code -ne 0 ]; then
error "Setup failed with exit code: $exit_code"
echo
echo -e "${RED}Troubleshooting Tips:${NC}"
echo "• Check the error messages above for specific issues"
echo "• Ensure you have sufficient permissions"
echo "• Try running individual setup steps manually"
echo "• Check the deployment documentation"
echo "• Use --verbose flag for more detailed output"
fi
}
trap cleanup EXIT
# Main setup function
main() {
log "Starting Custom PHP Framework deployment setup"
detect_os
check_root
# Setup steps
install_dependencies
verify_dependencies
setup_configuration
generate_ssh_keys
test_environment
# Summary
show_setup_summary
success "Deployment setup completed successfully!"
}
# Script execution
parse_arguments "$@"
main