Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
- ADD_CHAIN138_TO_LEDGER_LIVE: Ledger form done; public code review repo bis-innovations/LedgerLive; init/push commands - CONTRACT_DEPLOYMENT_RUNBOOK: Chain 138 gas price 1 gwei, 36-addr check, TransactionMirror workaround - CONTRACT_*: AddressMapper, MirrorManager deployed 2026-02-12; 36-address on-chain check - NEXT_STEPS_FOR_YOU: Ledger done; steps completable now (no LAN); run-completable-tasks-from-anywhere - MASTER_INDEX, OPERATOR_OPTIONAL, SMART_CONTRACTS_INVENTORY_SIMPLE: updates - LEDGER_BLOCKCHAIN_INTEGRATION_COMPLETE: bis-innovations/LedgerLive reference Co-authored-by: Cursor <cursoragent@cursor.com>
284 lines
10 KiB
Bash
Executable File
284 lines
10 KiB
Bash
Executable File
#!/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} <<CREATE_CONTAINER_EOF
|
|
set -e
|
|
pct create $vmid $TEMPLATE \
|
|
--hostname $hostname \
|
|
--memory $((memory * 1024)) \
|
|
--cores $cores \
|
|
--rootfs $STORAGE:${disk} \
|
|
--net0 name=eth0,bridge=$NETWORK,ip=$ip/24,gw=$GATEWAY \
|
|
--description "$description" \
|
|
--start 1 \
|
|
--onboot 1 \
|
|
--unprivileged 0
|
|
CREATE_CONTAINER_EOF
|
|
|
|
if [ $? -eq 0 ]; then
|
|
log_success "Container $vmid created successfully"
|
|
|
|
# Wait for container to start
|
|
log_info " Waiting for container to start..."
|
|
sleep 5
|
|
|
|
# Check status
|
|
local status=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} \
|
|
"pct status $vmid 2>/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 "$@"
|
|
|