556 lines
20 KiB
Bash
556 lines
20 KiB
Bash
|
|
#!/bin/bash
|
|||
|
|
# Comprehensive Deployment Validation Script for ml110-01
|
|||
|
|
# Validates all prerequisites, configurations, and deployment readiness
|
|||
|
|
|
|||
|
|
set -e
|
|||
|
|
|
|||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||
|
|
PROJECT_ROOT="$SCRIPT_DIR"
|
|||
|
|
DEPLOY_DIR="$PROJECT_ROOT/smom-dbis-138-proxmox"
|
|||
|
|
|
|||
|
|
# Colors
|
|||
|
|
RED='\033[0;31m'
|
|||
|
|
GREEN='\033[0;32m'
|
|||
|
|
YELLOW='\033[1;33m'
|
|||
|
|
BLUE='\033[0;34m'
|
|||
|
|
CYAN='\033[0;36m'
|
|||
|
|
NC='\033[0m'
|
|||
|
|
|
|||
|
|
# Status counters
|
|||
|
|
PASSED=0
|
|||
|
|
FAILED=0
|
|||
|
|
WARNINGS=0
|
|||
|
|
|
|||
|
|
# Functions
|
|||
|
|
pass() {
|
|||
|
|
echo -e "${GREEN}✅${NC} $1"
|
|||
|
|
((PASSED++))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fail() {
|
|||
|
|
echo -e "${RED}❌${NC} $1"
|
|||
|
|
((FAILED++))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
warn() {
|
|||
|
|
echo -e "${YELLOW}⚠️${NC} $1"
|
|||
|
|
((WARNINGS++))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
info() {
|
|||
|
|
echo -e "${BLUE}ℹ️${NC} $1"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
section() {
|
|||
|
|
echo ""
|
|||
|
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|||
|
|
echo -e "${CYAN}$1${NC}"
|
|||
|
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|||
|
|
echo ""
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Load environment
|
|||
|
|
ENV_FILE="$HOME/.env"
|
|||
|
|
if [ -f "$ENV_FILE" ]; then
|
|||
|
|
source <(grep -E "^PROXMOX_" "$ENV_FILE" 2>/dev/null | sed 's/^/export /' || true)
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
TARGET_HOST="${PROXMOX_HOST:-192.168.11.10}"
|
|||
|
|
TARGET_NODE="${TARGET_NODE:-ml110-01}"
|
|||
|
|
|
|||
|
|
echo ""
|
|||
|
|
echo -e "${BLUE}╔════════════════════════════════════════════════════════════════════════╗${NC}"
|
|||
|
|
echo -e "${BLUE}║${NC} Deployment Validation for ml110-01 (${TARGET_HOST}) ${BLUE}║${NC}"
|
|||
|
|
echo -e "${BLUE}╚════════════════════════════════════════════════════════════════════════╝${NC}"
|
|||
|
|
echo ""
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# SECTION 1: PREREQUISITES
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
section "1. PREREQUISITES CHECK"
|
|||
|
|
|
|||
|
|
# Check if running on Proxmox host or remote
|
|||
|
|
if command -v pct &> /dev/null; then
|
|||
|
|
info "Running on Proxmox host - can execute pct commands directly"
|
|||
|
|
ON_PROXMOX_HOST=true
|
|||
|
|
else
|
|||
|
|
info "Running remotely - will use Proxmox API"
|
|||
|
|
ON_PROXMOX_HOST=false
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# Check required tools
|
|||
|
|
REQUIRED_TOOLS=("curl" "jq" "git" "bash")
|
|||
|
|
for tool in "${REQUIRED_TOOLS[@]}"; do
|
|||
|
|
if command -v "$tool" &> /dev/null; then
|
|||
|
|
pass "$tool installed"
|
|||
|
|
else
|
|||
|
|
fail "$tool not found (required)"
|
|||
|
|
fi
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
# Check deployment directory
|
|||
|
|
if [ -d "$DEPLOY_DIR" ]; then
|
|||
|
|
pass "Deployment directory exists: $DEPLOY_DIR"
|
|||
|
|
else
|
|||
|
|
fail "Deployment directory not found: $DEPLOY_DIR"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# SECTION 2: PROXMOX CONNECTION
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
section "2. PROXMOX CONNECTION VALIDATION"
|
|||
|
|
|
|||
|
|
# Test API connectivity
|
|||
|
|
info "Testing connection to $TARGET_HOST:8006"
|
|||
|
|
API_RESPONSE=$(curl -k -s -w "\n%{http_code}" -H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
|
|||
|
|
"https://${TARGET_HOST}:8006/api2/json/version" 2>&1 || echo "ERROR")
|
|||
|
|
|
|||
|
|
HTTP_CODE=$(echo "$API_RESPONSE" | tail -1)
|
|||
|
|
RESPONSE_BODY=$(echo "$API_RESPONSE" | sed '$d')
|
|||
|
|
|
|||
|
|
if [ "$HTTP_CODE" = "200" ]; then
|
|||
|
|
VERSION=$(echo "$RESPONSE_BODY" | jq -r '.data.version' 2>/dev/null || echo "unknown")
|
|||
|
|
pass "API connection successful (Proxmox version: $VERSION)"
|
|||
|
|
else
|
|||
|
|
fail "API connection failed (HTTP $HTTP_CODE)"
|
|||
|
|
if [ -n "$RESPONSE_BODY" ]; then
|
|||
|
|
info "Response: $(echo "$RESPONSE_BODY" | head -c 200)"
|
|||
|
|
fi
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# Get node list
|
|||
|
|
info "Retrieving node list..."
|
|||
|
|
NODES_RESPONSE=$(curl -k -s -H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
|
|||
|
|
"https://${TARGET_HOST}:8006/api2/json/nodes" 2>&1)
|
|||
|
|
|
|||
|
|
if echo "$NODES_RESPONSE" | jq -e '.data' &>/dev/null; then
|
|||
|
|
NODE_COUNT=$(echo "$NODES_RESPONSE" | jq '.data | length')
|
|||
|
|
NODE_NAMES=$(echo "$NODES_RESPONSE" | jq -r '.data[].node' | tr '\n' ' ')
|
|||
|
|
pass "Retrieved $NODE_COUNT node(s): $NODE_NAMES"
|
|||
|
|
|
|||
|
|
# Check if target node exists
|
|||
|
|
if echo "$NODES_RESPONSE" | jq -e ".data[] | select(.node==\"$TARGET_NODE\")" &>/dev/null; then
|
|||
|
|
pass "Target node '$TARGET_NODE' found"
|
|||
|
|
else
|
|||
|
|
FIRST_NODE=$(echo "$NODES_RESPONSE" | jq -r '.data[0].node')
|
|||
|
|
warn "Target node '$TARGET_NODE' not found, using first node: $FIRST_NODE"
|
|||
|
|
TARGET_NODE="$FIRST_NODE"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
fail "Failed to retrieve nodes"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# Get node status
|
|||
|
|
info "Checking node status for $TARGET_NODE..."
|
|||
|
|
NODE_STATUS=$(curl -k -s -H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
|
|||
|
|
"https://${TARGET_HOST}:8006/api2/json/nodes/${TARGET_NODE}/status" 2>&1)
|
|||
|
|
|
|||
|
|
if echo "$NODE_STATUS" | jq -e '.data.status' &>/dev/null; then
|
|||
|
|
STATUS=$(echo "$NODE_STATUS" | jq -r '.data.status')
|
|||
|
|
if [ "$STATUS" = "online" ]; then
|
|||
|
|
pass "Node $TARGET_NODE is online"
|
|||
|
|
else
|
|||
|
|
fail "Node $TARGET_NODE status: $STATUS"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
warn "Could not retrieve node status"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# SECTION 3: STORAGE VALIDATION
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
section "3. STORAGE VALIDATION"
|
|||
|
|
|
|||
|
|
# Get storage list
|
|||
|
|
info "Checking storage availability..."
|
|||
|
|
STORAGE_RESPONSE=$(curl -k -s -H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
|
|||
|
|
"https://${TARGET_HOST}:8006/api2/json/nodes/${TARGET_NODE}/storage" 2>&1)
|
|||
|
|
|
|||
|
|
if echo "$STORAGE_RESPONSE" | jq -e '.data' &>/dev/null; then
|
|||
|
|
STORAGE_COUNT=$(echo "$STORAGE_RESPONSE" | jq '.data | length')
|
|||
|
|
pass "Found $STORAGE_COUNT storage pool(s)"
|
|||
|
|
|
|||
|
|
# Check for common storage types
|
|||
|
|
STORAGE_TYPES=$(echo "$STORAGE_RESPONSE" | jq -r '.data[].type' | sort -u | tr '\n' ' ')
|
|||
|
|
info "Storage types available: $STORAGE_TYPES"
|
|||
|
|
|
|||
|
|
# Check for container storage (rootdir)
|
|||
|
|
CONTAINER_STORAGE=$(echo "$STORAGE_RESPONSE" | jq -r '.data[] | select(.content | contains("rootdir")) | .storage' | head -1)
|
|||
|
|
if [ -n "$CONTAINER_STORAGE" ]; then
|
|||
|
|
pass "Container storage found: $CONTAINER_STORAGE"
|
|||
|
|
|
|||
|
|
# Check storage capacity
|
|||
|
|
STORAGE_INFO=$(echo "$STORAGE_RESPONSE" | jq ".[] | select(.storage==\"$CONTAINER_STORAGE\")")
|
|||
|
|
if echo "$STORAGE_INFO" | jq -e '.content' &>/dev/null; then
|
|||
|
|
TOTAL=$(echo "$STORAGE_INFO" | jq -r '.total // 0' | numfmt --to=iec-i --suffix=B 2>/dev/null || echo "unknown")
|
|||
|
|
FREE=$(echo "$STORAGE_INFO" | jq -r '.avail // 0' | numfmt --to=iec-i --suffix=B 2>/dev/null || echo "unknown")
|
|||
|
|
USED=$(echo "$STORAGE_INFO" | jq -r '.used // 0' | numfmt --to=iec-i --suffix=B 2>/dev/null || echo "unknown")
|
|||
|
|
info "Storage $CONTAINER_STORAGE: Total=$TOTAL, Free=$FREE, Used=$USED"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
fail "No container storage (rootdir) found"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# Check for template storage (vztmpl)
|
|||
|
|
TEMPLATE_STORAGE=$(echo "$STORAGE_RESPONSE" | jq -r '.data[] | select(.content | contains("vztmpl")) | .storage' | head -1)
|
|||
|
|
if [ -n "$TEMPLATE_STORAGE" ]; then
|
|||
|
|
pass "Template storage found: $TEMPLATE_STORAGE"
|
|||
|
|
else
|
|||
|
|
warn "No template storage (vztmpl) found"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
fail "Failed to retrieve storage information"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# SECTION 4: TEMPLATE VALIDATION
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
section "4. LXC TEMPLATE VALIDATION"
|
|||
|
|
|
|||
|
|
if [ -n "$TEMPLATE_STORAGE" ]; then
|
|||
|
|
info "Checking templates on storage: $TEMPLATE_STORAGE"
|
|||
|
|
TEMPLATES_RESPONSE=$(curl -k -s -H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
|
|||
|
|
"https://${TARGET_HOST}:8006/api2/json/nodes/${TARGET_NODE}/storage/${TEMPLATE_STORAGE}/content?content=vztmpl" 2>&1)
|
|||
|
|
|
|||
|
|
if echo "$TEMPLATES_RESPONSE" | jq -e '.data' &>/dev/null; then
|
|||
|
|
TEMPLATE_COUNT=$(echo "$TEMPLATES_RESPONSE" | jq '.data | length')
|
|||
|
|
pass "Found $TEMPLATE_COUNT template(s)"
|
|||
|
|
|
|||
|
|
# Check for Debian 12 template
|
|||
|
|
DEBIAN_TEMPLATE=$(echo "$TEMPLATES_RESPONSE" | jq -r '.data[] | select(.volid | contains("debian-12")) | .volid' | head -1)
|
|||
|
|
if [ -n "$DEBIAN_TEMPLATE" ]; then
|
|||
|
|
pass "Debian 12 template found: $DEBIAN_TEMPLATE"
|
|||
|
|
else
|
|||
|
|
fail "Debian 12 template not found (required for deployment)"
|
|||
|
|
info "Available templates:"
|
|||
|
|
echo "$TEMPLATES_RESPONSE" | jq -r '.data[].volid' | head -10 | sed 's/^/ - /'
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
warn "Could not retrieve template list"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
warn "Cannot check templates - no template storage found"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# SECTION 5: CONFIGURATION FILES
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
section "5. CONFIGURATION FILES VALIDATION"
|
|||
|
|
|
|||
|
|
# Check if config files exist
|
|||
|
|
CONFIG_DIR="$DEPLOY_DIR/config"
|
|||
|
|
if [ -d "$CONFIG_DIR" ]; then
|
|||
|
|
pass "Config directory exists: $CONFIG_DIR"
|
|||
|
|
|
|||
|
|
# Check proxmox.conf
|
|||
|
|
if [ -f "$CONFIG_DIR/proxmox.conf" ]; then
|
|||
|
|
pass "proxmox.conf exists"
|
|||
|
|
source "$CONFIG_DIR/proxmox.conf" 2>/dev/null || true
|
|||
|
|
|
|||
|
|
# Validate config values
|
|||
|
|
if [ -n "${PROXMOX_HOST:-}" ]; then
|
|||
|
|
if [ "$PROXMOX_HOST" = "$TARGET_HOST" ] || [ "$PROXMOX_HOST" = "proxmox.example.com" ]; then
|
|||
|
|
if [ "$PROXMOX_HOST" = "$TARGET_HOST" ]; then
|
|||
|
|
pass "PROXMOX_HOST configured: $PROXMOX_HOST"
|
|||
|
|
else
|
|||
|
|
warn "PROXMOX_HOST still set to example: $PROXMOX_HOST"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
warn "PROXMOX_HOST mismatch: configured=$PROXMOX_HOST, expected=$TARGET_HOST"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
fail "PROXMOX_HOST not set in proxmox.conf"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
if [ -n "${PROXMOX_NODE:-}" ]; then
|
|||
|
|
pass "PROXMOX_NODE configured: $PROXMOX_NODE"
|
|||
|
|
else
|
|||
|
|
warn "PROXMOX_NODE not set (will use default)"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
if [ -n "${PROXMOX_STORAGE:-}" ]; then
|
|||
|
|
pass "PROXMOX_STORAGE configured: $PROXMOX_STORAGE"
|
|||
|
|
else
|
|||
|
|
warn "PROXMOX_STORAGE not set (will use default)"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
if [ -n "${CONTAINER_OS_TEMPLATE:-}" ]; then
|
|||
|
|
pass "CONTAINER_OS_TEMPLATE configured: $CONTAINER_OS_TEMPLATE"
|
|||
|
|
else
|
|||
|
|
warn "CONTAINER_OS_TEMPLATE not set (will use default)"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
if [ -f "$CONFIG_DIR/proxmox.conf.example" ]; then
|
|||
|
|
fail "proxmox.conf not found (example exists - needs to be copied and configured)"
|
|||
|
|
else
|
|||
|
|
fail "proxmox.conf not found"
|
|||
|
|
fi
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# Check network.conf
|
|||
|
|
if [ -f "$CONFIG_DIR/network.conf" ]; then
|
|||
|
|
pass "network.conf exists"
|
|||
|
|
source "$CONFIG_DIR/network.conf" 2>/dev/null || true
|
|||
|
|
|
|||
|
|
if [ -n "${SUBNET_BASE:-}" ]; then
|
|||
|
|
pass "SUBNET_BASE configured: $SUBNET_BASE"
|
|||
|
|
else
|
|||
|
|
warn "SUBNET_BASE not set"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
if [ -n "${GATEWAY:-}" ]; then
|
|||
|
|
pass "GATEWAY configured: $GATEWAY"
|
|||
|
|
else
|
|||
|
|
warn "GATEWAY not set"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
if [ -f "$CONFIG_DIR/network.conf.example" ]; then
|
|||
|
|
warn "network.conf not found (example exists)"
|
|||
|
|
else
|
|||
|
|
warn "network.conf not found"
|
|||
|
|
fi
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
fail "Config directory not found: $CONFIG_DIR"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# SECTION 6: DEPLOYMENT SCRIPTS
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
section "6. DEPLOYMENT SCRIPTS VALIDATION"
|
|||
|
|
|
|||
|
|
SCRIPTS_DIR="$DEPLOY_DIR/scripts/deployment"
|
|||
|
|
if [ -d "$SCRIPTS_DIR" ]; then
|
|||
|
|
pass "Deployment scripts directory exists"
|
|||
|
|
|
|||
|
|
REQUIRED_SCRIPTS=(
|
|||
|
|
"deploy-all.sh"
|
|||
|
|
"deploy-besu-nodes.sh"
|
|||
|
|
"deploy-services.sh"
|
|||
|
|
"deploy-hyperledger-services.sh"
|
|||
|
|
"deploy-monitoring.sh"
|
|||
|
|
"deploy-explorer.sh"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
for script in "${REQUIRED_SCRIPTS[@]}"; do
|
|||
|
|
SCRIPT_PATH="$SCRIPTS_DIR/$script"
|
|||
|
|
if [ -f "$SCRIPT_PATH" ]; then
|
|||
|
|
if [ -x "$SCRIPT_PATH" ]; then
|
|||
|
|
pass "$script exists and is executable"
|
|||
|
|
else
|
|||
|
|
warn "$script exists but is not executable"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# Check for syntax errors
|
|||
|
|
if bash -n "$SCRIPT_PATH" 2>&1 | grep -q "error"; then
|
|||
|
|
fail "$script has syntax errors"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
warn "$script not found"
|
|||
|
|
fi
|
|||
|
|
done
|
|||
|
|
else
|
|||
|
|
fail "Deployment scripts directory not found: $SCRIPTS_DIR"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# Check common library
|
|||
|
|
LIB_DIR="$DEPLOY_DIR/lib"
|
|||
|
|
if [ -f "$LIB_DIR/common.sh" ]; then
|
|||
|
|
pass "common.sh library exists"
|
|||
|
|
else
|
|||
|
|
fail "common.sh library not found"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
if [ -f "$LIB_DIR/proxmox-api.sh" ]; then
|
|||
|
|
pass "proxmox-api.sh library exists"
|
|||
|
|
else
|
|||
|
|
warn "proxmox-api.sh library not found"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# SECTION 7: RESOURCE REQUIREMENTS
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
section "7. RESOURCE REQUIREMENTS VALIDATION"
|
|||
|
|
|
|||
|
|
# Calculate total resource requirements
|
|||
|
|
TOTAL_MEMORY=0
|
|||
|
|
TOTAL_CORES=0
|
|||
|
|
TOTAL_DISK=0
|
|||
|
|
|
|||
|
|
# Load resource config if available
|
|||
|
|
if [ -f "$CONFIG_DIR/proxmox.conf" ]; then
|
|||
|
|
source "$CONFIG_DIR/proxmox.conf" 2>/dev/null || true
|
|||
|
|
|
|||
|
|
# Calculate based on default counts
|
|||
|
|
VALIDATOR_COUNT="${VALIDATORS_COUNT:-4}"
|
|||
|
|
SENTRY_COUNT="${SENTRIES_COUNT:-3}"
|
|||
|
|
RPC_COUNT="${RPC_COUNT:-3}"
|
|||
|
|
SERVICE_COUNT="${SERVICES_COUNT:-4}"
|
|||
|
|
|
|||
|
|
TOTAL_MEMORY=$((VALIDATOR_MEMORY * VALIDATOR_COUNT + SENTRY_MEMORY * SENTRY_COUNT + RPC_MEMORY * RPC_COUNT + SERVICE_MEMORY * SERVICE_COUNT + MONITORING_MEMORY))
|
|||
|
|
TOTAL_CORES=$((VALIDATOR_CORES * VALIDATOR_COUNT + SENTRY_CORES * SENTRY_COUNT + RPC_CORES * RPC_COUNT + SERVICE_CORES * SERVICE_COUNT + MONITORING_CORES))
|
|||
|
|
TOTAL_DISK=$((VALIDATOR_DISK * VALIDATOR_COUNT + SENTRY_DISK * SENTRY_COUNT + RPC_DISK * RPC_COUNT + SERVICE_DISK * SERVICE_COUNT + MONITORING_DISK))
|
|||
|
|
|
|||
|
|
info "Estimated resource requirements:"
|
|||
|
|
info " Memory: $((TOTAL_MEMORY / 1024))GB"
|
|||
|
|
info " CPU Cores: $TOTAL_CORES"
|
|||
|
|
info " Disk: ${TOTAL_DISK}GB"
|
|||
|
|
|
|||
|
|
# Get node resources
|
|||
|
|
if [ -n "$NODE_STATUS" ]; then
|
|||
|
|
NODE_MEMORY=$(echo "$NODE_STATUS" | jq -r '.data.memory.total // 0')
|
|||
|
|
NODE_FREE_MEMORY=$(echo "$NODE_STATUS" | jq -r '.data.memory.free // 0')
|
|||
|
|
NODE_CPU_COUNT=$(echo "$NODE_STATUS" | jq -r '.data.cpuinfo.cpus // 0')
|
|||
|
|
|
|||
|
|
if [ "$NODE_MEMORY" != "0" ] && [ -n "$NODE_MEMORY" ]; then
|
|||
|
|
MEMORY_GB=$((NODE_MEMORY / 1024 / 1024 / 1024))
|
|||
|
|
FREE_MEMORY_GB=$((NODE_FREE_MEMORY / 1024 / 1024 / 1024))
|
|||
|
|
info "Node resources:"
|
|||
|
|
info " Total Memory: ${MEMORY_GB}GB (Free: ${FREE_MEMORY_GB}GB)"
|
|||
|
|
info " CPU Cores: $NODE_CPU_COUNT"
|
|||
|
|
|
|||
|
|
if [ $FREE_MEMORY_GB -lt $((TOTAL_MEMORY / 1024)) ]; then
|
|||
|
|
warn "Insufficient free memory: need $((TOTAL_MEMORY / 1024))GB, have ${FREE_MEMORY_GB}GB"
|
|||
|
|
else
|
|||
|
|
pass "Sufficient memory available"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
if [ $NODE_CPU_COUNT -lt $TOTAL_CORES ]; then
|
|||
|
|
warn "Limited CPU cores: need $TOTAL_CORES, have $NODE_CPU_COUNT (containers can share CPU)"
|
|||
|
|
else
|
|||
|
|
pass "Sufficient CPU cores available"
|
|||
|
|
fi
|
|||
|
|
fi
|
|||
|
|
fi
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# SECTION 8: NETWORK CONFIGURATION
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
section "8. NETWORK CONFIGURATION VALIDATION"
|
|||
|
|
|
|||
|
|
# Get network interfaces
|
|||
|
|
info "Checking network configuration..."
|
|||
|
|
NETWORK_RESPONSE=$(curl -k -s -H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
|
|||
|
|
"https://${TARGET_HOST}:8006/api2/json/nodes/${TARGET_NODE}/network" 2>&1)
|
|||
|
|
|
|||
|
|
if echo "$NETWORK_RESPONSE" | jq -e '.data' &>/dev/null; then
|
|||
|
|
BRIDGES=$(echo "$NETWORK_RESPONSE" | jq -r '.data[] | select(.type=="bridge") | .iface' | tr '\n' ' ')
|
|||
|
|
if [ -n "$BRIDGES" ]; then
|
|||
|
|
pass "Network bridges found: $BRIDGES"
|
|||
|
|
|
|||
|
|
# Check for vmbr0
|
|||
|
|
if echo "$BRIDGES" | grep -q "vmbr0"; then
|
|||
|
|
pass "vmbr0 bridge exists (required)"
|
|||
|
|
else
|
|||
|
|
warn "vmbr0 bridge not found (may cause network issues)"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
warn "No network bridges found"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
warn "Could not retrieve network configuration"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# SECTION 9: EXISTING CONTAINERS
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
section "9. EXISTING CONTAINERS CHECK"
|
|||
|
|
|
|||
|
|
info "Checking for existing containers..."
|
|||
|
|
CONTAINERS_RESPONSE=$(curl -k -s -H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
|
|||
|
|
"https://${TARGET_HOST}:8006/api2/json/nodes/${TARGET_NODE}/lxc" 2>&1)
|
|||
|
|
|
|||
|
|
if echo "$CONTAINERS_RESPONSE" | jq -e '.data' &>/dev/null; then
|
|||
|
|
EXISTING_COUNT=$(echo "$CONTAINERS_RESPONSE" | jq '.data | length')
|
|||
|
|
if [ "$EXISTING_COUNT" -gt 0 ]; then
|
|||
|
|
info "Found $EXISTING_COUNT existing container(s)"
|
|||
|
|
|
|||
|
|
# Check for VMID conflicts
|
|||
|
|
EXPECTED_VMIDS=(106 107 108 109 110 111 112 115 116 117 120 121 122 130 140 150 151 152 153)
|
|||
|
|
CONFLICTS=()
|
|||
|
|
|
|||
|
|
for vmid in "${EXPECTED_VMIDS[@]}"; do
|
|||
|
|
if echo "$CONTAINERS_RESPONSE" | jq -e ".data[] | select(.vmid==$vmid)" &>/dev/null; then
|
|||
|
|
CONFLICTS+=("$vmid")
|
|||
|
|
fi
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
if [ ${#CONFLICTS[@]} -gt 0 ]; then
|
|||
|
|
warn "VMID conflicts detected: ${CONFLICTS[*]} (containers already exist)"
|
|||
|
|
else
|
|||
|
|
pass "No VMID conflicts detected"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
pass "No existing containers (clean slate)"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
warn "Could not retrieve container list"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# SECTION 10: INSTALLATION SCRIPTS
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
section "10. INSTALLATION SCRIPTS VALIDATION"
|
|||
|
|
|
|||
|
|
INSTALL_DIR="$DEPLOY_DIR/install"
|
|||
|
|
if [ -d "$INSTALL_DIR" ]; then
|
|||
|
|
pass "Install scripts directory exists"
|
|||
|
|
|
|||
|
|
REQUIRED_INSTALL_SCRIPTS=(
|
|||
|
|
"besu-validator-install.sh"
|
|||
|
|
"besu-sentry-install.sh"
|
|||
|
|
"besu-rpc-install.sh"
|
|||
|
|
"oracle-publisher-install.sh"
|
|||
|
|
"ccip-monitor-install.sh"
|
|||
|
|
"keeper-install.sh"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
for script in "${REQUIRED_INSTALL_SCRIPTS[@]}"; do
|
|||
|
|
if [ -f "$INSTALL_DIR/$script" ]; then
|
|||
|
|
pass "$script exists"
|
|||
|
|
else
|
|||
|
|
warn "$script not found"
|
|||
|
|
fi
|
|||
|
|
done
|
|||
|
|
else
|
|||
|
|
fail "Install scripts directory not found: $INSTALL_DIR"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# SUMMARY
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
section "VALIDATION SUMMARY"
|
|||
|
|
|
|||
|
|
echo -e "${CYAN}Results:${NC}"
|
|||
|
|
echo -e " ${GREEN}Passed:${NC} $PASSED"
|
|||
|
|
echo -e " ${RED}Failed:${NC} $FAILED"
|
|||
|
|
echo -e " ${YELLOW}Warnings:${NC} $WARNINGS"
|
|||
|
|
echo ""
|
|||
|
|
|
|||
|
|
if [ $FAILED -eq 0 ]; then
|
|||
|
|
echo -e "${GREEN}✅ Deployment validation PASSED${NC}"
|
|||
|
|
echo ""
|
|||
|
|
echo "Next steps:"
|
|||
|
|
echo " 1. Review configuration files in $DEPLOY_DIR/config/"
|
|||
|
|
echo " 2. Run deployment: cd $DEPLOY_DIR && ./scripts/deployment/deploy-all.sh"
|
|||
|
|
exit 0
|
|||
|
|
else
|
|||
|
|
echo -e "${RED}❌ Deployment validation FAILED${NC}"
|
|||
|
|
echo ""
|
|||
|
|
echo "Please fix the issues above before proceeding with deployment."
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
|