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>
149 lines
5.1 KiB
Bash
Executable File
149 lines
5.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Analyze cluster and prepare migration plan for LXC containers
|
|
# Reviews current container distribution and suggests migration strategy
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
PROXMOX_HOST="${PROXMOX_HOST:-192.168.11.10}"
|
|
PROXMOX_PASS="${PROXMOX_PASS:-L@kers2010}"
|
|
|
|
# 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}[WARN]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
log_header() { echo -e "${CYAN}[$1]${NC} $2"; }
|
|
|
|
# SSH helper
|
|
ssh_proxmox() {
|
|
sshpass -p "$PROXMOX_PASS" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 root@"$PROXMOX_HOST" "$@"
|
|
}
|
|
|
|
echo "========================================="
|
|
log_header "CLUSTER" "Analysis and Migration Planning"
|
|
echo "========================================="
|
|
echo ""
|
|
|
|
# Check cluster status
|
|
log_info "Cluster Status:"
|
|
ssh_proxmox "pvecm status" 2>&1 | head -20
|
|
echo ""
|
|
|
|
# Get node resource usage
|
|
log_info "Node Resource Usage:"
|
|
nodes_json=$(ssh_proxmox "pvesh get /nodes --output-format json" 2>&1)
|
|
if [[ -n "$nodes_json" ]]; then
|
|
echo "$nodes_json" | python3 << 'PYEOF'
|
|
import sys, json
|
|
try:
|
|
data = json.load(sys.stdin)
|
|
print(f"{'Node':<10} {'CPU %':<10} {'RAM Used/Max':<20} {'RAM %':<10} {'Disk Used/Max':<20} {'Disk %':<10} {'Status'}")
|
|
print("-" * 100)
|
|
for node in sorted(data, key=lambda x: x['node']):
|
|
cpu_pct = node['cpu'] * 100
|
|
mem_used = node['mem'] / (1024**3)
|
|
mem_max = node['maxmem'] / (1024**3)
|
|
mem_pct = (node['mem'] / node['maxmem']) * 100 if node['maxmem'] > 0 else 0
|
|
disk_used = node['disk'] / (1024**3)
|
|
disk_max = node['maxdisk'] / (1024**3)
|
|
disk_pct = (node['disk'] / node['maxdisk']) * 100 if node['maxdisk'] > 0 else 0
|
|
status = "🟢" if node['status'] == 'online' else "🔴"
|
|
print(f"{node['node']:<10} {cpu_pct:>6.2f}% {mem_used:>6.1f}/{mem_max:>6.1f}GB {mem_pct:>5.1f}% {disk_used:>6.1f}/{disk_max:>6.1f}GB {disk_pct:>5.1f}% {status}")
|
|
except Exception as e:
|
|
print(f"Error parsing node data: {e}", file=sys.stderr)
|
|
PYEOF
|
|
else
|
|
log_error "Failed to get node information"
|
|
fi
|
|
echo ""
|
|
|
|
# Get container distribution per node
|
|
log_info "Container Distribution by Node:"
|
|
echo ""
|
|
|
|
for node in ml110 pve pve2; do
|
|
log_header "NODE" "$node"
|
|
containers_json=$(ssh_proxmox "pvesh get /nodes/$node/lxc --output-format json" 2>&1)
|
|
|
|
if [[ -n "$containers_json" ]]; then
|
|
echo "$containers_json" | python3 << 'PYEOF'
|
|
import sys, json
|
|
try:
|
|
response = sys.stdin.read()
|
|
if not response or response.strip() == '':
|
|
print(" No containers found")
|
|
sys.exit(0)
|
|
|
|
data = json.loads(response)
|
|
if 'data' in data and isinstance(data['data'], list):
|
|
containers = sorted(data['data'], key=lambda x: x['vmid'])
|
|
if containers:
|
|
print(f"{'VMID':<6} {'Name':<35} {'Status':<12}")
|
|
print("-" * 55)
|
|
for c in containers:
|
|
vmid = str(c['vmid'])
|
|
name = (c.get('name', 'N/A') or 'N/A')[:35]
|
|
status = c.get('status', 'unknown')
|
|
status_icon = "🟢" if status == "running" else "🔴" if status == "stopped" else "🟡"
|
|
print(f"{vmid:<6} {name:<35} {status_icon} {status}")
|
|
print(f"\nTotal: {len(containers)} containers")
|
|
else:
|
|
print(" No containers found")
|
|
else:
|
|
print(" No containers found (empty data)")
|
|
except json.JSONDecodeError as e:
|
|
print(f" Error parsing JSON: {e}")
|
|
print(f" Response: {response[:200]}")
|
|
except Exception as e:
|
|
print(f" Error: {e}")
|
|
PYEOF
|
|
else
|
|
echo " Error retrieving containers"
|
|
fi
|
|
echo ""
|
|
done
|
|
|
|
# Migration recommendations
|
|
log_info "Migration Recommendations:"
|
|
echo ""
|
|
echo "📊 Resource Analysis:"
|
|
echo " - ml110: Heavy load (28.3% RAM used, 9.4% CPU)"
|
|
echo " - pve2: Almost empty (1.8% RAM, 0.06% CPU) - IDEAL for migration target"
|
|
echo " - pve: Light load (1.1% RAM, 0.20% CPU)"
|
|
echo ""
|
|
|
|
echo "🎯 Priority 1 - High Resource Containers (move to pve2):"
|
|
echo " - Besu validators (1000-1004) - High CPU/memory usage"
|
|
echo " - Besu RPC nodes (2500-2502) - High memory usage (16GB each)"
|
|
echo " - Blockscout (5000) - Database intensive"
|
|
echo ""
|
|
|
|
echo "🎯 Priority 2 - Medium Priority:"
|
|
echo " - Besu sentries (1500-1503) - Moderate resource usage"
|
|
echo " - Service containers (3500-3501) - Oracle, CCIP monitor"
|
|
echo " - Firefly (6200) - Moderate resources"
|
|
echo ""
|
|
|
|
echo "🔒 Priority 3 - Keep on ml110 (infrastructure):"
|
|
echo " - Infrastructure services (100-105) - proxmox-mail-gateway, cloudflared, omada, gitea, nginx"
|
|
echo " - Monitoring (130) - Keep on primary node"
|
|
echo " - These are core infrastructure and should remain on primary node"
|
|
echo ""
|
|
|
|
log_success "Analysis complete!"
|
|
echo ""
|
|
log_info "Next steps:"
|
|
echo " 1. Review migration plan above"
|
|
echo " 2. Run: ./scripts/migrate-containers-to-pve2.sh to execute migrations"
|
|
echo " 3. Verify containers after migration"
|
|
echo ""
|