- Organized 252 files across project - Root directory: 187 → 2 files (98.9% reduction) - Moved configuration guides to docs/04-configuration/ - Moved troubleshooting guides to docs/09-troubleshooting/ - Moved quick start guides to docs/01-getting-started/ - Moved reports to reports/ directory - Archived temporary files - Generated comprehensive reports and documentation - Created maintenance scripts and guides All files organized according to established standards.
430 lines
15 KiB
Bash
Executable File
430 lines
15 KiB
Bash
Executable File
#!/bin/bash
|
|
# Complete RPC Translator Deployment Script
|
|
# Handles SSH setup, deployment, configuration, and service startup
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[✗]${NC} $1"; }
|
|
log_section() { echo -e "${CYAN}════════════════════════════════════════${NC}"; }
|
|
|
|
# VMID configuration
|
|
declare -A VMIDS=(
|
|
["2400"]="192.168.11.240"
|
|
["2401"]="192.168.11.241"
|
|
["2402"]="192.168.11.242"
|
|
)
|
|
|
|
PROXMOX_HOST="${PROXMOX_HOST:-192.168.11.10}"
|
|
DEPLOY_DIR="/opt/rpc-translator-138"
|
|
|
|
# Function to check if we can access VMID via pct
|
|
check_pct_access() {
|
|
local vmid="$1"
|
|
local vmip="$2"
|
|
|
|
# Try to find which node has this VMID
|
|
local node=""
|
|
for n in ml110 r630-01 r630-02; do
|
|
if ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 root@"$PROXMOX_HOST" \
|
|
"pvesh get /nodes/$n/lxc/$vmid/status/current --output-format json >/dev/null 2>&1" 2>/dev/null; then
|
|
node="$n"
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ -n "$node" ]; then
|
|
echo "$node"
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
# Global variable to store deployed ports
|
|
declare -A DEPLOYED_PORTS
|
|
|
|
# Function to deploy to VMID using pct
|
|
deploy_via_pct() {
|
|
local vmid="$1"
|
|
local vmip="$2"
|
|
local node="$3"
|
|
|
|
log_info "Deploying to VMID $vmid via pct on node $node..."
|
|
|
|
# Check if dist exists, if not try to build
|
|
cd "$PROJECT_DIR"
|
|
if [ ! -d "$PROJECT_DIR/dist" ]; then
|
|
log_info "dist directory not found, building TypeScript..."
|
|
if command -v node >/dev/null 2>&1; then
|
|
if command -v pnpm >/dev/null 2>&1; then
|
|
pnpm run build 2>&1 || npm run build 2>&1 || true
|
|
else
|
|
npm run build 2>&1 || true
|
|
fi
|
|
else
|
|
log_warn "Node.js not found locally. Will build on target VMID."
|
|
fi
|
|
else
|
|
log_success "Using existing dist directory"
|
|
fi
|
|
|
|
# Check if Node.js is installed on target
|
|
log_info "Checking Node.js on VMID $vmid..."
|
|
NODE_VERSION=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- node --version 2>/dev/null || echo 'not_installed'" 2>/dev/null || echo "not_installed")
|
|
|
|
if [ "$NODE_VERSION" = "not_installed" ]; then
|
|
log_warn "Node.js not found on VMID $vmid. Installing..."
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- bash -c 'curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs'" 2>/dev/null || {
|
|
log_error "Failed to install Node.js"
|
|
return 1
|
|
}
|
|
fi
|
|
|
|
# Create deployment directory
|
|
log_info "Creating deployment directory..."
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- mkdir -p $DEPLOY_DIR" 2>/dev/null || return 1
|
|
|
|
# Copy files using tar pipe (more reliable than pct push)
|
|
log_info "Copying files to VMID $vmid..."
|
|
|
|
# Copy essential files: package.json, env.template
|
|
log_info "Copying package.json and env.template..."
|
|
tar -czf - -C "$PROJECT_DIR" package.json env.template 2>/dev/null | \
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- bash -c 'mkdir -p $DEPLOY_DIR && cd $DEPLOY_DIR && tar -xzf -'" 2>/dev/null || {
|
|
log_error "Failed to copy package.json and env.template"
|
|
return 1
|
|
}
|
|
|
|
# Verify files were copied
|
|
PACKAGE_EXISTS=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- test -f $DEPLOY_DIR/package.json && echo 'yes' || echo 'no'" 2>/dev/null || echo "no")
|
|
|
|
if [ "$PACKAGE_EXISTS" != "yes" ]; then
|
|
log_error "package.json not found after copy"
|
|
return 1
|
|
fi
|
|
log_success "Files copied successfully"
|
|
|
|
# Copy dist directory or build on target
|
|
if [ -d "$PROJECT_DIR/dist" ]; then
|
|
log_info "Copying dist directory..."
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- mkdir -p $DEPLOY_DIR/dist" 2>/dev/null || return 1
|
|
|
|
# Copy dist files - preserve structure
|
|
tar -czf - -C "$PROJECT_DIR" dist/ 2>/dev/null | \
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- bash -c 'cd $DEPLOY_DIR && tar -xzf - && ls -la dist/ 2>&1 | head -10'" 2>/dev/null || return 1
|
|
|
|
# Verify main.js exists
|
|
MAIN_JS=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- find $DEPLOY_DIR/dist -name 'main.js' -type f 2>/dev/null | head -1" 2>/dev/null || echo "")
|
|
|
|
if [ -z "$MAIN_JS" ]; then
|
|
log_error "main.js not found in dist directory"
|
|
log_info "Checking dist structure..."
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- find $DEPLOY_DIR/dist -type f 2>/dev/null | head -10" 2>/dev/null || true
|
|
return 1
|
|
fi
|
|
log_success "Found main.js at: $MAIN_JS"
|
|
else
|
|
log_warn "dist directory not found locally, will build on target..."
|
|
# Copy source files and build on target
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- mkdir -p $DEPLOY_DIR/src" 2>/dev/null || return 1
|
|
|
|
# Copy source and tsconfig
|
|
tar -czf - -C "$PROJECT_DIR" src/ tsconfig.json 2>/dev/null | \
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- bash -c 'cd $DEPLOY_DIR && tar -xzf -'" 2>/dev/null || return 1
|
|
|
|
# Build on target
|
|
log_info "Building TypeScript on target VMID..."
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- bash -c 'cd $DEPLOY_DIR && npm install typescript --save-dev && npx tsc'" 2>/dev/null || {
|
|
log_error "Build failed on target"
|
|
return 1
|
|
}
|
|
fi
|
|
|
|
# Install dependencies
|
|
log_info "Installing dependencies..."
|
|
INSTALL_OUTPUT=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- bash -c 'cd $DEPLOY_DIR && npm install --production 2>&1'" 2>/dev/null)
|
|
INSTALL_EXIT=$?
|
|
|
|
if [ $INSTALL_EXIT -ne 0 ]; then
|
|
log_error "Dependency installation failed"
|
|
log_info "Output: $INSTALL_OUTPUT"
|
|
return 1
|
|
fi
|
|
log_success "Dependencies installed"
|
|
|
|
# Copy systemd service (with corrected path)
|
|
log_info "Installing systemd service..."
|
|
# Read service file and fix the path
|
|
SERVICE_CONTENT=$(cat "$PROJECT_DIR/systemd/rpc-translator-138.service" | sed 's|dist/main.js|dist/src/main.js|g')
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- bash -c 'cat > /etc/systemd/system/rpc-translator-138.service <<\"EOFSERVICE\"
|
|
$SERVICE_CONTENT
|
|
EOFSERVICE
|
|
'" 2>/dev/null || {
|
|
log_warn "Failed to copy systemd service via exec, trying pct push..."
|
|
# Create temp file with corrected path
|
|
TEMP_SERVICE=$(mktemp)
|
|
sed 's|dist/main.js|dist/src/main.js|g' "$PROJECT_DIR/systemd/rpc-translator-138.service" > "$TEMP_SERVICE"
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct push $vmid $TEMP_SERVICE /etc/systemd/system/rpc-translator-138.service" 2>/dev/null || return 1
|
|
rm -f "$TEMP_SERVICE"
|
|
}
|
|
|
|
# Create .env file if it doesn't exist
|
|
log_info "Configuring .env file..."
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- bash -c 'if [ ! -f $DEPLOY_DIR/.env ]; then cp $DEPLOY_DIR/env.template $DEPLOY_DIR/.env; fi'" 2>/dev/null || return 1
|
|
|
|
# Check if port 9545 is in use, if so use alternative port
|
|
log_info "Checking port availability..."
|
|
PORT_IN_USE=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- ss -tlnp 2>/dev/null | grep -q ':9545 ' && echo 'yes' || echo 'no'" 2>/dev/null || echo "no")
|
|
|
|
if [ "$PORT_IN_USE" = "yes" ]; then
|
|
log_warn "Port 9545 is in use, checking for alternative port..."
|
|
# Try 9547, 9548, etc.
|
|
ALT_PORT=9547
|
|
ALT_WS_PORT=9548
|
|
while ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- ss -tlnp 2>/dev/null | grep -q ':$ALT_PORT '" 2>/dev/null; do
|
|
ALT_PORT=$((ALT_PORT + 2))
|
|
ALT_WS_PORT=$((ALT_WS_PORT + 2))
|
|
done
|
|
log_info "Using alternative ports: HTTP $ALT_PORT, WS $ALT_WS_PORT"
|
|
HTTP_PORT=$ALT_PORT
|
|
WS_PORT=$ALT_WS_PORT
|
|
else
|
|
HTTP_PORT=9545
|
|
WS_PORT=9546
|
|
fi
|
|
|
|
# Store ports for summary
|
|
DEPLOYED_PORTS[$vmid]="$HTTP_PORT:$WS_PORT"
|
|
|
|
# Update .env with correct values
|
|
log_info "Updating .env configuration..."
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- bash -c 'cat > $DEPLOY_DIR/.env <<EOF
|
|
# Server Configuration
|
|
HTTP_PORT=$HTTP_PORT
|
|
WS_PORT=$WS_PORT
|
|
NODE_ENV=production
|
|
|
|
# Besu Upstream Configuration
|
|
BESU_HTTP_URLS=http://127.0.0.1:8545
|
|
BESU_WS_URLS=ws://127.0.0.1:8546
|
|
CHAIN_ID=138
|
|
|
|
# Web3Signer Configuration (VMID 107)
|
|
WEB3SIGNER_URL=http://192.168.11.111:9000
|
|
WEB3SIGNER_TIMEOUT=5000
|
|
|
|
# Redis Configuration (VMID 106)
|
|
REDIS_HOST=192.168.11.110
|
|
REDIS_PORT=6379
|
|
REDIS_PASSWORD=
|
|
REDIS_DB=0
|
|
REDIS_KEY_PREFIX=rpc-translator:138
|
|
|
|
# Vault Configuration (VMID 108) - Optional
|
|
VAULT_ADDR=http://192.168.11.112:8200
|
|
VAULT_ROLE_ID=
|
|
VAULT_SECRET_ID=
|
|
VAULT_PATH_TRANSLATOR_CONFIG=secret/data/chain138/translator
|
|
|
|
# Translator Policy
|
|
WALLET_ALLOWLIST=
|
|
MAX_GAS_LIMIT=30000000
|
|
MAX_GAS_PRICE_WEI=100000000000
|
|
MIN_GAS_PRICE_WEI=1000000000
|
|
EOF
|
|
'" 2>/dev/null || return 1
|
|
|
|
# Reload systemd and enable service
|
|
log_info "Enabling systemd service..."
|
|
DAEMON_RELOAD=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- systemctl daemon-reload 2>&1" 2>/dev/null)
|
|
if [ $? -ne 0 ]; then
|
|
log_error "Failed to reload systemd: $DAEMON_RELOAD"
|
|
return 1
|
|
fi
|
|
|
|
ENABLE_OUTPUT=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- systemctl enable rpc-translator-138.service 2>&1" 2>/dev/null)
|
|
if [ $? -ne 0 ]; then
|
|
log_error "Failed to enable service: $ENABLE_OUTPUT"
|
|
# Check if service file exists
|
|
SERVICE_EXISTS=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- test -f /etc/systemd/system/rpc-translator-138.service && echo 'yes' || echo 'no'" 2>/dev/null || echo "no")
|
|
if [ "$SERVICE_EXISTS" != "yes" ]; then
|
|
log_error "Service file not found at /etc/systemd/system/rpc-translator-138.service"
|
|
fi
|
|
return 1
|
|
fi
|
|
log_success "Service enabled"
|
|
|
|
# Start service
|
|
log_info "Starting service..."
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- systemctl start rpc-translator-138.service" 2>/dev/null || {
|
|
log_warn "Service start failed, checking status..."
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- systemctl status rpc-translator-138.service --no-pager -l | head -20" 2>/dev/null || true
|
|
return 1
|
|
}
|
|
|
|
# Wait a moment for service to start
|
|
sleep 2
|
|
|
|
# Check service status
|
|
log_info "Checking service status..."
|
|
SERVICE_STATUS=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- systemctl is-active rpc-translator-138.service 2>/dev/null || echo 'inactive'" 2>/dev/null || echo "unknown")
|
|
|
|
if [ "$SERVICE_STATUS" = "active" ]; then
|
|
log_success "Service is running on VMID $vmid"
|
|
else
|
|
log_warn "Service status: $SERVICE_STATUS"
|
|
log_info "Checking logs..."
|
|
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
|
|
"pct exec $vmid -- journalctl -u rpc-translator-138.service --no-pager -n 20" 2>/dev/null || true
|
|
fi
|
|
|
|
# Test endpoint
|
|
log_info "Testing HTTP endpoint on port $HTTP_PORT..."
|
|
sleep 2
|
|
HTTP_RESPONSE=$(curl -s -X POST "http://${vmip}:${HTTP_PORT}" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' 2>/dev/null || echo "")
|
|
|
|
if echo "$HTTP_RESPONSE" | grep -q "0x8a"; then
|
|
log_success "HTTP endpoint responding correctly on VMID $vmid (port $HTTP_PORT)"
|
|
else
|
|
log_warn "HTTP endpoint test failed or not ready yet"
|
|
log_info "Response: $HTTP_RESPONSE"
|
|
# Check if service is still starting
|
|
sleep 2
|
|
HTTP_RESPONSE2=$(curl -s -X POST "http://${vmip}:${HTTP_PORT}" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' 2>/dev/null || echo "")
|
|
if echo "$HTTP_RESPONSE2" | grep -q "0x8a"; then
|
|
log_success "HTTP endpoint now responding on VMID $vmid (port $HTTP_PORT)"
|
|
fi
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# Main deployment
|
|
log_section
|
|
log_info "RPC Translator Service - Complete Deployment"
|
|
log_section
|
|
echo ""
|
|
|
|
# Check prerequisites
|
|
log_info "Checking prerequisites..."
|
|
if ! ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 root@"$PROXMOX_HOST" "echo 'Connected'" >/dev/null 2>&1; then
|
|
log_error "Cannot connect to Proxmox host $PROXMOX_HOST"
|
|
exit 1
|
|
fi
|
|
log_success "Proxmox host accessible"
|
|
echo ""
|
|
|
|
# Deploy to each VMID
|
|
FAILED_VMIDS=()
|
|
SUCCESS_VMIDS=()
|
|
|
|
for VMID in "${!VMIDS[@]}"; do
|
|
VMIP="${VMIDS[$VMID]}"
|
|
|
|
log_section
|
|
log_info "Deploying to VMID $VMID ($VMIP)"
|
|
log_section
|
|
echo ""
|
|
|
|
# Try to find node
|
|
NODE=$(check_pct_access "$VMID" "$VMIP" 2>/dev/null || echo "")
|
|
|
|
if [ -z "$NODE" ]; then
|
|
log_warn "Could not find VMID $VMID via pct, trying direct SSH..."
|
|
# Try direct deployment via SSH
|
|
if deploy_via_pct "$VMID" "$VMIP" "direct" 2>/dev/null; then
|
|
SUCCESS_VMIDS+=("$VMID")
|
|
else
|
|
log_error "Failed to deploy to VMID $VMID"
|
|
FAILED_VMIDS+=("$VMID")
|
|
fi
|
|
else
|
|
if deploy_via_pct "$VMID" "$VMIP" "$NODE"; then
|
|
SUCCESS_VMIDS+=("$VMID")
|
|
else
|
|
log_error "Failed to deploy to VMID $VMID"
|
|
FAILED_VMIDS+=("$VMID")
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
done
|
|
|
|
# Summary
|
|
log_section
|
|
log_info "Deployment Summary"
|
|
log_section
|
|
echo ""
|
|
|
|
if [ ${#SUCCESS_VMIDS[@]} -gt 0 ]; then
|
|
log_success "Successfully deployed to: ${SUCCESS_VMIDS[*]}"
|
|
echo ""
|
|
log_info "Service endpoints:"
|
|
for vmid in "${SUCCESS_VMIDS[@]}"; do
|
|
vmip="${VMIDS[$vmid]}"
|
|
ports="${DEPLOYED_PORTS[$vmid]:-9545:9546}"
|
|
http_port="${ports%%:*}"
|
|
ws_port="${ports#*:}"
|
|
echo " VMID $vmid: http://${vmip}:${http_port} (HTTP), ws://${vmip}:${ws_port} (WebSocket)"
|
|
done
|
|
echo ""
|
|
fi
|
|
|
|
if [ ${#FAILED_VMIDS[@]} -gt 0 ]; then
|
|
log_error "Failed to deploy to: ${FAILED_VMIDS[*]}"
|
|
echo ""
|
|
log_info "To retry deployment:"
|
|
for vmid in "${FAILED_VMIDS[@]}"; do
|
|
vmip="${VMIDS[$vmid]}"
|
|
echo " ./scripts/deploy-to-vmid.sh $vmid $vmip"
|
|
done
|
|
echo ""
|
|
fi
|
|
|
|
log_section
|
|
log_info "Deployment Complete"
|
|
log_section
|
|
echo ""
|