#!/bin/bash # Calejo Control Adapter - One-Click Server Setup Script # Automatically reads from existing deployment configuration files set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Default configuration ENVIRONMENT="production" SERVER_HOST="" SSH_USERNAME="" SSH_KEY_FILE="" DRY_RUN=false VERBOSE=false # Function to print colored output print_status() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # Function to display usage usage() { echo "Calejo Control Adapter - One-Click Server Setup" echo "==================================================" echo "" echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" echo " -e, --environment Deployment environment (production, staging) [default: auto-detect]" echo " -h, --host Server hostname or IP address [default: auto-detect]" echo " -u, --user SSH username [default: auto-detect]" echo " -k, --key SSH private key file [default: auto-detect]" echo " --verbose Enable verbose output" echo " --dry-run Show what would be done without making changes" echo " --help Show this help message" echo "" echo "Examples:" echo " $0 # Auto-detect and setup using existing config" echo " $0 --dry-run # Show setup steps without executing" echo " $0 -h custom-server.com # Override host from config" echo "" } # Function to read deployment configuration from existing files read_deployment_config() { local config_dir="deploy" print_status "Reading existing deployment configuration..." # Read from production.yml if it exists if [[ -f "$config_dir/config/production.yml" ]]; then print_status "Found production configuration: $config_dir/config/production.yml" # Extract values from production.yml if [[ -z "$SSH_HOST" ]]; then SSH_HOST=$(grep -E "^\s*host:\s*" "$config_dir/config/production.yml" | head -1 | sed 's/^[[:space:]]*host:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r') [[ -n "$SSH_HOST" ]] && print_status " Host: $SSH_HOST" fi if [[ -z "$SSH_USERNAME" ]]; then SSH_USERNAME=$(grep -E "^\s*username:\s*" "$config_dir/config/production.yml" | head -1 | sed 's/^[[:space:]]*username:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r') [[ -n "$SSH_USERNAME" ]] && print_status " Username: $SSH_USERNAME" fi if [[ -z "$SSH_KEY_FILE" ]]; then SSH_KEY_FILE=$(grep -E "^\s*key_file:\s*" "$config_dir/config/production.yml" | head -1 | sed 's/^[[:space:]]*key_file:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r') [[ -n "$SSH_KEY_FILE" ]] && print_status " Key file: $SSH_KEY_FILE" fi fi # Read from staging.yml if it exists if [[ -f "$config_dir/config/staging.yml" ]]; then print_status "Found staging configuration: $config_dir/config/staging.yml" # Only use staging config if environment is staging if [[ "$ENVIRONMENT" == "staging" ]]; then if [[ -z "$SSH_HOST" ]]; then SSH_HOST=$(grep -E "^\s*host:\s*" "$config_dir/config/staging.yml" | head -1 | sed 's/^[[:space:]]*host:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r') [[ -n "$SSH_HOST" ]] && print_status " Host: $SSH_HOST" fi fi fi # Check for existing remote deployment script configuration if [[ -f "$config_dir/ssh/deploy-remote.sh" ]]; then print_status "Found remote deployment script: $config_dir/ssh/deploy-remote.sh" # Extract default values from deploy-remote.sh if [[ -z "$SSH_HOST" ]]; then SSH_HOST=$(grep -E "SSH_HOST=" "$config_dir/ssh/deploy-remote.sh" | head -1 | cut -d'=' -f2 | tr -d '\"' | tr -d "\'") [[ -n "$SSH_HOST" ]] && print_status " Host from script: $SSH_HOST" fi if [[ -z "$SSH_USERNAME" ]]; then SSH_USERNAME=$(grep -E "SSH_USER=" "$config_dir/ssh/deploy-remote.sh" | head -1 | cut -d'=' -f2 | tr -d '\"' | tr -d "\'") [[ -n "$SSH_USERNAME" ]] && print_status " Username from script: $SSH_USERNAME" fi if [[ -z "$SSH_KEY_FILE" ]]; then SSH_KEY_FILE=$(grep -E "SSH_KEY=" "$config_dir/ssh/deploy-remote.sh" | head -1 | cut -d'=' -f2 | tr -d '\"' | tr -d "\'") [[ -n "$SSH_KEY_FILE" ]] && print_status " Key file from script: $SSH_KEY_FILE" fi fi # Set defaults if still empty ENVIRONMENT=${ENVIRONMENT:-production} SSH_HOST=${SSH_HOST:-localhost} SSH_USERNAME=${SSH_USERNAME:-$USER} SSH_KEY_FILE=${SSH_KEY_FILE:-~/.ssh/id_rsa} # Use SSH_HOST as SERVER_HOST if not specified SERVER_HOST=${SERVER_HOST:-$SSH_HOST} print_success "Configuration loaded successfully" } # Function to parse command line arguments parse_arguments() { while [[ $# -gt 0 ]]; do case $1 in -e|--environment) ENVIRONMENT="$2" shift 2 ;; -h|--host) SERVER_HOST="$2" shift 2 ;; -u|--user) SSH_USERNAME="$2" shift 2 ;; -k|--key) SSH_KEY_FILE="$2" shift 2 ;; --verbose) VERBOSE=true shift ;; --dry-run) DRY_RUN=true shift ;; --help) usage exit 0 ;; *) print_error "Unknown option: $1" usage exit 1 ;; esac done } # Function to detect if running locally or needs remote setup detect_deployment_type() { if [[ -n "$SERVER_HOST" && "$SERVER_HOST" != "localhost" && "$SERVER_HOST" != "127.0.0.1" ]]; then echo "remote" else echo "local" fi } # Function to check prerequisites check_prerequisites() { print_status "Checking prerequisites..." if [[ "$DRY_RUN" == "true" ]]; then echo " [DRY RUN] Would check prerequisites" return 0 fi # For local deployment, check local Docker if [[ "$DEPLOYMENT_TYPE" == "local" ]]; then # Check Docker if ! command -v docker &> /dev/null; then print_error "Docker is not installed" echo "Please install Docker first: https://docs.docker.com/get-docker/" exit 1 fi # Check Docker Compose if ! command -v docker-compose &> /dev/null; then print_error "Docker Compose is not installed" echo "Please install Docker Compose first: https://docs.docker.com/compose/install/" exit 1 fi fi # For remote deployment, we'll handle Docker installation automatically if [[ "$DEPLOYMENT_TYPE" == "remote" ]]; then print_status "Remote deployment - Docker will be installed automatically if needed" fi print_success "Prerequisites check passed" } # Function to setup local deployment setup_local_deployment() { print_status "Setting up local deployment..." if [[ "$DRY_RUN" == "true" ]]; then echo " [DRY RUN] Would setup local deployment" return 0 fi # Create necessary directories mkdir -p ./data/postgres ./logs ./certs # Generate default configuration if not exists if [[ ! -f ".env" ]]; then print_status "Creating default configuration..." cp config/.env.example .env print_success "Default configuration created" fi # Build and start services print_status "Building and starting services..." docker-compose up --build -d print_success "Local deployment completed" } # Function to install Docker on remote server install_docker_remote() { local host="$1" local user="$2" local key_file="$3" print_status "Installing Docker on remote server $host..." if [[ "$DRY_RUN" == "true" ]]; then echo " [DRY RUN] Would install Docker on $host" return 0 fi # Check if Docker is already installed if ssh -o StrictHostKeyChecking=no -i "$key_file" "$user@$host" "command -v docker" &> /dev/null; then print_success "Docker is already installed" return 0 fi # Install Docker using official script print_status "Installing Docker using official script..." ssh -o StrictHostKeyChecking=no -i "$key_file" "$user@$host" \ "curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh" # Add user to docker group print_status "Adding user to docker group..." ssh -o StrictHostKeyChecking=no -i "$key_file" "$user@$host" \ "usermod -aG docker $user" # Install Docker Compose print_status "Installing Docker Compose..." ssh -o StrictHostKeyChecking=no -i "$key_file" "$user@$host" \ "curl -L \"https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose" # Verify installation if ssh -o StrictHostKeyChecking=no -i "$key_file" "$user@$host" "docker --version && docker-compose --version"; then print_success "Docker and Docker Compose installed successfully" return 0 else print_error "Docker installation failed" return 1 fi } # Function to setup remote deployment setup_remote_deployment() { print_status "Setting up remote deployment on $SERVER_HOST..." if [[ "$DRY_RUN" == "true" ]]; then echo " [DRY RUN] Would setup remote deployment on $SERVER_HOST" return 0 fi # Install Docker if needed if ! ssh -o StrictHostKeyChecking=no -i "$SSH_KEY_FILE" "$SSH_USERNAME@$SERVER_HOST" "command -v docker" &> /dev/null; then install_docker_remote "$SERVER_HOST" "$SSH_USERNAME" "$SSH_KEY_FILE" fi # Use existing deployment script if [[ -f "deploy/ssh/deploy-remote.sh" ]]; then print_status "Using existing remote deployment script..." ./deploy/ssh/deploy-remote.sh -e "$ENVIRONMENT" else print_error "Remote deployment script not found" return 1 fi print_success "Remote deployment completed" } # Function to validate setup validate_setup() { local host="$1" print_status "Validating setup..." if [[ "$DRY_RUN" == "true" ]]; then echo " [DRY RUN] Would validate setup" return 0 fi # Test health endpoint if curl -s "http://$host:8080/health" > /dev/null; then print_success "Health check passed" else print_warning "Health check failed - service may still be starting" fi return 0 } # Function to display setup completion message display_completion_message() { local deployment_type="$1" local host="$2" echo "" echo "==================================================" echo " SETUP COMPLETED SUCCESSFULLY!" echo "==================================================" echo "" echo "🎉 Calejo Control Adapter is now running!" echo "" echo "🌍 Access URLs:" echo " Dashboard: http://$host:8080/dashboard" echo " REST API: http://$host:8080" echo " Health Check: http://$host:8080/health" echo "" echo "🔧 Next Steps:" echo " 1. Open the dashboard in your browser" echo " 2. Configure your SCADA systems and hardware" echo " 3. Set up safety limits and user accounts" echo " 4. Integrate with your existing infrastructure" echo "" if [[ "$deployment_type" == "local" ]]; then echo "💡 Local Development Tips:" echo " - View logs: docker-compose logs -f" echo " - Stop services: docker-compose down" echo " - Restart: docker-compose up -d" else echo "💡 Remote Server Tips:" echo " - View logs: ssh -i $SSH_KEY_FILE $SSH_USERNAME@$host 'cd /opt/calejo-control-adapter && docker-compose logs -f'" echo " - Stop services: ssh -i $SSH_KEY_FILE $SSH_USERNAME@$host 'cd /opt/calejo-control-adapter && docker-compose down'" echo " - Restart: ssh -i $SSH_KEY_FILE $SSH_USERNAME@$host 'cd /opt/calejo-control-adapter && docker-compose up -d'" fi echo "" echo "==================================================" echo "" } # Main setup function main() { echo "" echo "🚀 Calejo Control Adapter - One-Click Server Setup" echo "==================================================" echo "" # Parse command line arguments parse_arguments "$@" # Read deployment configuration from files read_deployment_config # Detect deployment type local deployment_type=$(detect_deployment_type) # Display setup information echo "Setup Configuration:" echo " Environment: $ENVIRONMENT" echo " Deployment: $deployment_type" if [[ "$deployment_type" == "remote" ]]; then echo " Server: $SERVER_HOST" echo " User: $SSH_USERNAME" else echo " Server: localhost" fi if [[ "$DRY_RUN" == "true" ]]; then echo " Mode: DRY RUN" fi echo "" # Check prerequisites check_prerequisites # Perform deployment if [[ "$deployment_type" == "local" ]]; then setup_local_deployment local final_host="localhost" else setup_remote_deployment local final_host="$SERVER_HOST" fi # Validate setup validate_setup "$final_host" # Display completion message display_completion_message "$deployment_type" "$final_host" echo "" print_success "One-click setup completed!" echo "" } # Run main function main "$@"