#!/usr/bin/env bash # Create all missing ChainID 138 containers on ml110 (Proxmox host) # This script creates 13 containers: 7 Besu nodes, 5 Hyperledger services, 1 Explorer set -euo pipefail # Load IP configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true PROXMOX_HOST="${PROXMOX_HOST:-${PROXMOX_HOST_ML110:-192.168.11.10}}" STORAGE="${STORAGE:-local-lvm}" # Template format: local:vztmpl/template-name or just template-name TEMPLATE="${TEMPLATE:-local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst}" NETWORK="${NETWORK:-vmbr0}" GATEWAY="${GATEWAY:-${NETWORK_GATEWAY:-192.168.11.1}}" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # Check SSH access check_ssh_access() { log_info "Checking SSH access to $PROXMOX_HOST..." if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} "echo 'SSH OK'" &>/dev/null; then log_success "SSH access confirmed" return 0 else log_error "Cannot access $PROXMOX_HOST via SSH" log_error "Please ensure:" log_error " 1. SSH key is set up" log_error " 2. Host is reachable" log_error " 3. Root access is available" return 1 fi } # Check if container exists container_exists() { local vmid=$1 ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} \ "pct list | grep -q '^$vmid ' && echo 'exists' || echo 'missing'" 2>/dev/null || echo "error" } # Create a container create_container() { local vmid=$1 local hostname=$2 local ip=$3 local memory=$4 local cores=$5 local disk=$6 local description="$7" log_info "Creating container $vmid: $hostname ($ip)..." # Check if already exists local exists=$(container_exists "$vmid") if [[ "$exists" == "exists" ]]; then log_warn "Container $vmid already exists, skipping..." return 0 fi # Create container log_info " Memory: ${memory}GB, CPU: ${cores} cores, Disk: ${disk}GB" $DRY_RUN && { log_info " [DRY-RUN] Would create container $vmid"; return 0; } ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} </dev/null | awk '{print \$2}'" || echo "unknown") if [[ "$status" == "running" ]]; then log_success " Container $vmid is running" else log_warn " Container $vmid status: $status" fi return 0 else log_error "Failed to create container $vmid" return 1 fi } # Dry-run: show what would be created without executing DRY_RUN=false [[ "${1:-}" == "--dry-run" ]] && DRY_RUN=true # Main execution main() { echo "" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "ChainID 138 Container Creation Script" $DRY_RUN && log_info "[DRY-RUN] No containers will be created" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" log_info "Target: $PROXMOX_HOST" log_info "Storage: $STORAGE" log_info "Template: $TEMPLATE" echo "" # Check SSH access (skip in dry-run) if ! $DRY_RUN && ! check_ssh_access; then exit 1 fi echo "" log_info "This will create 13 containers:" log_info " • 7 Besu nodes (1 sentry + 6 RPC)" log_info " • 5 Hyperledger services" log_info " • 1 Explorer" echo "" # Check for non-interactive mode (or dry-run) if [[ "${NON_INTERACTIVE:-}" == "1" ]] || $DRY_RUN || [[ ! -t 0 ]]; then log_info "Proceeding automatically" else read -p "Continue? (y/N): " -n 1 -r echo "" if [[ ! $REPLY =~ ^[Yy]$ ]]; then log_info "Creation cancelled" exit 0 fi fi local success_count=0 local fail_count=0 local skip_count=0 echo "" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "Creating Besu Nodes" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" # 1. Besu Sentry Node if create_container 1504 "besu-sentry-5" "${IP_BESU_SENTRY:-${IP_BESU_SENTRY:-192.168.11.154}}" 4 2 100 "Besu Sentry Node for ChainID 138 - Ali's dedicated host"; then success_count=$((success_count + 1)) else fail_count=$((fail_count + 1)) fi echo "" # 2-7. Besu RPC Nodes declare -A RPC_NODES=( [2503]="besu-rpc-4:${RPC_ALI_1_ALT:-${RPC_ALI_1_ALT:-${RPC_ALI_1_ALT:-192.168.11.253}}}:Ali RPC (0x8a identity)" [2504]="besu-rpc-4:${RPC_ALI_2_ALT:-${RPC_ALI_2_ALT:-${RPC_ALI_2_ALT:-192.168.11.254}}}:Ali RPC (0x1 identity)" [2505]="besu-rpc-luis:${RPC_LUIS_1:-${RPC_LUIS_1:-${RPC_LUIS_1:-192.168.11.255}}}:Luis RPC (0x8a identity)" [2506]="besu-rpc-luis:${RPC_LUIS_2:-192.168.11.202}:Luis RPC (0x1 identity)" [2507]="besu-rpc-putu:${RPC_PUTU_1:-192.168.11.203}:Putu RPC (0x8a identity)" [2508]="besu-rpc-putu:${RPC_PUTU_2:-192.168.11.204}:Putu RPC (0x1 identity)" ) for vmid in "${!RPC_NODES[@]}"; do IFS=':' read -r hostname ip description <<< "${RPC_NODES[$vmid]}" local exists=$(container_exists "$vmid") if [[ "$exists" == "exists" ]]; then log_warn "Container $vmid already exists, skipping..." skip_count=$((skip_count + 1)) elif create_container "$vmid" "$hostname" "$ip" 16 4 200 "Besu RPC Node - $description"; then success_count=$((success_count + 1)) else fail_count=$((fail_count + 1)) fi echo "" done log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "Creating Hyperledger Services" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" # 8-9. Firefly if create_container 6200 "firefly-1" "${IP_FIREFLY:-192.168.11.66}" 4 2 50 "Hyperledger Firefly Core"; then success_count=$((success_count + 1)) else fail_count=$((fail_count + 1)) fi echo "" if create_container 6201 "firefly-2" "${IP_FIREFLY_2:-192.168.11.67}" 4 2 50 "Hyperledger Firefly Node for ChainID 138 - Ali's dedicated host"; then success_count=$((success_count + 1)) else fail_count=$((fail_count + 1)) fi echo "" # 10. Cacti if create_container 5200 "cacti-1" "${IP_CACTI:-${IP_CACTI:-192.168.11.64}}" 4 2 50 "Hyperledger Cacti Interop Middleware"; then success_count=$((success_count + 1)) else fail_count=$((fail_count + 1)) fi echo "" # 11. Fabric if create_container 6000 "fabric-1" "${IP_FABRIC:-${IP_FABRIC:-192.168.11.65}}" 8 4 100 "Hyperledger Fabric Enterprise Contracts"; then success_count=$((success_count + 1)) else fail_count=$((fail_count + 1)) fi echo "" # 12. Indy if create_container 6400 "indy-1" "${IP_INDY:-${IP_INDY:-192.168.11.68}}" 8 4 100 "Hyperledger Indy Identity Layer"; then success_count=$((success_count + 1)) else fail_count=$((fail_count + 1)) fi echo "" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "Creating Explorer" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" # 13. Blockscout (IP TBD - using placeholder) if create_container 5000 "blockscout-1" "${IP_BLOCKSCOUT:-192.168.11.69}" 8 4 200 "Blockscout Explorer for ChainID 138"; then success_count=$((success_count + 1)) else fail_count=$((fail_count + 1)) fi echo "" # Summary echo "" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log_info "Creation Summary" log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" log_success "Successfully created: $success_count containers" if [ $skip_count -gt 0 ]; then log_warn "Skipped (already exist): $skip_count containers" fi if [ $fail_count -gt 0 ]; then log_error "Failed: $fail_count containers" fi echo "" if [ $success_count -gt 0 ] || [ $skip_count -gt 0 ]; then log_info "Next steps:" log_info " 1. Run: ./scripts/deploy-all-chain138-containers.sh" log_info " 2. Verify: ./scripts/verify-chain138-config.sh" log_info " 3. Set up JWT authentication (automated in deployment script)" fi echo "" } main "$@"