#!/usr/bin/env bash # Complete All Incomplete Tasks in Parallel Execution Mode # This script executes all pending tasks in parallel for maximum efficiency set -uo pipefail NODE_IP="${PROXMOX_HOST_R630_01}" MAX_PARALLEL=10 # Maximum parallel operations LOG_DIR="/tmp/parallel-tasks-$(date +%Y%m%d-%H%M%S)" mkdir -p "$LOG_DIR" # Color output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } echo "═══════════════════════════════════════════════════════════" echo "Complete All Tasks - Parallel Execution Mode" echo "═══════════════════════════════════════════════════════════" echo "Log Directory: $LOG_DIR" echo "Max Parallel: $MAX_PARALLEL" echo "" # Task tracking declare -A TASK_STATUS declare -A TASK_PIDS TOTAL_TASKS=0 COMPLETED_TASKS=0 FAILED_TASKS=0 # Function to run task in background and track it run_parallel_task() { local task_id="$1" local task_name="$2" local task_command="$3" log_info "Starting task: $task_name (ID: $task_id)" ( eval "$task_command" > "$LOG_DIR/${task_id}.log" 2>&1 local exit_code=$? if [ $exit_code -eq 0 ]; then echo "SUCCESS" > "$LOG_DIR/${task_id}.status" log_info "✓ Completed: $task_name" else echo "FAILED" > "$LOG_DIR/${task_id}.status" log_error "✗ Failed: $task_name (see $LOG_DIR/${task_id}.log)" fi exit $exit_code ) & TASK_PIDS[$task_id]=$! TASK_STATUS[$task_id]="running" ((TOTAL_TASKS++)) } # Function to wait for parallel tasks with limit wait_for_slot() { while [ ${#TASK_PIDS[@]} -ge $MAX_PARALLEL ]; do for task_id in "${!TASK_PIDS[@]}"; do if ! kill -0 ${TASK_PIDS[$task_id]} 2>/dev/null; then wait ${TASK_PIDS[$task_id]} exit_code=$? if [ -f "$LOG_DIR/${task_id}.status" ]; then status=$(cat "$LOG_DIR/${task_id}.status") if [ "$status" = "SUCCESS" ]; then ((COMPLETED_TASKS++)) else ((FAILED_TASKS++)) fi fi unset TASK_PIDS[$task_id] TASK_STATUS[$task_id]="completed" fi done sleep 0.5 done } # Function to wait for all tasks wait_all_tasks() { log_info "Waiting for all tasks to complete..." for task_id in "${!TASK_PIDS[@]}"; do wait ${TASK_PIDS[$task_id]} exit_code=$? if [ -f "$LOG_DIR/${task_id}.status" ]; then status=$(cat "$LOG_DIR/${task_id}.status") if [ "$status" = "SUCCESS" ]; then ((COMPLETED_TASKS++)) else ((FAILED_TASKS++)) fi fi done } # ============================================================================ # TASK 1: Install Database Services (PostgreSQL) # ============================================================================ install_postgresql() { local vmid="$1" local hostname="$2" log_info "Installing PostgreSQL on CT $vmid ($hostname)..." ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${NODE_IP} " pct exec $vmid -- bash -c ' export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq postgresql-15 postgresql-contrib-15 >/dev/null 2>&1 # Configure PostgreSQL sed -i \"s/#listen_addresses = .*/listen_addresses = '\''*'\''/\" /etc/postgresql/15/main/postgresql.conf systemctl enable postgresql@15-main systemctl start postgresql@15-main # Wait for PostgreSQL to start sleep 3 systemctl is-active postgresql@15-main >/dev/null && echo \"PostgreSQL installed and running\" ' " } # Install PostgreSQL on all database containers in parallel log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "TASK 1: Installing PostgreSQL (4 containers)" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" for vmid in 10000 10001 10100 10101; do wait_for_slot hostname=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${NODE_IP} \ "pct config $vmid 2>/dev/null | grep '^hostname:' | sed 's/^hostname: //'" || echo "unknown") run_parallel_task "postgres-$vmid" "PostgreSQL on CT $vmid" "install_postgresql $vmid '$hostname'" done # ============================================================================ # TASK 2: Install Redis # ============================================================================ install_redis() { local vmid="$1" local hostname="$2" log_info "Installing Redis on CT $vmid ($hostname)..." ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${NODE_IP} " pct exec $vmid -- bash -c ' export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq redis-server >/dev/null 2>&1 # Configure Redis to listen on all interfaces sed -i \"s/^bind .*/bind 0.0.0.0/\" /etc/redis/redis.conf systemctl enable redis-server systemctl restart redis-server sleep 2 systemctl is-active redis-server >/dev/null && echo \"Redis installed and running\" ' " } log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "TASK 2: Installing Redis (2 containers)" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" for vmid in 10020 10120; do wait_for_slot hostname=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${NODE_IP} \ "pct config $vmid 2>/dev/null | grep '^hostname:' | sed 's/^hostname: //'" || echo "unknown") run_parallel_task "redis-$vmid" "Redis on CT $vmid" "install_redis $vmid '$hostname'" done # ============================================================================ # TASK 3: Install Node.js Runtime # ============================================================================ install_nodejs() { local vmid="$1" local hostname="$2" log_info "Installing Node.js on CT $vmid ($hostname)..." ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${NODE_IP} " pct exec $vmid -- bash -c ' export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq curl ca-certificates gnupg >/dev/null 2>&1 # Install Node.js 18.x curl -fsSL https://deb.nodesource.com/setup_18.x | bash - >/dev/null 2>&1 apt-get install -y -qq nodejs >/dev/null 2>&1 # Install PM2 globally npm install -g pm2 >/dev/null 2>&1 node --version && npm --version && pm2 --version && echo \"Node.js installed\" ' " } log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "TASK 3: Installing Node.js (14 containers)" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" for vmid in 10030 10040 10050 10060 10070 10080 10090 10091 10092 10130 10150 10151; do wait_for_slot hostname=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${NODE_IP} \ "pct config $vmid 2>/dev/null | grep '^hostname:' | sed 's/^hostname: //'" || echo "unknown") run_parallel_task "nodejs-$vmid" "Node.js on CT $vmid" "install_nodejs $vmid '$hostname'" done # Wait for database and Node.js installations to complete wait_all_tasks log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "Phase 1 Complete: Database and Runtime Installation" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "Completed: $COMPLETED_TASKS / Failed: $FAILED_TASKS / Total: $TOTAL_TASKS" echo "" # ============================================================================ # TASK 4: Configure PostgreSQL Databases # ============================================================================ configure_postgresql_order() { local vmid="$1" ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${NODE_IP} " pct exec $vmid -- bash -c ' sudo -u postgres psql << \"EOF\" CREATE DATABASE order_db; CREATE USER order_user WITH PASSWORD '\''order_password'\''; GRANT ALL PRIVILEGES ON DATABASE order_db TO order_user; ALTER DATABASE order_db OWNER TO order_user; EOF echo \"Order database configured\" ' " } configure_postgresql_dbis() { local vmid="$1" ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${NODE_IP} " pct exec $vmid -- bash -c ' sudo -u postgres psql << \"EOF\" CREATE DATABASE dbis_core; CREATE USER dbis WITH PASSWORD '\''8cba649443f97436db43b34ab2c0e75b5cf15611bef9c099cee6fb22cc3d7771'\''; GRANT ALL PRIVILEGES ON DATABASE dbis_core TO dbis; ALTER DATABASE dbis_core OWNER TO dbis; EOF echo \"DBIS database configured\" ' " } log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "TASK 4: Configuring PostgreSQL Databases" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" for vmid in 10000 10001; do wait_for_slot run_parallel_task "pg-config-order-$vmid" "Configure Order DB on CT $vmid" "configure_postgresql_order $vmid" done for vmid in 10100 10101; do wait_for_slot run_parallel_task "pg-config-dbis-$vmid" "Configure DBIS DB on CT $vmid" "configure_postgresql_dbis $vmid" done wait_all_tasks # ============================================================================ # TASK 5: Update Application Configurations with New IPs # ============================================================================ update_config_ips() { local vmid="$1" local old_ip="$2" local new_ip="$3" ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${NODE_IP} " pct exec $vmid -- bash -c ' # Find and update .env files find /opt /home /root -name \".env\" -type f 2>/dev/null | while read envfile; do if [ -f \"\$envfile\" ] && [ -r \"\$envfile\" ]; then sed -i \"s|$old_ip|$new_ip|g\" \"\$envfile\" 2>/dev/null fi done # Find and update config files find /opt /home /root -name \"*.config.*\" -o -name \"*config*.json\" -o -name \"*config*.yaml\" -o -name \"*config*.yml\" 2>/dev/null | while read configfile; do if [ -f \"\$configfile\" ] && [ -r \"\$configfile\" ]; then sed -i \"s|$old_ip|$new_ip|g\" \"\$configfile\" 2>/dev/null fi done echo \"Configuration updated for CT $vmid\" ' " } log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "TASK 5: Updating Application Configurations" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" # Update Order service configs (old VLAN 200 IPs to new VLAN 11 IPs) declare -A ip_mappings=( ["10.200.0.10"]="${ORDER_POSTGRES_PRIMARY:-${ORDER_POSTGRES_PRIMARY:-192.168.11.44}}" # order-postgres-primary ["10.200.0.11"]="${ORDER_POSTGRES_REPLICA:-${ORDER_POSTGRES_REPLICA:-192.168.11.45}}" # order-postgres-replica ["10.200.0.20"]="${ORDER_REDIS_IP:-192.168.11.38}" # order-redis ["10.200.0.30"]="${IP_SERVICE_40:-${IP_SERVICE_40:-${IP_SERVICE_40:-192.168.11.40}}}" # order-identity ["10.200.0.40"]="${IP_SERVICE_41:-${IP_SERVICE_41:-${IP_SERVICE_41:-192.168.11.41}}}" # order-intake ["10.200.0.50"]="${IP_SERVICE_49:-${IP_SERVICE_49:-${IP_SERVICE_49:-192.168.11.49}}}" # order-finance ["10.200.0.60"]="${IP_SERVICE_42:-${IP_SERVICE_42:-${IP_SERVICE_42:-192.168.11.42}}}" # order-dataroom ["10.200.0.70"]="${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-192.168.11.50}}}}}}" # order-legal ["10.200.0.80"]="${IP_SERVICE_43:-${IP_SERVICE_43:-${IP_SERVICE_43:-192.168.11.43}}}" # order-eresidency ["10.200.0.90"]="${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-${IP_SERVICE_36:-192.168.11.36}}}}}}" # order-portal-public ["10.200.0.91"]="${IP_SERVICE_35:-${IP_SERVICE_35:-${IP_SERVICE_35:-${IP_SERVICE_35:-${IP_SERVICE_35:-${IP_SERVICE_35:-192.168.11.35}}}}}}" # order-portal-internal ["10.200.0.92"]="${IP_MIM_WEB:-192.168.11.37}" # order-mcp-legal ["10.200.0.200"]="${ORDER_REDIS_REPLICA:-${ORDER_REDIS_REPLICA:-${ORDER_REDIS_REPLICA:-192.168.11.46}}}" # order-prometheus ["10.200.0.201"]="${IP_SERVICE_47:-${IP_SERVICE_47:-${IP_SERVICE_47:-192.168.11.47}}}" # order-grafana ["10.200.0.202"]="${IP_ORDER_OPENSEARCH:-${IP_ORDER_OPENSEARCH:-${IP_ORDER_OPENSEARCH:-192.168.11.48}}}" # order-opensearch ["10.200.0.210"]="${IP_ORDER_HAPROXY:-${IP_ORDER_HAPROXY:-192.168.11.39}}" # order-haproxy ["10.200.0.230"]="${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-192.168.11.51}}}}}}" # order-vault ) for old_ip in "${!ip_mappings[@]}"; do new_ip="${ip_mappings[$old_ip]}" # Find which container has this new IP for vmid in 10000 10001 10020 10030 10040 10050 10060 10070 10080 10090 10091 10092 10200 10201 10202 10210 10230; do wait_for_slot run_parallel_task "update-config-$vmid" "Update IPs in CT $vmid" "update_config_ips $vmid '$old_ip' '$new_ip'" done done wait_all_tasks # ============================================================================ # TASK 6: Install Monitoring Services # ============================================================================ install_prometheus() { local vmid="$1" ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${NODE_IP} " pct exec $vmid -- bash -c ' export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq prometheus >/dev/null 2>&1 systemctl enable prometheus systemctl start prometheus sleep 2 systemctl is-active prometheus >/dev/null && echo \"Prometheus installed\" ' " } install_grafana() { local vmid="$1" ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${NODE_IP} " pct exec $vmid -- bash -c ' export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq apt-transport-https software-properties-common wget >/dev/null 2>&1 wget -q -O - https://packages.grafana.com/gpg.key | apt-key add - echo \"deb https://packages.grafana.com/oss/deb stable main\" > /etc/apt/sources.list.d/grafana.list apt-get update -qq apt-get install -y -qq grafana >/dev/null 2>&1 systemctl enable grafana-server systemctl start grafana-server sleep 2 systemctl is-active grafana-server >/dev/null && echo \"Grafana installed\" ' " } log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "TASK 6: Installing Monitoring Services" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" wait_for_slot run_parallel_task "prometheus-10200" "Install Prometheus" "install_prometheus 10200" wait_for_slot run_parallel_task "grafana-10201" "Install Grafana" "install_grafana 10201" wait_all_tasks # ============================================================================ # TASK 7: Install Infrastructure Services # ============================================================================ install_haproxy() { local vmid="$1" ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${NODE_IP} " pct exec $vmid -- bash -c ' export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq haproxy >/dev/null 2>&1 systemctl enable haproxy systemctl start haproxy sleep 2 systemctl is-active haproxy >/dev/null && echo \"HAProxy installed\" ' " } install_vault() { local vmid="$1" ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${NODE_IP} " pct exec $vmid -- bash -c ' export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq curl unzip >/dev/null 2>&1 VAULT_VERSION=\"1.15.0\" wget -q https://releases.hashicorp.com/vault/\${VAULT_VERSION}/vault_\${VAULT_VERSION}_linux_amd64.zip unzip -q vault_\${VAULT_VERSION}_linux_amd64.zip mv vault /usr/local/bin/ chmod +x /usr/local/bin/vault # Create systemd service cat > /etc/systemd/system/vault.service << \"EOF\" [Unit] Description=HashiCorp Vault After=network.target [Service] Type=simple User=vault Group=vault ExecStart=/usr/local/bin/vault server -config=/etc/vault.d/vault.hcl Restart=on-failure [Install] WantedBy=multi-user.target EOF useradd -r -s /bin/false vault mkdir -p /etc/vault.d /var/lib/vault chown vault:vault /var/lib/vault echo \"Vault installed\" ' " } log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "TASK 7: Installing Infrastructure Services" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" wait_for_slot run_parallel_task "haproxy-10210" "Install HAProxy" "install_haproxy 10210" wait_for_slot run_parallel_task "vault-10230" "Install Vault" "install_vault 10230" wait_all_tasks # ============================================================================ # Final Summary # ============================================================================ log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "PARALLEL EXECUTION COMPLETE" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "Total Tasks: $TOTAL_TASKS" log_info "Completed: $COMPLETED_TASKS" log_info "Failed: $FAILED_TASKS" log_info "Success Rate: $(( COMPLETED_TASKS * 100 / TOTAL_TASKS ))%" log_info "" log_info "Logs: $LOG_DIR" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" if [ $FAILED_TASKS -eq 0 ]; then log_info "✅ ALL TASKS COMPLETED SUCCESSFULLY" exit 0 else log_error "⚠️ SOME TASKS FAILED - Review logs in $LOG_DIR" exit 1 fi