docs: restructure website, optimize HTML, gitignore private files
Website docs (website/docs/): - Delete 6 stale -md.html duplicates - Rename docs-clients/miners/developers → clients/miners/developers.html - Unify header/nav across all 15 pages (new .site-header pattern) - Fix 34 dead href=# links with real targets - Upgrade Font Awesome v4→v6 in index.html - Replace search stub with live client-side search (15-page index) - Extract all inline CSS into shared docs.css (+630 lines) - Extract inline theme JS into shared theme.js - Strip inline style= attributes from 10+ pages - Add .announce-banner, .source-links, .search-results CSS classes - Add Markdown Source links to clients/miners/developers pages - Update components.html title to Architecture & Components - Move browser-wallet.html to website/wallet/, leave redirect - Update all dates to February 2026 Website root: - Delete 6 root-level duplicate HTML files (160KB saved) - Rewire index.html and 404.html links Root README.md: - Fix 8 broken doc links to new numbered folder structure - Update copyright to 2026 .gitignore + .example files: - Gitignore private files: .aitbc.yaml, .env, deploy scripts, GPU scripts, service scripts, infra configs, .windsurf/, website README - Create 7 .example files for GitHub users with sanitized templates - Untrack 47 previously committed private files Live server: - Push all website files to aitbc-cascade:/var/www/html/ - Clean stale admin.html and index.nginx-debian.html
This commit is contained in:
@@ -1,24 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Clean up failed deployment and prepare for redeployment
|
||||
|
||||
echo "🧹 Cleaning up failed deployment..."
|
||||
echo "=================================="
|
||||
|
||||
# Stop any running services
|
||||
echo "Stopping services..."
|
||||
ssh ns3-root "systemctl stop blockchain-node blockchain-rpc nginx 2>/dev/null || true"
|
||||
|
||||
# Remove old directories
|
||||
echo "Removing old directories..."
|
||||
ssh ns3-root "rm -rf /opt/blockchain-node /opt/blockchain-node-src /opt/blockchain-explorer 2>/dev/null || true"
|
||||
|
||||
# Remove systemd services
|
||||
echo "Removing systemd services..."
|
||||
ssh ns3-root "systemctl disable blockchain-node blockchain-rpc blockchain-explorer 2>/dev/null || true"
|
||||
ssh ns3-root "rm -f /etc/systemd/system/blockchain-node.service /etc/systemd/system/blockchain-rpc.service /etc/systemd/system/blockchain-explorer.service 2>/dev/null || true"
|
||||
ssh ns3-root "systemctl daemon-reload"
|
||||
|
||||
echo "✅ Cleanup complete!"
|
||||
echo ""
|
||||
echo "You can now run: ./scripts/deploy/deploy-all-remote.sh"
|
||||
@@ -1,109 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Deploy AITBC services to incus container
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import time
|
||||
import sys
|
||||
|
||||
def run_command(cmd, container=None):
|
||||
"""Run command locally or in container"""
|
||||
if container:
|
||||
cmd = f"incus exec {container} -- {cmd}"
|
||||
print(f"Running: {cmd}")
|
||||
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
print(f"Error: {result.stderr}")
|
||||
return False
|
||||
return True
|
||||
|
||||
def deploy_to_container():
|
||||
container = "aitbc"
|
||||
container_ip = "10.1.223.93"
|
||||
|
||||
print("🚀 Deploying AITBC services to container...")
|
||||
|
||||
# Stop local services
|
||||
print("\n📋 Stopping local services...")
|
||||
subprocess.run("sudo fuser -k 8000/tcp 2>/dev/null || true", shell=True)
|
||||
subprocess.run("sudo fuser -k 9080/tcp 2>/dev/null || true", shell=True)
|
||||
subprocess.run("pkill -f 'marketplace-ui' 2>/dev/null || true", shell=True)
|
||||
subprocess.run("pkill -f 'trade-exchange' 2>/dev/null || true", shell=True)
|
||||
|
||||
# Copy project to container
|
||||
print("\n📁 Copying project to container...")
|
||||
subprocess.run(f"incus file push -r /home/oib/windsurf/aitbc {container}/home/oib/", shell=True)
|
||||
|
||||
# Setup Python environment in container
|
||||
print("\n🐍 Setting up Python environment...")
|
||||
run_command("cd /home/oib/aitbc && python3 -m venv .venv", container)
|
||||
run_command("cd /home/oib/aitbc && source .venv/bin/activate && pip install fastapi uvicorn httpx sqlmodel", container)
|
||||
|
||||
# Install dependencies
|
||||
print("\n📦 Installing dependencies...")
|
||||
run_command("cd /home/oib/aitbc/apps/coordinator-api && source ../../.venv/bin/activate && pip install -e .", container)
|
||||
run_command("cd /home/oib/aitbc/apps/blockchain-node && source ../../.venv/bin/activate && pip install -e .", container)
|
||||
|
||||
# Create startup script
|
||||
print("\n🔧 Creating startup script...")
|
||||
startup_script = """#!/bin/bash
|
||||
cd /home/oib/aitbc
|
||||
|
||||
# Start blockchain node
|
||||
echo "Starting blockchain node..."
|
||||
cd apps/blockchain-node
|
||||
source ../../.venv/bin/activate
|
||||
python -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 9080 &
|
||||
NODE_PID=$!
|
||||
|
||||
# Start coordinator API
|
||||
echo "Starting coordinator API..."
|
||||
cd ../coordinator-api
|
||||
source ../../.venv/bin/activate
|
||||
python -m uvicorn src.app.main:app --host 0.0.0.0 --port 8000 &
|
||||
COORD_PID=$!
|
||||
|
||||
# Start marketplace UI
|
||||
echo "Starting marketplace UI..."
|
||||
cd ../marketplace-ui
|
||||
python server.py --port 3001 &
|
||||
MARKET_PID=$!
|
||||
|
||||
# Start trade exchange
|
||||
echo "Starting trade exchange..."
|
||||
cd ../trade-exchange
|
||||
python server.py --port 3002 &
|
||||
EXCHANGE_PID=$!
|
||||
|
||||
echo "Services started!"
|
||||
echo "Blockchain: http://10.1.223.93:9080"
|
||||
echo "API: http://10.1.223.93:8000"
|
||||
echo "Marketplace: http://10.1.223.93:3001"
|
||||
echo "Exchange: http://10.1.223.93:3002"
|
||||
|
||||
# Wait for services
|
||||
wait $NODE_PID $COORD_PID $MARKET_PID $EXCHANGE_PID
|
||||
"""
|
||||
|
||||
# Write startup script to container
|
||||
with open('/tmp/start_aitbc.sh', 'w') as f:
|
||||
f.write(startup_script)
|
||||
|
||||
subprocess.run("incus file push /tmp/start_aitbc.sh aitbc/home/oib/", shell=True)
|
||||
run_command("chmod +x /home/oib/start_aitbc.sh", container)
|
||||
|
||||
# Start services
|
||||
print("\n🚀 Starting AITBC services...")
|
||||
run_command("/home/oib/start_aitbc.sh", container)
|
||||
|
||||
print(f"\n✅ Services deployed to container!")
|
||||
print(f"\n📋 Access URLs:")
|
||||
print(f" 🌐 Container IP: {container_ip}")
|
||||
print(f" 📊 Marketplace: http://{container_ip}:3001")
|
||||
print(f" 💱 Trade Exchange: http://{container_ip}:3002")
|
||||
print(f" 🔗 API: http://{container_ip}:8000")
|
||||
print(f" ⛓️ Blockchain: http://{container_ip}:9080")
|
||||
|
||||
if __name__ == "__main__":
|
||||
deploy_to_container()
|
||||
@@ -1,56 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy blockchain node and explorer by building directly on ns3
|
||||
|
||||
echo "🚀 AITBC Remote Deployment (Build on Server)"
|
||||
echo "=========================================="
|
||||
echo "This will build the blockchain node directly on ns3"
|
||||
echo "to utilize the gigabit connection instead of uploading."
|
||||
echo ""
|
||||
|
||||
# Copy deployment scripts to server
|
||||
echo "Copying deployment scripts to ns3..."
|
||||
scp scripts/deploy/deploy-blockchain-remote.sh ns3-root:/opt/
|
||||
scp scripts/deploy/deploy-explorer-remote.sh ns3-root:/opt/
|
||||
|
||||
# Create directories on server first
|
||||
echo "Creating directories on ns3..."
|
||||
ssh ns3-root "mkdir -p /opt/blockchain-node-src /opt/blockchain-node"
|
||||
|
||||
# Copy blockchain source code to server (excluding data files)
|
||||
echo "Copying blockchain source code to ns3..."
|
||||
rsync -av --exclude='data/' --exclude='*.db' --exclude='__pycache__' --exclude='.venv' apps/blockchain-node/ ns3-root:/opt/blockchain-node-src/
|
||||
|
||||
# Execute blockchain deployment
|
||||
echo ""
|
||||
echo "Deploying blockchain node..."
|
||||
ssh ns3-root "cd /opt && cp -r /opt/blockchain-node-src/* /opt/blockchain-node/ && cd /opt/blockchain-node && chmod +x ../deploy-blockchain-remote.sh && ../deploy-blockchain-remote.sh"
|
||||
|
||||
# Wait for blockchain to start
|
||||
echo ""
|
||||
echo "Waiting 10 seconds for blockchain node to start..."
|
||||
sleep 10
|
||||
|
||||
# Execute explorer deployment on ns3
|
||||
echo ""
|
||||
echo "Deploying blockchain explorer..."
|
||||
ssh ns3-root "cd /opt && ./deploy-explorer-remote.sh"
|
||||
|
||||
# Check services
|
||||
echo ""
|
||||
echo "Checking service status..."
|
||||
ssh ns3-root "systemctl status blockchain-node blockchain-rpc nginx --no-pager | grep -E 'Active:|Main PID:'"
|
||||
|
||||
echo ""
|
||||
echo "✅ Deployment complete!"
|
||||
echo ""
|
||||
echo "Services:"
|
||||
echo " - Blockchain Node RPC: http://localhost:8082"
|
||||
echo " - Blockchain Explorer: http://localhost:3000"
|
||||
echo ""
|
||||
echo "External access:"
|
||||
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
|
||||
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"
|
||||
echo ""
|
||||
echo "The blockchain node will start syncing automatically."
|
||||
echo "The explorer connects to the local node and displays real-time data."
|
||||
@@ -1,207 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy blockchain node and explorer to incus container
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Deploying Blockchain Node and Explorer"
|
||||
echo "========================================"
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Copy blockchain node to container
|
||||
print_status "Copying blockchain node to container..."
|
||||
ssh ns3-root "rm -rf /opt/blockchain-node 2>/dev/null || true"
|
||||
scp -r apps/blockchain-node ns3-root:/opt/
|
||||
|
||||
# Setup blockchain node in container
|
||||
print_status "Setting up blockchain node..."
|
||||
ssh ns3-root << 'EOF'
|
||||
cd /opt/blockchain-node
|
||||
|
||||
# Create configuration
|
||||
cat > .env << EOL
|
||||
CHAIN_ID=ait-devnet
|
||||
DB_PATH=./data/chain.db
|
||||
RPC_BIND_HOST=0.0.0.0
|
||||
RPC_BIND_PORT=8082
|
||||
P2P_BIND_HOST=0.0.0.0
|
||||
P2P_BIND_PORT=7070
|
||||
PROPOSER_KEY=proposer_key_$(date +%s)
|
||||
MINT_PER_UNIT=1000
|
||||
COORDINATOR_RATIO=0.05
|
||||
GOSSIP_BACKEND=memory
|
||||
EOL
|
||||
|
||||
# Create data directory
|
||||
mkdir -p data/devnet
|
||||
|
||||
# Setup Python environment
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -e .
|
||||
|
||||
# Generate genesis
|
||||
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
|
||||
python scripts/make_genesis.py --output data/devnet/genesis.json --force
|
||||
EOF
|
||||
|
||||
# Create systemd service for blockchain node
|
||||
print_status "Creating systemd service for blockchain node..."
|
||||
ssh ns3-root << 'EOF'
|
||||
cat > /etc/systemd/system/blockchain-node.service << EOL
|
||||
[Unit]
|
||||
Description=AITBC Blockchain Node
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/opt/blockchain-node
|
||||
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
|
||||
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
|
||||
cat > /etc/systemd/system/blockchain-rpc.service << EOL
|
||||
[Unit]
|
||||
Description=AITBC Blockchain RPC API
|
||||
After=blockchain-node.service
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/opt/blockchain-node
|
||||
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
|
||||
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable blockchain-node blockchain-rpc
|
||||
EOF
|
||||
|
||||
# Start blockchain node
|
||||
print_status "Starting blockchain node..."
|
||||
ssh ns3-root "systemctl start blockchain-node blockchain-rpc"
|
||||
|
||||
# Wait for node to start
|
||||
print_status "Waiting for blockchain node to start..."
|
||||
sleep 5
|
||||
|
||||
# Check status
|
||||
print_status "Checking blockchain node status..."
|
||||
ssh ns3-root "systemctl status blockchain-node blockchain-rpc --no-pager | grep -E 'Active:|Main PID:'"
|
||||
|
||||
# Copy explorer to container
|
||||
print_status "Copying blockchain explorer to container..."
|
||||
ssh ns3-root "rm -rf /opt/blockchain-explorer 2>/dev/null || true"
|
||||
scp -r apps/blockchain-explorer ns3-root:/opt/
|
||||
|
||||
# Setup explorer in container
|
||||
print_status "Setting up blockchain explorer..."
|
||||
ssh ns3-root << 'EOF'
|
||||
cd /opt/blockchain-explorer
|
||||
|
||||
# Create Python environment
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
EOF
|
||||
|
||||
# Create systemd service for explorer
|
||||
print_status "Creating systemd service for blockchain explorer..."
|
||||
ssh ns3-root << 'EOF'
|
||||
cat > /etc/systemd/system/blockchain-explorer.service << EOL
|
||||
[Unit]
|
||||
Description=AITBC Blockchain Explorer
|
||||
After=blockchain-rpc.service
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/opt/blockchain-explorer
|
||||
Environment=PATH=/opt/blockchain-explorer/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
ExecStart=/opt/blockchain-explorer/.venv/bin/python3 main.py
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable blockchain-explorer
|
||||
EOF
|
||||
|
||||
# Start explorer
|
||||
print_status "Starting blockchain explorer..."
|
||||
ssh ns3-root "systemctl start blockchain-explorer"
|
||||
|
||||
# Wait for explorer to start
|
||||
print_status "Waiting for explorer to start..."
|
||||
sleep 3
|
||||
|
||||
# Setup port forwarding
|
||||
print_status "Setting up port forwarding..."
|
||||
ssh ns3-root << 'EOF'
|
||||
# Clear existing NAT rules
|
||||
iptables -t nat -F PREROUTING 2>/dev/null || true
|
||||
iptables -t nat -F POSTROUTING 2>/dev/null || true
|
||||
|
||||
# Add port forwarding for blockchain RPC
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
|
||||
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
|
||||
|
||||
# Add port forwarding for explorer
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
|
||||
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
|
||||
|
||||
# Save rules
|
||||
mkdir -p /etc/iptables
|
||||
iptables-save > /etc/iptables/rules.v4
|
||||
|
||||
# Install iptables-persistent for persistence
|
||||
apt-get update
|
||||
apt-get install -y iptables-persistent
|
||||
EOF
|
||||
|
||||
# Check all services
|
||||
print_status "Checking all services..."
|
||||
ssh ns3-root "systemctl status blockchain-node blockchain-rpc blockchain-explorer --no-pager | grep -E 'Active:|Main PID:'"
|
||||
|
||||
print_success "✅ Deployment complete!"
|
||||
echo ""
|
||||
echo "Services deployed:"
|
||||
echo " - Blockchain Node RPC: http://192.168.100.10:8082"
|
||||
echo " - Blockchain Explorer: http://192.168.100.10:3000"
|
||||
echo ""
|
||||
echo "External access:"
|
||||
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
|
||||
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"
|
||||
echo ""
|
||||
echo "The explorer is connected to the local blockchain node and will display"
|
||||
echo "real-time blockchain data including blocks and transactions."
|
||||
@@ -1,94 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy blockchain explorer to incus container
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔍 Deploying Blockchain Explorer"
|
||||
echo "================================="
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Copy explorer to container
|
||||
print_status "Copying blockchain explorer to container..."
|
||||
ssh ns3-root "rm -rf /opt/blockchain-explorer 2>/dev/null || true"
|
||||
scp -r apps/blockchain-explorer ns3-root:/opt/
|
||||
|
||||
# Setup explorer in container
|
||||
print_status "Setting up blockchain explorer..."
|
||||
ssh ns3-root << 'EOF'
|
||||
cd /opt/blockchain-explorer
|
||||
|
||||
# Create Python environment
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
EOF
|
||||
|
||||
# Create systemd service for explorer
|
||||
print_status "Creating systemd service for blockchain explorer..."
|
||||
ssh ns3-root << 'EOF'
|
||||
cat > /etc/systemd/system/blockchain-explorer.service << EOL
|
||||
[Unit]
|
||||
Description=AITBC Blockchain Explorer
|
||||
After=blockchain-rpc.service
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/opt/blockchain-explorer
|
||||
Environment=PATH=/opt/blockchain-explorer/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
ExecStart=/opt/blockchain-explorer/.venv/bin/python3 main.py
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable blockchain-explorer
|
||||
EOF
|
||||
|
||||
# Start explorer
|
||||
print_status "Starting blockchain explorer..."
|
||||
ssh ns3-root "systemctl start blockchain-explorer"
|
||||
|
||||
# Wait for explorer to start
|
||||
print_status "Waiting for explorer to start..."
|
||||
sleep 3
|
||||
|
||||
# Setup port forwarding for explorer
|
||||
print_status "Setting up port forwarding for explorer..."
|
||||
ssh ns3-root << 'EOF'
|
||||
# Add port forwarding for explorer
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
|
||||
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
|
||||
|
||||
# Save rules
|
||||
iptables-save > /etc/iptables/rules.v4
|
||||
EOF
|
||||
|
||||
# Check status
|
||||
print_status "Checking blockchain explorer status..."
|
||||
ssh ns3-root "systemctl status blockchain-explorer --no-pager | grep -E 'Active:|Main PID:'"
|
||||
|
||||
print_success "✅ Blockchain explorer deployed!"
|
||||
echo ""
|
||||
echo "Explorer URL: http://192.168.100.10:3000"
|
||||
echo "External URL: http://aitbc.keisanki.net:3000"
|
||||
echo ""
|
||||
echo "The explorer will automatically connect to the local blockchain node."
|
||||
echo "You can view blocks, transactions, and chain statistics."
|
||||
@@ -1,157 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy blockchain node directly on ns3 server (build in place)
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Deploying Blockchain Node on ns3 (Build in Place)"
|
||||
echo "====================================================="
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if we're on the right server
|
||||
print_status "Checking server..."
|
||||
if [ "$(hostname)" != "ns3" ] && [ "$(hostname)" != "aitbc" ]; then
|
||||
print_warning "This script should be run on ns3 server"
|
||||
echo "Please run: ssh ns3-root"
|
||||
echo "Then: cd /opt && ./deploy-blockchain-remote.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install dependencies if needed
|
||||
print_status "Installing dependencies..."
|
||||
apt-get update
|
||||
apt-get install -y python3 python3-venv python3-pip git curl
|
||||
|
||||
# Create directory
|
||||
print_status "Creating blockchain node directory..."
|
||||
mkdir -p /opt/blockchain-node
|
||||
cd /opt/blockchain-node
|
||||
|
||||
# Check if source code exists
|
||||
if [ ! -d "src" ]; then
|
||||
print_status "Source code not found in /opt/blockchain-node, copying from /opt/blockchain-node-src..."
|
||||
if [ -d "/opt/blockchain-node-src" ]; then
|
||||
cp -r /opt/blockchain-node-src/* .
|
||||
else
|
||||
print_warning "Source code not found. Please ensure it was copied properly."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Setup Python environment
|
||||
print_status "Setting up Python environment..."
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -e .
|
||||
|
||||
# Create configuration with auto-sync
|
||||
print_status "Creating configuration..."
|
||||
cat > .env << EOL
|
||||
CHAIN_ID=ait-devnet
|
||||
DB_PATH=./data/chain.db
|
||||
RPC_BIND_HOST=0.0.0.0
|
||||
RPC_BIND_PORT=8082
|
||||
P2P_BIND_HOST=0.0.0.0
|
||||
P2P_BIND_PORT=7070
|
||||
PROPOSER_KEY=proposer_key_$(date +%s)
|
||||
MINT_PER_UNIT=1000
|
||||
COORDINATOR_RATIO=0.05
|
||||
GOSSIP_BACKEND=memory
|
||||
EOL
|
||||
|
||||
# Create fresh data directory
|
||||
print_status "Creating fresh data directory..."
|
||||
rm -rf data
|
||||
mkdir -p data/devnet
|
||||
|
||||
# Generate fresh genesis
|
||||
print_status "Generating fresh genesis block..."
|
||||
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
|
||||
python scripts/make_genesis.py --output data/devnet/genesis.json --force
|
||||
|
||||
# Create systemd service for blockchain node
|
||||
print_status "Creating systemd services..."
|
||||
cat > /etc/systemd/system/blockchain-node.service << EOL
|
||||
[Unit]
|
||||
Description=AITBC Blockchain Node
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/opt/blockchain-node
|
||||
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
|
||||
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
|
||||
cat > /etc/systemd/system/blockchain-rpc.service << EOL
|
||||
[Unit]
|
||||
Description=AITBC Blockchain RPC API
|
||||
After=blockchain-node.service
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/opt/blockchain-node
|
||||
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
|
||||
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
|
||||
# Enable and start services
|
||||
print_status "Starting blockchain node..."
|
||||
systemctl daemon-reload
|
||||
systemctl enable blockchain-node blockchain-rpc
|
||||
systemctl start blockchain-node blockchain-rpc
|
||||
|
||||
# Wait for services to start
|
||||
print_status "Waiting for services to start..."
|
||||
sleep 5
|
||||
|
||||
# Check status
|
||||
print_status "Checking service status..."
|
||||
systemctl status blockchain-node blockchain-rpc --no-pager | head -15
|
||||
|
||||
# Setup port forwarding if in container
|
||||
if [ "$(hostname)" = "aitbc" ]; then
|
||||
print_status "Setting up port forwarding..."
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
|
||||
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
|
||||
iptables-save > /etc/iptables/rules.v4
|
||||
fi
|
||||
|
||||
print_success "✅ Blockchain node deployed!"
|
||||
echo ""
|
||||
if [ "$(hostname)" = "aitbc" ]; then
|
||||
echo "Node RPC: http://192.168.100.10:8082"
|
||||
echo "External RPC: http://aitbc.keisanki.net:8082"
|
||||
else
|
||||
echo "Node RPC: http://95.216.198.140:8082"
|
||||
echo "External RPC: http://aitbc.keisanki.net:8082"
|
||||
fi
|
||||
echo ""
|
||||
echo "The node will automatically sync on startup."
|
||||
@@ -1,139 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy blockchain node and explorer to incus container
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Deploying Blockchain Node and Explorer"
|
||||
echo "========================================"
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Copy blockchain node to container
|
||||
print_status "Copying blockchain node to container..."
|
||||
ssh ns3-root "rm -rf /opt/blockchain-node 2>/dev/null || true"
|
||||
scp -r apps/blockchain-node ns3-root:/opt/
|
||||
|
||||
# Setup blockchain node in container
|
||||
print_status "Setting up blockchain node..."
|
||||
ssh ns3-root << 'EOF'
|
||||
cd /opt/blockchain-node
|
||||
|
||||
# Create configuration
|
||||
cat > .env << EOL
|
||||
CHAIN_ID=ait-devnet
|
||||
DB_PATH=./data/chain.db
|
||||
RPC_BIND_HOST=0.0.0.0
|
||||
RPC_BIND_PORT=8082
|
||||
P2P_BIND_HOST=0.0.0.0
|
||||
P2P_BIND_PORT=7070
|
||||
PROPOSER_KEY=proposer_key_$(date +%s)
|
||||
MINT_PER_UNIT=1000
|
||||
COORDINATOR_RATIO=0.05
|
||||
GOSSIP_BACKEND=memory
|
||||
EOL
|
||||
|
||||
# Create data directory
|
||||
mkdir -p data/devnet
|
||||
|
||||
# Setup Python environment
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -e .
|
||||
|
||||
# Generate genesis
|
||||
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
|
||||
python scripts/make_genesis.py --output data/devnet/genesis.json --force
|
||||
EOF
|
||||
|
||||
# Create systemd service for blockchain node
|
||||
print_status "Creating systemd service for blockchain node..."
|
||||
ssh ns3-root << 'EOF'
|
||||
cat > /etc/systemd/system/blockchain-node.service << EOL
|
||||
[Unit]
|
||||
Description=AITBC Blockchain Node
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/opt/blockchain-node
|
||||
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
|
||||
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
|
||||
cat > /etc/systemd/system/blockchain-rpc.service << EOL
|
||||
[Unit]
|
||||
Description=AITBC Blockchain RPC API
|
||||
After=blockchain-node.service
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/opt/blockchain-node
|
||||
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
|
||||
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable blockchain-node blockchain-rpc
|
||||
EOF
|
||||
|
||||
# Start blockchain node
|
||||
print_status "Starting blockchain node..."
|
||||
ssh ns3-root "systemctl start blockchain-node blockchain-rpc"
|
||||
|
||||
# Wait for node to start
|
||||
print_status "Waiting for blockchain node to start..."
|
||||
sleep 5
|
||||
|
||||
# Check status
|
||||
print_status "Checking blockchain node status..."
|
||||
ssh ns3-root "systemctl status blockchain-node blockchain-rpc --no-pager | grep -E 'Active:|Main PID:'"
|
||||
|
||||
# Setup port forwarding
|
||||
print_status "Setting up port forwarding..."
|
||||
ssh ns3-root << 'EOF'
|
||||
# Clear existing rules
|
||||
iptables -t nat -F PREROUTING 2>/dev/null || true
|
||||
iptables -t nat -F POSTROUTING 2>/dev/null || true
|
||||
|
||||
# Add port forwarding for blockchain RPC
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
|
||||
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
|
||||
|
||||
# Save rules
|
||||
mkdir -p /etc/iptables
|
||||
iptables-save > /etc/iptables/rules.v4
|
||||
EOF
|
||||
|
||||
print_success "✅ Blockchain node deployed!"
|
||||
echo ""
|
||||
echo "Node RPC: http://192.168.100.10:8082"
|
||||
echo "External RPC: http://aitbc.keisanki.net:8082"
|
||||
echo ""
|
||||
echo "Next: Deploying blockchain explorer..."
|
||||
@@ -1,316 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy blockchain node and explorer directly on ns3
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 AITBC Direct Deployment on ns3"
|
||||
echo "================================="
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if we're on ns3
|
||||
if [ "$(hostname)" != "ns3" ] && [ "$(hostname)" != "aitbc" ]; then
|
||||
print_warning "This script must be run on ns3 server"
|
||||
echo "Run: ssh ns3-root"
|
||||
echo "Then: cd /opt && ./deploy-direct.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Stop existing services
|
||||
print_status "Stopping existing services..."
|
||||
systemctl stop blockchain-node blockchain-rpc blockchain-explorer nginx 2>/dev/null || true
|
||||
|
||||
# Install dependencies
|
||||
print_status "Installing dependencies..."
|
||||
apt-get update
|
||||
apt-get install -y python3 python3-venv python3-pip git curl nginx
|
||||
|
||||
# Deploy blockchain node
|
||||
print_status "Deploying blockchain node..."
|
||||
cd /opt
|
||||
rm -rf blockchain-node
|
||||
cp -r blockchain-node-src blockchain-node
|
||||
cd blockchain-node
|
||||
|
||||
# Create configuration
|
||||
print_status "Creating configuration..."
|
||||
cat > .env << EOL
|
||||
CHAIN_ID=ait-devnet
|
||||
DB_PATH=./data/chain.db
|
||||
RPC_BIND_HOST=0.0.0.0
|
||||
RPC_BIND_PORT=8082
|
||||
P2P_BIND_HOST=0.0.0.0
|
||||
P2P_BIND_PORT=7070
|
||||
PROPOSER_KEY=proposer_key_$(date +%s)
|
||||
MINT_PER_UNIT=1000
|
||||
COORDINATOR_RATIO=0.05
|
||||
GOSSIP_BACKEND=memory
|
||||
EOL
|
||||
|
||||
# Create fresh data directory
|
||||
rm -rf data
|
||||
mkdir -p data/devnet
|
||||
|
||||
# Setup Python environment
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -e .
|
||||
|
||||
# Generate genesis
|
||||
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
|
||||
python scripts/make_genesis.py --output data/devnet/genesis.json --force
|
||||
|
||||
# Create systemd services
|
||||
print_status "Creating systemd services..."
|
||||
cat > /etc/systemd/system/blockchain-node.service << EOL
|
||||
[Unit]
|
||||
Description=AITBC Blockchain Node
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/opt/blockchain-node
|
||||
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
|
||||
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
|
||||
cat > /etc/systemd/system/blockchain-rpc.service << EOL
|
||||
[Unit]
|
||||
Description=AITBC Blockchain RPC API
|
||||
After=blockchain-node.service
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/opt/blockchain-node
|
||||
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
|
||||
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
|
||||
# Start blockchain services
|
||||
print_status "Starting blockchain services..."
|
||||
systemctl daemon-reload
|
||||
systemctl enable blockchain-node blockchain-rpc
|
||||
systemctl start blockchain-node blockchain-rpc
|
||||
|
||||
# Deploy explorer
|
||||
print_status "Deploying blockchain explorer..."
|
||||
cd /opt
|
||||
rm -rf blockchain-explorer
|
||||
mkdir -p blockchain-explorer
|
||||
cd blockchain-explorer
|
||||
|
||||
# Create HTML explorer
|
||||
cat > index.html << 'EOF'
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>AITBC Blockchain Explorer</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
</head>
|
||||
<body class="bg-gray-50">
|
||||
<header class="bg-blue-600 text-white shadow-lg">
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i data-lucide="cube" class="w-8 h-8"></i>
|
||||
<h1 class="text-2xl font-bold">AITBC Blockchain Explorer</h1>
|
||||
</div>
|
||||
<button onclick="refreshData()" class="bg-blue-500 hover:bg-blue-400 px-3 py-1 rounded flex items-center space-x-1">
|
||||
<i data-lucide="refresh-cw" class="w-4 h-4"></i>
|
||||
<span>Refresh</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container mx-auto px-4 py-8">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-gray-500 text-sm">Current Height</p>
|
||||
<p class="text-2xl font-bold" id="chain-height">-</p>
|
||||
</div>
|
||||
<i data-lucide="trending-up" class="w-10 h-10 text-green-500"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-gray-500 text-sm">Latest Block</p>
|
||||
<p class="text-lg font-mono" id="latest-hash">-</p>
|
||||
</div>
|
||||
<i data-lucide="hash" class="w-10 h-10 text-blue-500"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-gray-500 text-sm">Node Status</p>
|
||||
<p class="text-lg font-semibold" id="node-status">-</p>
|
||||
</div>
|
||||
<i data-lucide="activity" class="w-10 h-10 text-purple-500"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-lg shadow">
|
||||
<div class="px-6 py-4 border-b">
|
||||
<h2 class="text-xl font-semibold flex items-center">
|
||||
<i data-lucide="blocks" class="w-5 h-5 mr-2"></i>
|
||||
Latest Blocks
|
||||
</h2>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="text-left text-gray-500 text-sm">
|
||||
<th class="pb-3">Height</th>
|
||||
<th class="pb-3">Hash</th>
|
||||
<th class="pb-3">Timestamp</th>
|
||||
<th class="pb-3">Transactions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="blocks-table">
|
||||
<tr>
|
||||
<td colspan="4" class="text-center py-8 text-gray-500">
|
||||
Loading blocks...
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
|
||||
const RPC_URL = 'http://localhost:8082';
|
||||
|
||||
async function refreshData() {
|
||||
try {
|
||||
const response = await fetch(`${RPC_URL}/rpc/head`);
|
||||
const head = await response.json();
|
||||
|
||||
document.getElementById('chain-height').textContent = head.height || '-';
|
||||
document.getElementById('latest-hash').textContent = head.hash ? head.hash.substring(0, 16) + '...' : '-';
|
||||
document.getElementById('node-status').innerHTML = '<span class="text-green-500">Online</span>';
|
||||
|
||||
// Load last 10 blocks
|
||||
const tbody = document.getElementById('blocks-table');
|
||||
tbody.innerHTML = '';
|
||||
|
||||
for (let i = 0; i < 10 && head.height - i >= 0; i++) {
|
||||
const blockResponse = await fetch(`${RPC_URL}/rpc/blocks/${head.height - i}`);
|
||||
const block = await blockResponse.json();
|
||||
|
||||
const row = tbody.insertRow();
|
||||
row.innerHTML = `
|
||||
<td class="py-3 font-mono">${block.height}</td>
|
||||
<td class="py-3 font-mono text-sm">${block.hash ? block.hash.substring(0, 16) + '...' : '-'}</td>
|
||||
<td class="py-3 text-sm">${new Date(block.timestamp * 1000).toLocaleString()}</td>
|
||||
<td class="py-3">${block.transactions ? block.transactions.length : 0}</td>
|
||||
`;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
document.getElementById('node-status').innerHTML = '<span class="text-red-500">Error</span>';
|
||||
}
|
||||
}
|
||||
|
||||
refreshData();
|
||||
setInterval(refreshData, 30000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
# Configure nginx
|
||||
print_status "Configuring nginx..."
|
||||
cat > /etc/nginx/sites-available/blockchain-explorer << EOL
|
||||
server {
|
||||
listen 3000;
|
||||
server_name _;
|
||||
root /opt/blockchain-explorer;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files \$uri \$uri/ =404;
|
||||
}
|
||||
}
|
||||
EOL
|
||||
|
||||
ln -sf /etc/nginx/sites-available/blockchain-explorer /etc/nginx/sites-enabled/
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
nginx -t
|
||||
systemctl reload nginx
|
||||
|
||||
# Setup port forwarding if in container
|
||||
if [ "$(hostname)" = "aitbc" ]; then
|
||||
print_status "Setting up port forwarding..."
|
||||
iptables -t nat -F PREROUTING 2>/dev/null || true
|
||||
iptables -t nat -F POSTROUTING 2>/dev/null || true
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
|
||||
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
|
||||
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
|
||||
iptables-save > /etc/iptables/rules.v4
|
||||
fi
|
||||
|
||||
# Wait for services to start
|
||||
print_status "Waiting for services to start..."
|
||||
sleep 5
|
||||
|
||||
# Check services
|
||||
print_status "Checking service status..."
|
||||
systemctl status blockchain-node blockchain-rpc nginx --no-pager | grep -E 'Active:|Main PID:'
|
||||
|
||||
print_success "✅ Deployment complete!"
|
||||
echo ""
|
||||
echo "Services:"
|
||||
if [ "$(hostname)" = "aitbc" ]; then
|
||||
echo " - Blockchain Node RPC: http://192.168.100.10:8082"
|
||||
echo " - Blockchain Explorer: http://192.168.100.10:3000"
|
||||
echo ""
|
||||
echo "External access:"
|
||||
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
|
||||
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"
|
||||
else
|
||||
echo " - Blockchain Node RPC: http://localhost:8082"
|
||||
echo " - Blockchain Explorer: http://localhost:3000"
|
||||
echo ""
|
||||
echo "External access:"
|
||||
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
|
||||
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"
|
||||
fi
|
||||
@@ -1,88 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy AITBC services to domain https://aitbc.bubuit.net
|
||||
|
||||
set -e
|
||||
|
||||
DOMAIN="aitbc.bubuit.net"
|
||||
CONTAINER="aitbc"
|
||||
|
||||
echo "🚀 Deploying AITBC services to https://$DOMAIN"
|
||||
echo ""
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Stop local services
|
||||
print_status "Stopping local services..."
|
||||
sudo fuser -k 8000/tcp 2>/dev/null || true
|
||||
sudo fuser -k 9080/tcp 2>/dev/null || true
|
||||
sudo fuser -k 3001/tcp 2>/dev/null || true
|
||||
sudo fuser -k 3002/tcp 2>/dev/null || true
|
||||
|
||||
# Deploy to container
|
||||
print_status "Deploying to container..."
|
||||
python /home/oib/windsurf/aitbc/container-deploy.py
|
||||
|
||||
# Copy nginx config to container
|
||||
print_status "Configuring nginx for domain..."
|
||||
incus file push /home/oib/windsurf/aitbc/nginx-aitbc.conf $CONTAINER/etc/nginx/sites-available/aitbc
|
||||
|
||||
# Enable site
|
||||
incus exec $CONTAINER -- ln -sf /etc/nginx/sites-available/aitbc /etc/nginx/sites-enabled/
|
||||
incus exec $CONTAINER -- rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Test nginx config
|
||||
incus exec $CONTAINER -- nginx -t
|
||||
|
||||
# Reload nginx
|
||||
incus exec $CONTAINER -- systemctl reload nginx
|
||||
|
||||
# Install SSL certificate (Let's Encrypt)
|
||||
print_warning "SSL Certificate Setup:"
|
||||
echo "1. Ensure port 80/443 are forwarded to container IP (10.1.223.93)"
|
||||
echo "2. Run certbot in container:"
|
||||
echo " incus exec $CONTAINER -- certbot --nginx -d $DOMAIN"
|
||||
echo ""
|
||||
|
||||
# Update UIs to use correct API endpoints
|
||||
print_status "Updating API endpoints..."
|
||||
|
||||
# Update marketplace API base URL
|
||||
incus exec $CONTAINER -- sed -i "s|http://127.0.0.1:8000|https://$DOMAIN/api|g" /home/oib/aitbc/apps/marketplace-ui/index.html
|
||||
|
||||
# Update exchange API endpoints
|
||||
incus exec $CONTAINER -- sed -i "s|http://127.0.0.1:8000|https://$DOMAIN/api|g" /home/oib/aitbc/apps/trade-exchange/index.html
|
||||
incus exec $CONTAINER -- sed -i "s|http://127.0.0.1:9080|https://$DOMAIN/rpc|g" /home/oib/aitbc/apps/trade-exchange/index.html
|
||||
|
||||
# Restart services to apply changes
|
||||
print_status "Restarting services..."
|
||||
incus exec $CONTAINER -- pkill -f "server.py"
|
||||
sleep 2
|
||||
incus exec $CONTAINER -- /home/oib/start_aitbc.sh
|
||||
|
||||
echo ""
|
||||
print_status "✅ Deployment complete!"
|
||||
echo ""
|
||||
echo "📋 Service URLs:"
|
||||
echo " 🌐 Domain: https://$DOMAIN"
|
||||
echo " 📊 Marketplace: https://$DOMAIN/Marketplace"
|
||||
echo " 💱 Trade Exchange: https://$DOMAIN/Exchange"
|
||||
echo " 🔗 API: https://$DOMAIN/api"
|
||||
echo " ⛓️ Blockchain RPC: https://$DOMAIN/rpc"
|
||||
echo ""
|
||||
echo "📝 Next Steps:"
|
||||
echo "1. Forward ports 80/443 to container IP (10.1.223.93)"
|
||||
echo "2. Install SSL certificate:"
|
||||
echo " incus exec $CONTAINER -- certbot --nginx -d $DOMAIN"
|
||||
echo "3. Test services at the URLs above"
|
||||
@@ -1,74 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy AITBC Trade Exchange to the server
|
||||
|
||||
set -e
|
||||
|
||||
SERVER="root@10.1.223.93"
|
||||
EXCHANGE_DIR="/root/aitbc/apps/trade-exchange"
|
||||
|
||||
echo "🚀 Deploying AITBC Trade Exchange"
|
||||
echo "=================================="
|
||||
echo "Server: $SERVER"
|
||||
echo ""
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Test SSH connection
|
||||
print_status "Testing SSH connection..."
|
||||
ssh $SERVER "hostname && ip a show eth0 | grep inet"
|
||||
|
||||
# Copy updated files
|
||||
print_status "Copying updated Exchange files..."
|
||||
scp /home/oib/windsurf/aitbc/apps/trade-exchange/index.html $SERVER:$EXCHANGE_DIR/
|
||||
scp /home/oib/windsurf/aitbc/apps/trade-exchange/server.py $SERVER:$EXCHANGE_DIR/
|
||||
|
||||
# Ensure assets are available
|
||||
print_status "Ensuring assets directory exists..."
|
||||
ssh $SERVER "mkdir -p /var/www/aitbc.bubuit.net/assets"
|
||||
ssh $SERVER "mkdir -p /var/www/aitbc.bubuit.net/assets/css"
|
||||
ssh $SERVER "mkdir -p /var/www/aitbc.bubuit.net/assets/js"
|
||||
|
||||
# Copy assets if they don't exist
|
||||
print_status "Copying assets if needed..."
|
||||
if ! ssh $SERVER "test -f /var/www/aitbc.bubuit.net/assets/css/aitbc.css"; then
|
||||
scp -r /home/oib/windsurf/aitbc/assets/* $SERVER:/var/www/aitbc.bubuit.net/assets/
|
||||
fi
|
||||
|
||||
# Restart the exchange service
|
||||
print_status "Restarting Trade Exchange service..."
|
||||
ssh $SERVER "systemctl restart aitbc-exchange"
|
||||
|
||||
# Wait for service to start
|
||||
print_status "Waiting for service to start..."
|
||||
sleep 5
|
||||
|
||||
# Check service status
|
||||
print_status "Checking service status..."
|
||||
ssh $SERVER "systemctl status aitbc-exchange --no-pager -l | head -10"
|
||||
|
||||
# Test the endpoint
|
||||
print_status "Testing Exchange endpoint..."
|
||||
ssh $SERVER "curl -s http://127.0.0.1:3002/ | head -c 100"
|
||||
echo ""
|
||||
|
||||
echo ""
|
||||
print_status "✅ Exchange deployment complete!"
|
||||
echo ""
|
||||
echo "📋 URLs:"
|
||||
echo " 🌐 IP: http://10.1.223.93/Exchange"
|
||||
echo " 🔒 Domain: https://aitbc.bubuit.net/Exchange"
|
||||
echo ""
|
||||
echo "🔍 To check logs:"
|
||||
echo " ssh $SERVER 'journalctl -u aitbc-exchange -f'"
|
||||
@@ -1,396 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy blockchain explorer directly on ns3 server
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔍 Deploying Blockchain Explorer on ns3"
|
||||
echo "======================================"
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if we're on the right server
|
||||
if [ "$(hostname)" != "ns3" ] && [ "$(hostname)" != "aitbc" ]; then
|
||||
print_warning "This script should be run on ns3 server"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create directory
|
||||
print_status "Creating blockchain explorer directory..."
|
||||
mkdir -p /opt/blockchain-explorer
|
||||
cd /opt/blockchain-explorer
|
||||
|
||||
# Create a simple HTML-based explorer (no build needed)
|
||||
print_status "Creating web-based explorer..."
|
||||
cat > index.html << 'EOF'
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>AITBC Blockchain Explorer</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
.fade-in { animation: fadeIn 0.3s ease-in; }
|
||||
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-50">
|
||||
<header class="bg-blue-600 text-white shadow-lg">
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i data-lucide="cube" class="w-8 h-8"></i>
|
||||
<h1 class="text-2xl font-bold">AITBC Blockchain Explorer</h1>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<span class="text-sm">Network: <span class="font-mono bg-blue-700 px-2 py-1 rounded">ait-devnet</span></span>
|
||||
<button onclick="refreshData()" class="bg-blue-500 hover:bg-blue-400 px-3 py-1 rounded flex items-center space-x-1">
|
||||
<i data-lucide="refresh-cw" class="w-4 h-4"></i>
|
||||
<span>Refresh</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container mx-auto px-4 py-8">
|
||||
<!-- Chain Stats -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-gray-500 text-sm">Current Height</p>
|
||||
<p class="text-2xl font-bold" id="chain-height">-</p>
|
||||
</div>
|
||||
<i data-lucide="trending-up" class="w-10 h-10 text-green-500"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-gray-500 text-sm">Latest Block</p>
|
||||
<p class="text-lg font-mono" id="latest-hash">-</p>
|
||||
</div>
|
||||
<i data-lucide="hash" class="w-10 h-10 text-blue-500"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-gray-500 text-sm">Node Status</p>
|
||||
<p class="text-lg font-semibold" id="node-status">-</p>
|
||||
</div>
|
||||
<i data-lucide="activity" class="w-10 h-10 text-purple-500"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Search -->
|
||||
<div class="bg-white rounded-lg shadow p-6 mb-8">
|
||||
<div class="flex space-x-4">
|
||||
<input type="text" id="search-input" placeholder="Search by block height, hash, or transaction hash"
|
||||
class="flex-1 px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
<button onclick="search()" class="bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700">
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Latest Blocks -->
|
||||
<div class="bg-white rounded-lg shadow">
|
||||
<div class="px-6 py-4 border-b">
|
||||
<h2 class="text-xl font-semibold flex items-center">
|
||||
<i data-lucide="blocks" class="w-5 h-5 mr-2"></i>
|
||||
Latest Blocks
|
||||
</h2>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="text-left text-gray-500 text-sm">
|
||||
<th class="pb-3">Height</th>
|
||||
<th class="pb-3">Hash</th>
|
||||
<th class="pb-3">Timestamp</th>
|
||||
<th class="pb-3">Transactions</th>
|
||||
<th class="pb-3">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="blocks-table">
|
||||
<tr>
|
||||
<td colspan="5" class="text-center py-8 text-gray-500">
|
||||
Loading blocks...
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Block Details Modal -->
|
||||
<div id="block-modal" class="fixed inset-0 bg-black bg-opacity-50 hidden z-50">
|
||||
<div class="flex items-center justify-center min-h-screen p-4">
|
||||
<div class="bg-white rounded-lg max-w-4xl w-full max-h-[90vh] overflow-y-auto">
|
||||
<div class="p-6 border-b">
|
||||
<div class="flex justify-between items-center">
|
||||
<h2 class="text-2xl font-bold">Block Details</h2>
|
||||
<button onclick="closeModal()" class="text-gray-500 hover:text-gray-700">
|
||||
<i data-lucide="x" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-6" id="block-details">
|
||||
<!-- Block details will be loaded here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-gray-800 text-white mt-12">
|
||||
<div class="container mx-auto px-4 py-6 text-center">
|
||||
<p class="text-sm">AITBC Blockchain Explorer - Connected to node at http://localhost:8082</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
// Initialize lucide icons
|
||||
lucide.createIcons();
|
||||
|
||||
// RPC URL - change based on environment
|
||||
const RPC_URL = window.location.hostname === 'localhost' ?
|
||||
'http://localhost:8082' :
|
||||
'http://95.216.198.140:8082';
|
||||
|
||||
// Global state
|
||||
let currentData = {};
|
||||
|
||||
// Load initial data
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
refreshData();
|
||||
});
|
||||
|
||||
// Refresh all data
|
||||
async function refreshData() {
|
||||
try {
|
||||
await Promise.all([
|
||||
loadChainStats(),
|
||||
loadLatestBlocks()
|
||||
]);
|
||||
} catch (error) {
|
||||
console.error('Error refreshing data:', error);
|
||||
document.getElementById('node-status').innerHTML = '<span class="text-red-500">Error</span>';
|
||||
}
|
||||
}
|
||||
|
||||
// Load chain statistics
|
||||
async function loadChainStats() {
|
||||
const response = await fetch(`${RPC_URL}/rpc/head`);
|
||||
const data = await response.json();
|
||||
|
||||
document.getElementById('chain-height').textContent = data.height || '-';
|
||||
document.getElementById('latest-hash').textContent = data.hash ? data.hash.substring(0, 16) + '...' : '-';
|
||||
document.getElementById('node-status').innerHTML = '<span class="text-green-500">Online</span>';
|
||||
|
||||
currentData.head = data;
|
||||
}
|
||||
|
||||
// Load latest blocks
|
||||
async function loadLatestBlocks() {
|
||||
const tbody = document.getElementById('blocks-table');
|
||||
tbody.innerHTML = '<tr><td colspan="5" class="text-center py-8 text-gray-500">Loading blocks...</td></tr>';
|
||||
|
||||
const head = await fetch(`${RPC_URL}/rpc/head`).then(r => r.json());
|
||||
const blocks = [];
|
||||
|
||||
// Load last 10 blocks
|
||||
for (let i = 0; i < 10 && head.height - i >= 0; i++) {
|
||||
const block = await fetch(`${RPC_URL}/rpc/blocks/${head.height - i}`).then(r => r.json());
|
||||
blocks.push(block);
|
||||
}
|
||||
|
||||
tbody.innerHTML = blocks.map(block => `
|
||||
<tr class="border-t hover:bg-gray-50">
|
||||
<td class="py-3 font-mono">${block.height}</td>
|
||||
<td class="py-3 font-mono text-sm">${block.hash ? block.hash.substring(0, 16) + '...' : '-'}</td>
|
||||
<td class="py-3 text-sm">${formatTimestamp(block.timestamp)}</td>
|
||||
<td class="py-3">${block.transactions ? block.transactions.length : 0}</td>
|
||||
<td class="py-3">
|
||||
<button onclick="showBlockDetails(${block.height})" class="text-blue-600 hover:text-blue-800">
|
||||
View Details
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
// Show block details
|
||||
async function showBlockDetails(height) {
|
||||
const block = await fetch(`${RPC_URL}/rpc/blocks/${height}`).then(r => r.json());
|
||||
const modal = document.getElementById('block-modal');
|
||||
const details = document.getElementById('block-details');
|
||||
|
||||
details.innerHTML = `
|
||||
<div class="space-y-6">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold mb-2">Block Header</h3>
|
||||
<div class="bg-gray-50 rounded p-4 space-y-2">
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-600">Height:</span>
|
||||
<span class="font-mono">${block.height}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-600">Hash:</span>
|
||||
<span class="font-mono text-sm">${block.hash || '-'}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-600">Parent Hash:</span>
|
||||
<span class="font-mono text-sm">${block.parent_hash || '-'}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-600">Timestamp:</span>
|
||||
<span>${formatTimestamp(block.timestamp)}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-600">Proposer:</span>
|
||||
<span class="font-mono text-sm">${block.proposer || '-'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${block.transactions && block.transactions.length > 0 ? `
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold mb-2">Transactions (${block.transactions.length})</h3>
|
||||
<div class="space-y-2">
|
||||
${block.transactions.map(tx => `
|
||||
<div class="bg-gray-50 rounded p-4">
|
||||
<div class="flex justify-between mb-2">
|
||||
<span class="text-gray-600">Hash:</span>
|
||||
<span class="font-mono text-sm">${tx.hash || '-'}</span>
|
||||
</div>
|
||||
<div class="flex justify-between mb-2">
|
||||
<span class="text-gray-600">Type:</span>
|
||||
<span>${tx.type || '-'}</span>
|
||||
</div>
|
||||
<div class="flex justify-between mb-2">
|
||||
<span class="text-gray-600">From:</span>
|
||||
<span class="font-mono text-sm">${tx.sender || '-'}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-600">Fee:</span>
|
||||
<span>${tx.fee || '0'}</span>
|
||||
</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
` : '<p class="text-gray-500">No transactions in this block</p>'}
|
||||
</div>
|
||||
`;
|
||||
|
||||
modal.classList.remove('hidden');
|
||||
}
|
||||
|
||||
// Close modal
|
||||
function closeModal() {
|
||||
document.getElementById('block-modal').classList.add('hidden');
|
||||
}
|
||||
|
||||
// Search functionality
|
||||
async function search() {
|
||||
const query = document.getElementById('search-input').value.trim();
|
||||
if (!query) return;
|
||||
|
||||
// Try block height first
|
||||
if (/^\\d+$/.test(query)) {
|
||||
showBlockDetails(parseInt(query));
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Add transaction hash search
|
||||
alert('Search by block height is currently supported');
|
||||
}
|
||||
|
||||
// Format timestamp
|
||||
function formatTimestamp(timestamp) {
|
||||
if (!timestamp) return '-';
|
||||
return new Date(timestamp * 1000).toLocaleString();
|
||||
}
|
||||
|
||||
// Auto-refresh every 30 seconds
|
||||
setInterval(refreshData, 30000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
# Install a simple web server
|
||||
print_status "Installing web server..."
|
||||
apt-get install -y nginx
|
||||
|
||||
# Configure nginx to serve the explorer
|
||||
print_status "Configuring nginx..."
|
||||
cat > /etc/nginx/sites-available/blockchain-explorer << EOL
|
||||
server {
|
||||
listen 3000;
|
||||
server_name _;
|
||||
root /opt/blockchain-explorer;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files \$uri \$uri/ =404;
|
||||
}
|
||||
|
||||
# CORS headers for API access
|
||||
location /rpc/ {
|
||||
proxy_pass http://localhost:8082;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
||||
EOL
|
||||
|
||||
# Enable the site
|
||||
ln -sf /etc/nginx/sites-available/blockchain-explorer /etc/nginx/sites-enabled/
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Test and reload nginx
|
||||
nginx -t
|
||||
systemctl reload nginx
|
||||
|
||||
# Setup port forwarding if in container
|
||||
if [ "$(hostname)" = "aitbc" ]; then
|
||||
print_status "Setting up port forwarding..."
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
|
||||
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
|
||||
iptables-save > /etc/iptables/rules.v4
|
||||
fi
|
||||
|
||||
print_status "Checking nginx status..."
|
||||
systemctl status nginx --no-pager | head -10
|
||||
|
||||
print_success "✅ Blockchain explorer deployed!"
|
||||
echo ""
|
||||
echo "Explorer URL: http://localhost:3000"
|
||||
if [ "$(hostname)" = "aitbc" ]; then
|
||||
echo "External URL: http://aitbc.keisanki.net:3000"
|
||||
else
|
||||
echo "External URL: http://aitbc.keisanki.net:3000"
|
||||
fi
|
||||
echo ""
|
||||
echo "The explorer is a static HTML site served by nginx."
|
||||
@@ -1,66 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy AITBC Explorer to the server
|
||||
|
||||
set -e
|
||||
|
||||
SERVER="root@10.1.223.93"
|
||||
EXPLORER_DIR="/root/aitbc/apps/explorer-web"
|
||||
NGINX_CONFIG="/etc/nginx/sites-available/aitbc"
|
||||
|
||||
echo "🚀 Deploying AITBC Explorer to Server"
|
||||
echo "====================================="
|
||||
echo "Server: $SERVER"
|
||||
echo ""
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Build the explorer locally first
|
||||
print_status "Building explorer locally..."
|
||||
cd /home/oib/windsurf/aitbc/apps/explorer-web
|
||||
npm run build
|
||||
|
||||
# Copy built files to server
|
||||
print_status "Copying explorer build to server..."
|
||||
scp -r dist $SERVER:$EXPLORER_DIR/
|
||||
|
||||
# Update nginx config to include explorer
|
||||
print_status "Updating nginx configuration..."
|
||||
|
||||
# Backup current config
|
||||
ssh $SERVER "cp $NGINX_CONFIG ${NGINX_CONFIG}.backup"
|
||||
|
||||
# Add explorer location to nginx config
|
||||
ssh $SERVER "sed -i '/# Health endpoint/i\\
|
||||
# Explorer\\
|
||||
location /explorer/ {\\
|
||||
alias /root/aitbc/apps/explorer-web/dist/;\\
|
||||
try_files \$uri \$uri/ /explorer/index.html;\\
|
||||
}\\
|
||||
\\
|
||||
# Explorer mock data\\
|
||||
location /explorer/mock/ {\\
|
||||
alias /root/aitbc/apps/explorer-web/public/mock/;\\
|
||||
}\\
|
||||
' $NGINX_CONFIG"
|
||||
|
||||
# Test and reload nginx
|
||||
print_status "Testing and reloading nginx..."
|
||||
ssh $SERVER "nginx -t && systemctl reload nginx"
|
||||
|
||||
print_status "✅ Explorer deployment complete!"
|
||||
echo ""
|
||||
echo "📋 Explorer URL:"
|
||||
echo " 🌐 Explorer: https://aitbc.bubuit.net/explorer/"
|
||||
echo ""
|
||||
@@ -1,121 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy the first blockchain node
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Deploying First Blockchain Node"
|
||||
echo "================================="
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
NODE1_DIR="/opt/blockchain-node"
|
||||
|
||||
# Create configuration for first node
|
||||
print_status "Creating configuration for first node..."
|
||||
cat > $NODE1_DIR/.env << EOF
|
||||
CHAIN_ID=ait-devnet
|
||||
DB_PATH=./data/chain.db
|
||||
RPC_BIND_HOST=127.0.0.1
|
||||
RPC_BIND_PORT=8080
|
||||
P2P_BIND_HOST=0.0.0.0
|
||||
P2P_BIND_PORT=7070
|
||||
PROPOSER_KEY=node1_proposer_key_$(date +%s)
|
||||
MINT_PER_UNIT=1000
|
||||
COORDINATOR_RATIO=0.05
|
||||
GOSSIP_BACKEND=http
|
||||
GOSSIP_BROADCAST_URL=http://127.0.0.1:7071/gossip
|
||||
EOF
|
||||
|
||||
# Create data directory
|
||||
mkdir -p $NODE1_DIR/data/devnet
|
||||
|
||||
# Generate genesis file
|
||||
print_status "Generating genesis file..."
|
||||
cd $NODE1_DIR
|
||||
export PYTHONPATH="${NODE1_DIR}/src:${NODE1_DIR}/scripts:${PYTHONPATH:-}"
|
||||
python3 scripts/make_genesis.py --output data/devnet/genesis.json --force
|
||||
|
||||
# Create systemd service
|
||||
print_status "Creating systemd service..."
|
||||
sudo cat > /etc/systemd/system/blockchain-node.service << EOF
|
||||
[Unit]
|
||||
Description=AITBC Blockchain Node 1
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=$NODE1_DIR
|
||||
Environment=PATH=$NODE1_DIR/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=$NODE1_DIR/src:$NODE1_DIR/scripts
|
||||
ExecStart=$NODE1_DIR/.venv/bin/python3 -m aitbc_chain.main
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create RPC API service
|
||||
print_status "Creating RPC API service..."
|
||||
sudo cat > /etc/systemd/system/blockchain-rpc.service << EOF
|
||||
[Unit]
|
||||
Description=AITBC Blockchain RPC API 1
|
||||
After=blockchain-node.service
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=$NODE1_DIR
|
||||
Environment=PATH=$NODE1_DIR/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=$NODE1_DIR/src:$NODE1_DIR/scripts
|
||||
ExecStart=$NODE1_DIR/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8080
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Setup Python environment if not exists
|
||||
if [ ! -d "$NODE1_DIR/.venv" ]; then
|
||||
print_status "Setting up Python environment..."
|
||||
cd $NODE1_DIR
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -e .
|
||||
fi
|
||||
|
||||
# Enable and start services
|
||||
print_status "Enabling and starting services..."
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable blockchain-node blockchain-rpc
|
||||
sudo systemctl start blockchain-node blockchain-rpc
|
||||
|
||||
# Check status
|
||||
print_status "Checking service status..."
|
||||
sudo systemctl status blockchain-node --no-pager -l
|
||||
sudo systemctl status blockchain-rpc --no-pager -l
|
||||
|
||||
echo ""
|
||||
print_status "✅ First blockchain node deployed!"
|
||||
echo ""
|
||||
echo "Node 1 RPC: http://127.0.0.1:8080"
|
||||
echo "Node 2 RPC: http://127.0.0.1:8081"
|
||||
echo ""
|
||||
echo "To check logs:"
|
||||
echo " Node 1: sudo journalctl -u blockchain-node -f"
|
||||
echo " Node 2: sudo journalctl -u blockchain-node-2 -f"
|
||||
@@ -1,306 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy blockchain node and explorer inside the container
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Deploying Inside Container"
|
||||
echo "============================"
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if we're in the container
|
||||
if [ ! -f /proc/1/environ ] || ! grep -q container=lxc /proc/1/environ 2>/dev/null; then
|
||||
if [ "$(hostname)" != "aitbc" ]; then
|
||||
print_warning "This script must be run inside the aitbc container"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Stop existing services
|
||||
print_status "Stopping existing services..."
|
||||
systemctl stop blockchain-node blockchain-rpc nginx 2>/dev/null || true
|
||||
|
||||
# Install dependencies
|
||||
print_status "Installing dependencies..."
|
||||
apt-get update
|
||||
apt-get install -y python3 python3-venv python3-pip git curl nginx
|
||||
|
||||
# Deploy blockchain node
|
||||
print_status "Deploying blockchain node..."
|
||||
cd /opt
|
||||
rm -rf blockchain-node
|
||||
# The source is already in blockchain-node-src, copy it properly
|
||||
cp -r blockchain-node-src blockchain-node
|
||||
cd blockchain-node
|
||||
|
||||
# Check if pyproject.toml exists
|
||||
if [ ! -f pyproject.toml ]; then
|
||||
print_warning "pyproject.toml not found, looking for it..."
|
||||
find . -name "pyproject.toml" -type f
|
||||
# If it's in a subdirectory, move everything up
|
||||
if [ -f blockchain-node-src/pyproject.toml ]; then
|
||||
print_status "Moving files from nested directory..."
|
||||
mv blockchain-node-src/* .
|
||||
rmdir blockchain-node-src
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create configuration
|
||||
print_status "Creating configuration..."
|
||||
cat > .env << EOL
|
||||
CHAIN_ID=ait-devnet
|
||||
DB_PATH=./data/chain.db
|
||||
RPC_BIND_HOST=0.0.0.0
|
||||
RPC_BIND_PORT=8082
|
||||
P2P_BIND_HOST=0.0.0.0
|
||||
P2P_BIND_PORT=7070
|
||||
PROPOSER_KEY=proposer_key_$(date +%s)
|
||||
MINT_PER_UNIT=1000
|
||||
COORDINATOR_RATIO=0.05
|
||||
GOSSIP_BACKEND=memory
|
||||
EOL
|
||||
|
||||
# Create fresh data directory
|
||||
rm -rf data
|
||||
mkdir -p data/devnet
|
||||
|
||||
# Setup Python environment
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -e .
|
||||
|
||||
# Generate genesis
|
||||
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
|
||||
python scripts/make_genesis.py --output data/devnet/genesis.json --force
|
||||
|
||||
# Create systemd services
|
||||
print_status "Creating systemd services..."
|
||||
cat > /etc/systemd/system/blockchain-node.service << EOL
|
||||
[Unit]
|
||||
Description=AITBC Blockchain Node
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/opt/blockchain-node
|
||||
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
|
||||
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
|
||||
cat > /etc/systemd/system/blockchain-rpc.service << EOL
|
||||
[Unit]
|
||||
Description=AITBC Blockchain RPC API
|
||||
After=blockchain-node.service
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/opt/blockchain-node
|
||||
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
|
||||
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
|
||||
# Start blockchain services
|
||||
print_status "Starting blockchain services..."
|
||||
systemctl daemon-reload
|
||||
systemctl enable blockchain-node blockchain-rpc
|
||||
systemctl start blockchain-node blockchain-rpc
|
||||
|
||||
# Deploy explorer
|
||||
print_status "Deploying blockchain explorer..."
|
||||
cd /opt
|
||||
rm -rf blockchain-explorer
|
||||
mkdir -p blockchain-explorer
|
||||
cd blockchain-explorer
|
||||
|
||||
# Create HTML explorer
|
||||
cat > index.html << 'EOF'
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>AITBC Blockchain Explorer</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
</head>
|
||||
<body class="bg-gray-50">
|
||||
<header class="bg-blue-600 text-white shadow-lg">
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i data-lucide="cube" class="w-8 h-8"></i>
|
||||
<h1 class="text-2xl font-bold">AITBC Blockchain Explorer</h1>
|
||||
</div>
|
||||
<button onclick="refreshData()" class="bg-blue-500 hover:bg-blue-400 px-3 py-1 rounded flex items-center space-x-1">
|
||||
<i data-lucide="refresh-cw" class="w-4 h-4"></i>
|
||||
<span>Refresh</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container mx-auto px-4 py-8">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-gray-500 text-sm">Current Height</p>
|
||||
<p class="text-2xl font-bold" id="chain-height">-</p>
|
||||
</div>
|
||||
<i data-lucide="trending-up" class="w-10 h-10 text-green-500"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-gray-500 text-sm">Latest Block</p>
|
||||
<p class="text-lg font-mono" id="latest-hash">-</p>
|
||||
</div>
|
||||
<i data-lucide="hash" class="w-10 h-10 text-blue-500"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-gray-500 text-sm">Node Status</p>
|
||||
<p class="text-lg font-semibold" id="node-status">-</p>
|
||||
</div>
|
||||
<i data-lucide="activity" class="w-10 h-10 text-purple-500"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-lg shadow">
|
||||
<div class="px-6 py-4 border-b">
|
||||
<h2 class="text-xl font-semibold flex items-center">
|
||||
<i data-lucide="blocks" class="w-5 h-5 mr-2"></i>
|
||||
Latest Blocks
|
||||
</h2>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="text-left text-gray-500 text-sm">
|
||||
<th class="pb-3">Height</th>
|
||||
<th class="pb-3">Hash</th>
|
||||
<th class="pb-3">Timestamp</th>
|
||||
<th class="pb-3">Transactions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="blocks-table">
|
||||
<tr>
|
||||
<td colspan="4" class="text-center py-8 text-gray-500">
|
||||
Loading blocks...
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
|
||||
const RPC_URL = 'http://localhost:8082';
|
||||
|
||||
async function refreshData() {
|
||||
try {
|
||||
const response = await fetch(`${RPC_URL}/rpc/head`);
|
||||
const head = await response.json();
|
||||
|
||||
document.getElementById('chain-height').textContent = head.height || '-';
|
||||
document.getElementById('latest-hash').textContent = head.hash ? head.hash.substring(0, 16) + '...' : '-';
|
||||
document.getElementById('node-status').innerHTML = '<span class="text-green-500">Online</span>';
|
||||
|
||||
// Load last 10 blocks
|
||||
const tbody = document.getElementById('blocks-table');
|
||||
tbody.innerHTML = '';
|
||||
|
||||
for (let i = 0; i < 10 && head.height - i >= 0; i++) {
|
||||
const blockResponse = await fetch(`${RPC_URL}/rpc/blocks/${head.height - i}`);
|
||||
const block = await blockResponse.json();
|
||||
|
||||
const row = tbody.insertRow();
|
||||
row.innerHTML = `
|
||||
<td class="py-3 font-mono">${block.height}</td>
|
||||
<td class="py-3 font-mono text-sm">${block.hash ? block.hash.substring(0, 16) + '...' : '-'}</td>
|
||||
<td class="py-3 text-sm">${new Date(block.timestamp * 1000).toLocaleString()}</td>
|
||||
<td class="py-3">${block.transactions ? block.transactions.length : 0}</td>
|
||||
`;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
document.getElementById('node-status').innerHTML = '<span class="text-red-500">Error</span>';
|
||||
}
|
||||
}
|
||||
|
||||
refreshData();
|
||||
setInterval(refreshData, 30000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
# Configure nginx
|
||||
print_status "Configuring nginx..."
|
||||
cat > /etc/nginx/sites-available/blockchain-explorer << EOL
|
||||
server {
|
||||
listen 3000;
|
||||
server_name _;
|
||||
root /opt/blockchain-explorer;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files \$uri \$uri/ =404;
|
||||
}
|
||||
}
|
||||
EOL
|
||||
|
||||
ln -sf /etc/nginx/sites-available/blockchain-explorer /etc/nginx/sites-enabled/
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
nginx -t
|
||||
systemctl reload nginx
|
||||
|
||||
# Wait for services to start
|
||||
print_status "Waiting for services to start..."
|
||||
sleep 5
|
||||
|
||||
# Check services
|
||||
print_status "Checking service status..."
|
||||
systemctl status blockchain-node blockchain-rpc nginx --no-pager | grep -E 'Active:|Main PID:'
|
||||
|
||||
print_success "✅ Deployment complete in container!"
|
||||
echo ""
|
||||
echo "Services:"
|
||||
echo " - Blockchain Node RPC: http://localhost:8082"
|
||||
echo " - Blockchain Explorer: http://localhost:3000"
|
||||
echo ""
|
||||
echo "These are accessible from the host via port forwarding."
|
||||
@@ -1,56 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy Modern Blockchain Explorer
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Deploying Modern Blockchain Explorer"
|
||||
echo "======================================"
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Stop existing services
|
||||
print_status "Stopping existing services..."
|
||||
systemctl stop nginx 2>/dev/null || true
|
||||
|
||||
# Create directory
|
||||
print_status "Creating explorer directory..."
|
||||
rm -rf /opt/blockchain-explorer
|
||||
mkdir -p /opt/blockchain-explorer/assets
|
||||
|
||||
# Copy files
|
||||
print_status "Copying explorer files..."
|
||||
cp -r /opt/blockchain-node-src/apps/blockchain-explorer/* /opt/blockchain-explorer/
|
||||
|
||||
# Update nginx configuration
|
||||
print_status "Updating nginx configuration..."
|
||||
cp /opt/blockchain-explorer/nginx.conf /etc/nginx/sites-available/blockchain-explorer
|
||||
ln -sf /etc/nginx/sites-available/blockchain-explorer /etc/nginx/sites-enabled/
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Test and start nginx
|
||||
print_status "Starting nginx..."
|
||||
nginx -t
|
||||
systemctl start nginx
|
||||
|
||||
print_success "✅ Modern explorer deployed!"
|
||||
echo ""
|
||||
echo "Access URLs:"
|
||||
echo " - Explorer: http://localhost:3000/"
|
||||
echo " - API: http://localhost:3000/api/v1/"
|
||||
echo ""
|
||||
echo "Standardized API Endpoints:"
|
||||
echo " - GET /api/v1/chain/head"
|
||||
echo " - GET /api/v1/chain/blocks?limit=N"
|
||||
echo " - GET /api/v1/chain/blocks/{height}"
|
||||
@@ -1,160 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy nginx reverse proxy for AITBC services
|
||||
# This replaces firehol/iptables port forwarding with nginx reverse proxy
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Deploying Nginx Reverse Proxy for AITBC"
|
||||
echo "=========================================="
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if we're on the host server
|
||||
if ! grep -q "ns3-root" ~/.ssh/config 2>/dev/null; then
|
||||
print_error "ns3-root SSH configuration not found. Please add it to ~/.ssh/config"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install nginx on host if not already installed
|
||||
print_status "Checking nginx installation on host..."
|
||||
ssh ns3-root "which nginx > /dev/null || (apt-get update && apt-get install -y nginx)"
|
||||
|
||||
# Install certbot for SSL certificates
|
||||
print_status "Checking certbot installation..."
|
||||
ssh ns3-root "which certbot > /dev/null || (apt-get update && apt-get install -y certbot python3-certbot-nginx)"
|
||||
|
||||
# Copy nginx configuration
|
||||
print_status "Copying nginx configuration..."
|
||||
scp infra/nginx/nginx-aitbc-reverse-proxy.conf ns3-root:/tmp/aitbc-reverse-proxy.conf
|
||||
|
||||
# Backup existing nginx configuration
|
||||
print_status "Backing up existing nginx configuration..."
|
||||
ssh ns3-root "mkdir -p /etc/nginx/backup && cp -r /etc/nginx/sites-available/* /etc/nginx/backup/ 2>/dev/null || true"
|
||||
|
||||
# Install the new configuration
|
||||
print_status "Installing nginx reverse proxy configuration..."
|
||||
ssh ns3-root << 'EOF'
|
||||
# Remove existing configurations
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
rm -f /etc/nginx/sites-available/aitbc*
|
||||
|
||||
# Copy new configuration
|
||||
cp /tmp/aitbc-reverse-proxy.conf /etc/nginx/sites-available/aitbc-reverse-proxy.conf
|
||||
|
||||
# Create symbolic link
|
||||
ln -sf /etc/nginx/sites-available/aitbc-reverse-proxy.conf /etc/nginx/sites-enabled/
|
||||
|
||||
# Test nginx configuration
|
||||
nginx -t
|
||||
EOF
|
||||
|
||||
# Check if SSL certificate exists
|
||||
print_status "Checking SSL certificate..."
|
||||
if ! ssh ns3-root "test -f /etc/letsencrypt/live/aitbc.keisanki.net/fullchain.pem"; then
|
||||
print_warning "SSL certificate not found. Obtaining Let's Encrypt certificate..."
|
||||
|
||||
# Obtain SSL certificate
|
||||
ssh ns3-root << 'EOF'
|
||||
# Stop nginx temporarily
|
||||
systemctl stop nginx 2>/dev/null || true
|
||||
|
||||
# Obtain certificate
|
||||
certbot certonly --standalone -d aitbc.keisanki.net -d api.aitbc.keisanki.net -d rpc.aitbc.keisanki.net --email admin@keisanki.net --agree-tos --non-interactive
|
||||
|
||||
# Start nginx
|
||||
systemctl start nginx
|
||||
EOF
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
print_error "Failed to obtain SSL certificate. Please run certbot manually:"
|
||||
echo "certbot certonly --standalone -d aitbc.keisanki.net -d api.aitbc.keisanki.net -d rpc.aitbc.keisanki.net"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Restart nginx
|
||||
print_status "Restarting nginx..."
|
||||
ssh ns3-root "systemctl restart nginx && systemctl enable nginx"
|
||||
|
||||
# Remove old iptables rules (optional)
|
||||
print_warning "Removing old iptables port forwarding rules (if they exist)..."
|
||||
ssh ns3-root << 'EOF'
|
||||
# Flush existing NAT rules for AITBC ports
|
||||
iptables -t nat -D PREROUTING -p tcp --dport 8000 -j DNAT --to-destination 192.168.100.10:8000 2>/dev/null || true
|
||||
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 8000 -j MASQUERADE 2>/dev/null || true
|
||||
iptables -t nat -D PREROUTING -p tcp --dport 8081 -j DNAT --to-destination 192.168.100.10:8081 2>/dev/null || true
|
||||
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 8081 -j MASQUERADE 2>/dev/null || true
|
||||
iptables -t nat -D PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082 2>/dev/null || true
|
||||
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE 2>/dev/null || true
|
||||
iptables -t nat -D PREROUTING -p tcp --dport 9080 -j DNAT --to-destination 192.168.100.10:9080 2>/dev/null || true
|
||||
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 9080 -j MASQUERADE 2>/dev/null || true
|
||||
iptables -t nat -D PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000 2>/dev/null || true
|
||||
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE 2>/dev/null || true
|
||||
|
||||
# Save iptables rules
|
||||
iptables-save > /etc/iptables/rules.v4 2>/dev/null || true
|
||||
EOF
|
||||
|
||||
# Wait for nginx to start
|
||||
sleep 2
|
||||
|
||||
# Test the configuration
|
||||
print_status "Testing reverse proxy configuration..."
|
||||
echo ""
|
||||
|
||||
# Test main domain
|
||||
if curl -s -o /dev/null -w "%{http_code}" https://aitbc.keisanki.net/health | grep -q "200"; then
|
||||
print_status "✅ Main domain (aitbc.keisanki.net) - OK"
|
||||
else
|
||||
print_error "❌ Main domain (aitbc.keisanki.net) - FAILED"
|
||||
fi
|
||||
|
||||
# Test API endpoint
|
||||
if curl -s -o /dev/null -w "%{http_code}" https://aitbc.keisanki.net/api/health | grep -q "200"; then
|
||||
print_status "✅ API endpoint - OK"
|
||||
else
|
||||
print_warning "⚠️ API endpoint - Not responding (service may not be running)"
|
||||
fi
|
||||
|
||||
# Test RPC endpoint
|
||||
if curl -s -o /dev/null -w "%{http_code}" https://aitbc.keisanki.net/rpc/head | grep -q "200"; then
|
||||
print_status "✅ RPC endpoint - OK"
|
||||
else
|
||||
print_warning "⚠️ RPC endpoint - Not responding (blockchain node may not be running)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
print_status "🎉 Nginx reverse proxy deployment complete!"
|
||||
echo ""
|
||||
echo "Service URLs:"
|
||||
echo " • Blockchain Explorer: https://aitbc.keisanki.net"
|
||||
echo " • API: https://aitbc.keisanki.net/api/"
|
||||
echo " • RPC: https://aitbc.keisanki.net/rpc/"
|
||||
echo " • Exchange: https://aitbc.keisanki.net/exchange/"
|
||||
echo ""
|
||||
echo "Alternative URLs:"
|
||||
echo " • API-only: https://api.aitbc.keisanki.net"
|
||||
echo " • RPC-only: https://rpc.aitbc.keisanki.net"
|
||||
echo ""
|
||||
echo "Note: Make sure all services are running in the container:"
|
||||
echo " • blockchain-explorer.service (port 3000)"
|
||||
echo " • coordinator-api.service (port 8000)"
|
||||
echo " • blockchain-rpc.service (port 8082)"
|
||||
echo " • aitbc-exchange.service (port 9080)"
|
||||
@@ -1,55 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "🚀 Deploying AITBC for Production..."
|
||||
|
||||
# 1. Setup production assets
|
||||
echo "📦 Setting up production assets..."
|
||||
bash setup-production-assets.sh
|
||||
|
||||
# 2. Copy assets to server
|
||||
echo "📋 Copying assets to server..."
|
||||
scp -r assets/ aitbc:/var/www/html/
|
||||
|
||||
# 3. Update Nginx configuration
|
||||
echo "⚙️ Updating Nginx configuration..."
|
||||
ssh aitbc "cat >> /etc/nginx/sites-available/aitbc.conf << 'EOF'
|
||||
|
||||
# Serve production assets
|
||||
location /assets/ {
|
||||
alias /var/www/html/assets/;
|
||||
expires 1y;
|
||||
add_header Cache-Control \"public, immutable\";
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
|
||||
# Gzip compression
|
||||
gzip on;
|
||||
gzip_types text/css application/javascript image/svg+xml;
|
||||
}
|
||||
|
||||
# Security headers
|
||||
add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;
|
||||
add_header X-Frame-Options \"SAMEORIGIN\" always;
|
||||
add_header X-Content-Type-Options \"nosniff\" always;
|
||||
EOF"
|
||||
|
||||
# 4. Reload Nginx
|
||||
echo "🔄 Reloading Nginx..."
|
||||
ssh aitbc "nginx -t && systemctl reload nginx"
|
||||
|
||||
# 5. Update Exchange page to use production assets
|
||||
echo "🔄 Updating Exchange page..."
|
||||
scp apps/trade-exchange/index.prod.html aitbc:/root/aitbc/apps/trade-exchange/index.html
|
||||
|
||||
# 6. Update Marketplace page
|
||||
echo "🔄 Updating Marketplace page..."
|
||||
sed -i 's|https://cdn.tailwindcss.com|/assets/js/tailwind.js|g' apps/marketplace-ui/index.html
|
||||
sed -i 's|https://unpkg.com/axios/dist/axios.min.js|/assets/js/axios.min.js|g' apps/marketplace-ui/index.html
|
||||
sed -i 's|https://unpkg.com/lucide@latest|/assets/js/lucide.js|g' apps/marketplace-ui/index.html
|
||||
scp apps/marketplace-ui/index.html aitbc:/root/aitbc/apps/marketplace-ui/
|
||||
|
||||
echo "✅ Production deployment complete!"
|
||||
echo ""
|
||||
echo "📝 Next steps:"
|
||||
echo "1. Restart services: ssh aitbc 'systemctl restart aitbc-exchange aitbc-marketplace-ui'"
|
||||
echo "2. Clear browser cache"
|
||||
echo "3. Test all pages"
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy blockchain node by building directly on ns3 server
|
||||
|
||||
echo "🚀 Remote Blockchain Deployment (Build on Server)"
|
||||
echo "=============================================="
|
||||
|
||||
# Copy deployment script to server
|
||||
echo "Copying deployment script to ns3..."
|
||||
scp scripts/deploy/deploy-blockchain-remote.sh ns3-root:/opt/
|
||||
|
||||
# Execute deployment on server
|
||||
echo "Executing deployment on ns3 (utilizing gigabit connection)..."
|
||||
ssh ns3-root "cd /opt && chmod +x deploy-blockchain-remote.sh && ./deploy-blockchain-remote.sh"
|
||||
|
||||
echo ""
|
||||
echo "Deployment complete!"
|
||||
echo "The blockchain node was built directly on ns3 using its fast connection."
|
||||
@@ -1,127 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy a second blockchain node on the same server
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Deploying Second Blockchain Node"
|
||||
echo "=================================="
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Create directory for second node
|
||||
print_status "Creating directory for second node..."
|
||||
NODE2_DIR="/opt/blockchain-node-2"
|
||||
sudo mkdir -p $NODE2_DIR
|
||||
sudo chown $USER:$USER $NODE2_DIR
|
||||
|
||||
# Copy blockchain node code
|
||||
print_status "Copying blockchain node code..."
|
||||
cp -r /opt/blockchain-node/* $NODE2_DIR/
|
||||
|
||||
# Create configuration for second node
|
||||
print_status "Creating configuration for second node..."
|
||||
cat > $NODE2_DIR/.env << EOF
|
||||
CHAIN_ID=ait-devnet
|
||||
DB_PATH=./data/chain2.db
|
||||
RPC_BIND_HOST=127.0.0.1
|
||||
RPC_BIND_PORT=8081
|
||||
P2P_BIND_HOST=0.0.0.0
|
||||
P2P_BIND_PORT=7071
|
||||
PROPOSER_KEY=node2_proposer_key_$(date +%s)
|
||||
MINT_PER_UNIT=1000
|
||||
COORDINATOR_RATIO=0.05
|
||||
GOSSIP_BACKEND=http
|
||||
GOSSIP_BROADCAST_URL=http://127.0.0.1:7070/gossip
|
||||
EOF
|
||||
|
||||
# Create data directory
|
||||
mkdir -p $NODE2_DIR/data/devnet
|
||||
|
||||
# Generate genesis file (same as first node)
|
||||
print_status "Generating genesis file..."
|
||||
cd $NODE2_DIR
|
||||
export PYTHONPATH="${NODE2_DIR}/src:${NODE2_DIR}/scripts:${PYTHONPATH:-}"
|
||||
python3 scripts/make_genesis.py --output data/devnet/genesis.json --force
|
||||
|
||||
# Create systemd service
|
||||
print_status "Creating systemd service..."
|
||||
sudo cat > /etc/systemd/system/blockchain-node-2.service << EOF
|
||||
[Unit]
|
||||
Description=AITBC Blockchain Node 2
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=$NODE2_DIR
|
||||
Environment=PATH=$NODE2_DIR/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=$NODE2_DIR/src:$NODE2_DIR/scripts
|
||||
ExecStart=$NODE2_DIR/.venv/bin/python3 -m aitbc_chain.main
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create RPC API service
|
||||
print_status "Creating RPC API service..."
|
||||
sudo cat > /etc/systemd/system/blockchain-rpc-2.service << EOF
|
||||
[Unit]
|
||||
Description=AITBC Blockchain RPC API 2
|
||||
After=blockchain-node-2.service
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=$NODE2_DIR
|
||||
Environment=PATH=$NODE2_DIR/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=$NODE2_DIR/src:$NODE2_DIR/scripts
|
||||
ExecStart=$NODE2_DIR/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8081
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Setup Python environment
|
||||
print_status "Setting up Python environment..."
|
||||
cd $NODE2_DIR
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -e .
|
||||
|
||||
# Enable and start services
|
||||
print_status "Enabling and starting services..."
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable blockchain-node-2 blockchain-rpc-2
|
||||
sudo systemctl start blockchain-node-2 blockchain-rpc-2
|
||||
|
||||
# Check status
|
||||
print_status "Checking service status..."
|
||||
sudo systemctl status blockchain-node-2 --no-pager -l
|
||||
sudo systemctl status blockchain-rpc-2 --no-pager -l
|
||||
|
||||
echo ""
|
||||
print_status "✅ Second blockchain node deployed!"
|
||||
echo ""
|
||||
echo "Node 1 RPC: http://127.0.0.1:8080"
|
||||
echo "Node 2 RPC: http://127.0.0.1:8081"
|
||||
echo ""
|
||||
echo "To check logs:"
|
||||
echo " Node 1: sudo journalctl -u blockchain-node -f"
|
||||
echo " Node 2: sudo journalctl -u blockchain-node-2 -f"
|
||||
@@ -1,84 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy blockchain node inside incus container aitbc
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 AITBC Deployment in Incus Container"
|
||||
echo "======================================"
|
||||
echo "This will deploy inside the aitbc container"
|
||||
echo ""
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if we're on ns3 host
|
||||
if [ "$(hostname)" != "ns3" ]; then
|
||||
print_warning "This script must be run on ns3 host"
|
||||
echo "Run: ssh ns3-root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if container exists
|
||||
if ! incus list | grep -q "aitbc.*RUNNING"; then
|
||||
print_warning "Container aitbc is not running"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copy source to container
|
||||
print_status "Copying source code to container..."
|
||||
incus exec aitbc -- rm -rf /opt/blockchain-node-src 2>/dev/null || true
|
||||
incus exec aitbc -- mkdir -p /opt/blockchain-node-src
|
||||
# Use the source already on the server
|
||||
incus file push -r /opt/blockchain-node-src/. aitbc/opt/blockchain-node-src/
|
||||
# Fix the nested directory issue - move everything up one level
|
||||
incus exec aitbc -- sh -c 'if [ -d /opt/blockchain-node-src/blockchain-node-src ]; then mv /opt/blockchain-node-src/blockchain-node-src/* /opt/blockchain-node-src/ && rmdir /opt/blockchain-node-src/blockchain-node-src; fi'
|
||||
|
||||
# Copy deployment script to container
|
||||
print_status "Copying deployment script to container..."
|
||||
incus file push /opt/deploy-in-container.sh aitbc/opt/
|
||||
|
||||
# Execute deployment inside container
|
||||
print_status "Deploying inside container..."
|
||||
incus exec aitbc -- bash /opt/deploy-in-container.sh
|
||||
|
||||
# Setup port forwarding on host
|
||||
print_status "Setting up port forwarding on host..."
|
||||
iptables -t nat -F PREROUTING 2>/dev/null || true
|
||||
iptables -t nat -F POSTROUTING 2>/dev/null || true
|
||||
|
||||
# Forward blockchain RPC
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
|
||||
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
|
||||
|
||||
# Forward explorer
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
|
||||
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
|
||||
|
||||
# Save rules
|
||||
mkdir -p /etc/iptables
|
||||
iptables-save > /etc/iptables/rules.v4
|
||||
|
||||
# Check services
|
||||
print_status "Checking services in container..."
|
||||
incus exec aitbc -- systemctl status blockchain-node blockchain-rpc nginx --no-pager | grep -E 'Active:|Main PID:'
|
||||
|
||||
print_success "✅ Deployment complete!"
|
||||
echo ""
|
||||
echo "Services in container aitbc:"
|
||||
echo " - Blockchain Node RPC: http://192.168.100.10:8082"
|
||||
echo " - Blockchain Explorer: http://192.168.100.10:3000"
|
||||
echo ""
|
||||
echo "External access via ns3:"
|
||||
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
|
||||
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"
|
||||
@@ -1,253 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# AITBC Services Deployment to Incus Container
|
||||
# This script deploys all AITBC services to the 'aitbc' container
|
||||
|
||||
set -e
|
||||
|
||||
CONTAINER_NAME="aitbc"
|
||||
CONTAINER_IP="10.1.223.93"
|
||||
PROJECT_DIR="/home/oib/windsurf/aitbc"
|
||||
|
||||
echo "🚀 Deploying AITBC services to container: $CONTAINER_NAME"
|
||||
echo "Container IP: $CONTAINER_IP"
|
||||
echo ""
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to print colored output
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Stop local services
|
||||
print_status "Stopping local AITBC services..."
|
||||
sudo fuser -k 8000/tcp 2>/dev/null || true
|
||||
sudo fuser -k 9080/tcp 2>/dev/null || true
|
||||
sudo fuser -k 3001/tcp 2>/dev/null || true
|
||||
sudo fuser -k 3002/tcp 2>/dev/null || true
|
||||
pkill -f "aitbc_chain.app" 2>/dev/null || true
|
||||
pkill -f "marketplace-ui" 2>/dev/null || true
|
||||
pkill -f "trade-exchange" 2>/dev/null || true
|
||||
|
||||
# Copy project to container
|
||||
print_status "Copying AITBC project to container..."
|
||||
incus file push -r $PROJECT_DIR $CONTAINER_NAME/home/oib/
|
||||
|
||||
# Setup container environment
|
||||
print_status "Setting up container environment..."
|
||||
incus exec $CONTAINER_NAME -- bash -c "
|
||||
cd /home/oib/aitbc
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
"
|
||||
|
||||
# Install dependencies for each service
|
||||
print_status "Installing dependencies..."
|
||||
|
||||
# Coordinator API
|
||||
print_status "Installing Coordinator API dependencies..."
|
||||
incus exec $CONTAINER_NAME -- bash -c "
|
||||
cd /home/oib/aitbc/apps/coordinator-api
|
||||
source ../.venv/bin/activate
|
||||
pip install -e .
|
||||
pip install fastapi uvicorn
|
||||
"
|
||||
|
||||
# Blockchain Node
|
||||
print_status "Installing Blockchain Node dependencies..."
|
||||
incus exec $CONTAINER_NAME -- bash -c "
|
||||
cd /home/oib/aitbc/apps/blockchain-node
|
||||
source ../.venv/bin/activate
|
||||
pip install -e .
|
||||
pip install fastapi uvicorn
|
||||
"
|
||||
|
||||
# Create systemd service files
|
||||
print_status "Creating systemd services..."
|
||||
|
||||
# Coordinator API service
|
||||
incus exec $CONTAINER_NAME -- tee /etc/systemd/system/aitbc-coordinator.service > /dev/null <<EOF
|
||||
[Unit]
|
||||
Description=AITBC Coordinator API
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=oib
|
||||
Group=oib
|
||||
WorkingDirectory=/home/oib/aitbc/apps/coordinator-api
|
||||
Environment=PATH=/home/oib/aitbc/.venv/bin
|
||||
ExecStart=/home/oib/aitbc/.venv/bin/python -m uvicorn src.app.main:app --host 0.0.0.0 --port 8000
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Blockchain Node service
|
||||
incus exec $CONTAINER_NAME -- tee /etc/systemd/system/aitbc-blockchain.service > /dev/null <<EOF
|
||||
[Unit]
|
||||
Description=AITBC Blockchain Node
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=oib
|
||||
Group=oib
|
||||
WorkingDirectory=/home/oib/aitbc/apps/blockchain-node
|
||||
Environment=PATH=/home/oib/aitbc/.venv/bin
|
||||
ExecStart=/home/oib/aitbc/.venv/bin/python -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 9080
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Marketplace UI service
|
||||
incus exec $CONTAINER_NAME -- tee /etc/systemd/system/aitbc-marketplace.service > /dev/null <<EOF
|
||||
[Unit]
|
||||
Description=AITBC Marketplace UI
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=oib
|
||||
Group=oib
|
||||
WorkingDirectory=/home/oib/aitbc/apps/marketplace-ui
|
||||
Environment=PATH=/home/oib/aitbc/.venv/bin
|
||||
ExecStart=/home/oib/aitbc/.venv/bin/python server.py --port 3001
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Trade Exchange service
|
||||
incus exec $CONTAINER_NAME -- tee /etc/systemd/system/aitbc-exchange.service > /dev/null <<EOF
|
||||
[Unit]
|
||||
Description=AITBC Trade Exchange
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=oib
|
||||
Group=oib
|
||||
WorkingDirectory=/home/oib/aitbc/apps/trade-exchange
|
||||
Environment=PATH=/home/oib/aitbc/.venv/bin
|
||||
ExecStart=/home/oib/aitbc/.venv/bin/python server.py --port 3002
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Reload systemd and start services
|
||||
print_status "Starting AITBC services..."
|
||||
incus exec $CONTAINER_NAME -- systemctl daemon-reload
|
||||
incus exec $CONTAINER_NAME -- systemctl enable aitbc-coordinator
|
||||
incus exec $CONTAINER_NAME -- systemctl enable aitbc-blockchain
|
||||
incus exec $CONTAINER_NAME -- systemctl enable aitbc-marketplace
|
||||
incus exec $CONTAINER_NAME -- systemctl enable aitbc-exchange
|
||||
|
||||
incus exec $CONTAINER_NAME -- systemctl start aitbc-coordinator
|
||||
incus exec $CONTAINER_NAME -- systemctl start aitbc-blockchain
|
||||
incus exec $CONTAINER_NAME -- systemctl start aitbc-marketplace
|
||||
incus exec $CONTAINER_NAME -- systemctl start aitbc-exchange
|
||||
|
||||
# Wait for services to start
|
||||
print_status "Waiting for services to start..."
|
||||
sleep 10
|
||||
|
||||
# Check service status
|
||||
print_status "Checking service status..."
|
||||
incus exec $CONTAINER_NAME -- systemctl status aitbc-coordinator --no-pager -l
|
||||
incus exec $CONTAINER_NAME -- systemctl status aitbc-blockchain --no-pager -l
|
||||
incus exec $CONTAINER_NAME -- systemctl status aitbc-marketplace --no-pager -l
|
||||
incus exec $CONTAINER_NAME -- systemctl status aitbc-exchange --no-pager -l
|
||||
|
||||
# Create nginx configuration for reverse proxy
|
||||
print_status "Setting up Nginx reverse proxy..."
|
||||
incus exec $CONTAINER_NAME -- tee /etc/nginx/sites-available/aitbc > /dev/null <<EOF
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
# Coordinator API
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8000/v1/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
}
|
||||
|
||||
# Blockchain RPC
|
||||
location /rpc/ {
|
||||
proxy_pass http://127.0.0.1:9080/rpc/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
}
|
||||
|
||||
# Marketplace UI
|
||||
location /marketplace/ {
|
||||
proxy_pass http://127.0.0.1:3001/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
}
|
||||
|
||||
# Trade Exchange
|
||||
location /exchange/ {
|
||||
proxy_pass http://127.0.0.1:3002/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
}
|
||||
|
||||
# Default redirect to marketplace
|
||||
location / {
|
||||
return 301 /marketplace/;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Enable nginx site
|
||||
incus exec $CONTAINER_NAME -- ln -sf /etc/nginx/sites-available/aitbc /etc/nginx/sites-enabled/
|
||||
incus exec $CONTAINER_NAME -- rm -f /etc/nginx/sites-enabled/default
|
||||
incus exec $CONTAINER_NAME -- nginx -t && incus exec $CONTAINER_NAME -- systemctl reload nginx
|
||||
|
||||
# Print access information
|
||||
echo ""
|
||||
print_status "✅ AITBC services deployed successfully!"
|
||||
echo ""
|
||||
echo "📋 Service URLs:"
|
||||
echo " 🌐 Public IP: $CONTAINER_IP"
|
||||
echo " 📊 Marketplace: http://$CONTAINER_IP/marketplace/"
|
||||
echo " 💱 Trade Exchange: http://$CONTAINER_IP/exchange/"
|
||||
echo " 🔗 API: http://$CONTAINER_IP/api/"
|
||||
echo " ⛓️ Blockchain RPC: http://$CONTAINER_IP/rpc/"
|
||||
echo ""
|
||||
print_status "To check logs: incus exec $CONTAINER_NAME -- journalctl -u aitbc-coordinator -f"
|
||||
print_status "To restart services: incus exec $CONTAINER_NAME -- systemctl restart aitbc-*"
|
||||
50
scripts/deploy/deploy-to-container.sh.example
Normal file
50
scripts/deploy/deploy-to-container.sh.example
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
|
||||
# AITBC Services Deployment to Container
|
||||
# Copy to deploy-to-container.sh and adjust variables for your environment
|
||||
|
||||
set -e
|
||||
|
||||
# === CONFIGURE THESE ===
|
||||
CONTAINER_NAME="aitbc"
|
||||
CONTAINER_IP="YOUR_CONTAINER_IP"
|
||||
PROJECT_DIR="/path/to/your/aitbc"
|
||||
SSH_ALIAS="your-ssh-alias" # or user@host
|
||||
|
||||
echo "🚀 Deploying AITBC services to container: $CONTAINER_NAME"
|
||||
echo "Container IP: $CONTAINER_IP"
|
||||
echo ""
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
# 1. Push website
|
||||
echo -e "${YELLOW}Deploying website...${NC}"
|
||||
scp -r "$PROJECT_DIR/website/index.html" "$PROJECT_DIR/website/404.html" \
|
||||
"$SSH_ALIAS:/var/www/html/"
|
||||
scp -r "$PROJECT_DIR/website/docs/"*.html "$SSH_ALIAS:/var/www/html/docs/"
|
||||
scp "$PROJECT_DIR/website/docs/css/docs.css" "$SSH_ALIAS:/var/www/html/docs/css/"
|
||||
scp "$PROJECT_DIR/website/docs/js/theme.js" "$SSH_ALIAS:/var/www/html/docs/js/"
|
||||
echo -e "${GREEN}✓ Website deployed${NC}"
|
||||
|
||||
# 2. Deploy coordinator API
|
||||
echo -e "${YELLOW}Deploying coordinator API...${NC}"
|
||||
ssh "$SSH_ALIAS" "cd /opt/aitbc && pip install -e apps/coordinator-api/"
|
||||
ssh "$SSH_ALIAS" "systemctl restart aitbc-coordinator"
|
||||
echo -e "${GREEN}✓ Coordinator deployed${NC}"
|
||||
|
||||
# 3. Deploy blockchain node
|
||||
echo -e "${YELLOW}Deploying blockchain node...${NC}"
|
||||
ssh "$SSH_ALIAS" "cd /opt/aitbc && pip install -e apps/blockchain-node/"
|
||||
ssh "$SSH_ALIAS" "systemctl restart aitbc-blockchain"
|
||||
echo -e "${GREEN}✓ Blockchain node deployed${NC}"
|
||||
|
||||
# 4. Verify
|
||||
echo ""
|
||||
echo -e "${YELLOW}Verifying services...${NC}"
|
||||
ssh "$SSH_ALIAS" "curl -s http://127.0.0.1:8000/v1/health | head -1"
|
||||
ssh "$SSH_ALIAS" "curl -s http://127.0.0.1:9080/rpc/health | head -1"
|
||||
echo -e "${GREEN}✓ All services running${NC}"
|
||||
@@ -1,241 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy AITBC services to the aitbc server (10.1.223.93)
|
||||
|
||||
set -e
|
||||
|
||||
SERVER="root@10.1.223.93"
|
||||
PROJECT_DIR="/root/aitbc"
|
||||
|
||||
echo "🚀 Deploying AITBC to Server"
|
||||
echo "=========================="
|
||||
echo "Server: $SERVER"
|
||||
echo ""
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Test SSH connection
|
||||
print_status "Testing SSH connection..."
|
||||
ssh $SERVER "hostname && ip a show eth0 | grep inet"
|
||||
|
||||
# Copy project to server
|
||||
print_status "Copying project to server..."
|
||||
ssh $SERVER "rm -rf $PROJECT_DIR 2>/dev/null || true"
|
||||
scp -r /home/oib/windsurf/aitbc $SERVER:/root/
|
||||
|
||||
# Setup Python environment
|
||||
print_status "Setting up Python environment..."
|
||||
ssh $SERVER "cd $PROJECT_DIR && python3 -m venv .venv && source .venv/bin/activate && pip install --upgrade pip"
|
||||
|
||||
# Install dependencies
|
||||
print_status "Installing dependencies..."
|
||||
ssh $SERVER "cd $PROJECT_DIR/apps/coordinator-api && source ../../.venv/bin/activate && pip install -e ."
|
||||
ssh $SERVER "cd $PROJECT_DIR/apps/blockchain-node && source ../../.venv/bin/activate && pip install -e ."
|
||||
|
||||
# Create systemd service files
|
||||
print_status "Creating systemd services..."
|
||||
|
||||
# Coordinator API service
|
||||
ssh $SERVER 'cat > /etc/systemd/system/aitbc-coordinator.service << EOF
|
||||
[Unit]
|
||||
Description=AITBC Coordinator API
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/root/aitbc/apps/coordinator-api
|
||||
Environment=PATH=/root/aitbc/.venv/bin
|
||||
ExecStart=/root/aitbc/.venv/bin/python -m uvicorn src.app.main:app --host 0.0.0.0 --port 8000
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF'
|
||||
|
||||
# Blockchain Node service
|
||||
ssh $SERVER 'cat > /etc/systemd/system/aitbc-blockchain.service << EOF
|
||||
[Unit]
|
||||
Description=AITBC Blockchain Node
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/root/aitbc/apps/blockchain-node
|
||||
Environment=PATH=/root/aitbc/.venv/bin
|
||||
ExecStart=/root/aitbc/.venv/bin/python -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 9080
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF'
|
||||
|
||||
# Marketplace UI service
|
||||
ssh $SERVER 'cat > /etc/systemd/system/aitbc-marketplace.service << EOF
|
||||
[Unit]
|
||||
Description=AITBC Marketplace UI
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/root/aitbc/apps/marketplace-ui
|
||||
Environment=PATH=/root/aitbc/.venv/bin
|
||||
ExecStart=/root/aitbc/.venv/bin/python server.py --port 3001
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF'
|
||||
|
||||
# Trade Exchange service
|
||||
ssh $SERVER 'cat > /etc/systemd/system/aitbc-exchange.service << EOF
|
||||
[Unit]
|
||||
Description=AITBC Trade Exchange
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/root/aitbc/apps/trade-exchange
|
||||
Environment=PATH=/root/aitbc/.venv/bin
|
||||
ExecStart=/root/aitbc/.venv/bin/python server.py --port 3002
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF'
|
||||
|
||||
# Install nginx if not installed
|
||||
print_status "Installing nginx..."
|
||||
ssh $SERVER "apt update && apt install -y nginx"
|
||||
|
||||
# Create nginx configuration
|
||||
print_status "Configuring nginx..."
|
||||
ssh $SERVER 'cat > /etc/nginx/sites-available/aitbc << EOF
|
||||
server {
|
||||
listen 80;
|
||||
server_name aitbc.bubuit.net;
|
||||
|
||||
# API routes
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8000/v1/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
}
|
||||
|
||||
# Admin routes
|
||||
location /admin/ {
|
||||
proxy_pass http://127.0.0.1:8000/admin/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
}
|
||||
|
||||
# Blockchain RPC
|
||||
location /rpc/ {
|
||||
proxy_pass http://127.0.0.1:9080/rpc/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
}
|
||||
|
||||
# Marketplace UI
|
||||
location /Marketplace {
|
||||
proxy_pass http://127.0.0.1:3001/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
}
|
||||
|
||||
# Trade Exchange
|
||||
location /Exchange {
|
||||
proxy_pass http://127.0.0.1:3002/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
}
|
||||
|
||||
# Health endpoint
|
||||
location /health {
|
||||
proxy_pass http://127.0.0.1:8000/v1/health;
|
||||
proxy_set_header Host \$host;
|
||||
}
|
||||
|
||||
# Default redirect
|
||||
location / {
|
||||
return 301 /Marketplace;
|
||||
}
|
||||
}
|
||||
EOF'
|
||||
|
||||
# Enable nginx site
|
||||
ssh $SERVER "ln -sf /etc/nginx/sites-available/aitbc /etc/nginx/sites-enabled/"
|
||||
ssh $SERVER "rm -f /etc/nginx/sites-enabled/default"
|
||||
|
||||
# Test and reload nginx
|
||||
ssh $SERVER "nginx -t && systemctl reload nginx"
|
||||
|
||||
# Start services
|
||||
print_status "Starting AITBC services..."
|
||||
ssh $SERVER "systemctl daemon-reload"
|
||||
ssh $SERVER "systemctl enable aitbc-coordinator aitbc-blockchain aitbc-marketplace aitbc-exchange"
|
||||
ssh $SERVER "systemctl start aitbc-coordinator aitbc-blockchain aitbc-marketplace aitbc-exchange"
|
||||
|
||||
# Wait for services to start
|
||||
print_status "Waiting for services to start..."
|
||||
sleep 10
|
||||
|
||||
# Check service status
|
||||
print_status "Checking service status..."
|
||||
ssh $SERVER "systemctl status aitbc-coordinator --no-pager -l | head -10"
|
||||
ssh $SERVER "systemctl status aitbc-blockchain --no-pager -l | head -10"
|
||||
|
||||
# Test endpoints
|
||||
print_status "Testing endpoints..."
|
||||
ssh $SERVER "curl -s http://127.0.0.1:8000/v1/health | head -c 100"
|
||||
echo ""
|
||||
ssh $SERVER "curl -s http://127.0.0.1:8000/v1/admin/stats -H 'X-Api-Key: ${ADMIN_API_KEY}' | head -c 100"
|
||||
echo ""
|
||||
|
||||
echo ""
|
||||
print_status "✅ Deployment complete!"
|
||||
echo ""
|
||||
echo "📋 Service URLs:"
|
||||
echo " 🌐 Server IP: 10.1.223.93"
|
||||
echo " 📊 Marketplace: http://10.1.223.93/Marketplace"
|
||||
echo " 💱 Trade Exchange: http://10.1.223.93/Exchange"
|
||||
echo " 🔗 API: http://10.1.223.93/api"
|
||||
echo " ⛓️ Blockchain RPC: http://10.1.223.93/rpc"
|
||||
echo ""
|
||||
echo "🔒 Domain URLs (with SSL):"
|
||||
echo " 📊 Marketplace: https://aitbc.bubuit.net/Marketplace"
|
||||
echo " 💱 Trade Exchange: https://aitbc.bubuit.net/Exchange"
|
||||
echo " 🔗 API: https://aitbc.bubuit.net/api"
|
||||
echo " ⛓️ Blockchain RPC: https://aitbc.bubuit.net/rpc"
|
||||
echo ""
|
||||
print_status "To manage services:"
|
||||
echo " ssh aitbc 'systemctl status aitbc-coordinator'"
|
||||
echo " ssh aitbc 'journalctl -u aitbc-coordinator -f'"
|
||||
@@ -1,158 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Deploy AITBC services to incus container with GPU miner integration
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import time
|
||||
import sys
|
||||
|
||||
def run_command(cmd, container=None):
|
||||
"""Run command locally or in container"""
|
||||
if container:
|
||||
cmd = f"incus exec {container} -- {cmd}"
|
||||
print(f"Running: {cmd}")
|
||||
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
print(f"Error: {result.stderr}")
|
||||
return False
|
||||
return True
|
||||
|
||||
def deploy_to_container():
|
||||
container = "aitbc"
|
||||
container_ip = "10.1.223.93"
|
||||
|
||||
print("🚀 Deploying AITBC services to container with GPU miner...")
|
||||
|
||||
# Check if container exists
|
||||
result = subprocess.run("incus list -c n", shell=True, capture_output=True, text=True)
|
||||
if container not in result.stdout:
|
||||
print(f"\n📦 Creating container {container}...")
|
||||
subprocess.run(f"incus launch images:ubuntu/22.04 {container}", shell=True)
|
||||
time.sleep(10)
|
||||
|
||||
# Ensure container is running
|
||||
subprocess.run(f"incus start {container}", shell=True)
|
||||
time.sleep(5)
|
||||
|
||||
# Update and install packages in container
|
||||
print("\n📦 Installing packages in container...")
|
||||
run_command("apt-get update", container)
|
||||
run_command("apt-get install -y python3 python3-pip python3-venv curl", container)
|
||||
|
||||
# Stop local services
|
||||
print("\n📋 Stopping local services...")
|
||||
subprocess.run("sudo fuser -k 8000/tcp 2>/dev/null || true", shell=True)
|
||||
subprocess.run("sudo fuser -k 9080/tcp 2>/dev/null || true", shell=True)
|
||||
subprocess.run("pkill -f 'marketplace-ui' 2>/dev/null || true", shell=True)
|
||||
subprocess.run("pkill -f 'trade-exchange' 2>/dev/null || true", shell=True)
|
||||
|
||||
# Copy project to container
|
||||
print("\n📁 Copying project to container...")
|
||||
subprocess.run(f"incus file push -r /home/oib/windsurf/aitbc {container}/home/oib/", shell=True)
|
||||
|
||||
# Setup Python environment in container
|
||||
print("\n🐍 Setting up Python environment...")
|
||||
run_command("cd /home/oib/aitbc && python3 -m venv .venv", container)
|
||||
run_command("cd /home/oib/aitbc && source .venv/bin/activate && pip install fastapi uvicorn httpx sqlmodel psutil", container)
|
||||
|
||||
# Install dependencies
|
||||
print("\n📦 Installing dependencies...")
|
||||
run_command("cd /home/oib/aitbc/apps/coordinator-api && source ../../.venv/bin/activate && pip install -e .", container)
|
||||
run_command("cd /home/oib/aitbc/apps/blockchain-node && source ../../.venv/bin/activate && pip install -e .", container)
|
||||
|
||||
# Create startup script with GPU miner
|
||||
print("\n🔧 Creating startup script with GPU miner...")
|
||||
startup_script = """#!/bin/bash
|
||||
cd /home/oib/aitbc
|
||||
source .venv/bin/activate
|
||||
|
||||
# Start coordinator API
|
||||
echo "Starting Coordinator API..."
|
||||
cd apps/coordinator-api
|
||||
source ../../.venv/bin/activate
|
||||
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 &
|
||||
COORD_PID=$!
|
||||
|
||||
# Start blockchain node
|
||||
echo "Starting Blockchain Node..."
|
||||
cd ../../apps/blockchain-node
|
||||
source ../../.venv/bin/activate
|
||||
python -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 9080 &
|
||||
BLOCK_PID=$!
|
||||
|
||||
# Start trade exchange
|
||||
echo "Starting Trade Exchange..."
|
||||
cd ../../apps/trade-exchange
|
||||
source ../../.venv/bin/activate
|
||||
python simple_exchange_api.py &
|
||||
EXCHANGE_PID=$!
|
||||
|
||||
# Start GPU registry
|
||||
echo "Starting GPU Registry..."
|
||||
cd ../..
|
||||
python gpu_registry_demo.py &
|
||||
REGISTRY_PID=$!
|
||||
|
||||
# Start GPU miner
|
||||
echo "Starting GPU Miner..."
|
||||
python gpu_miner_with_wait.py &
|
||||
MINER_PID=$!
|
||||
|
||||
echo "All services started!"
|
||||
echo "Coordinator API: http://10.1.223.93:8000"
|
||||
echo "Blockchain RPC: http://10.1.223.93:9080"
|
||||
echo "Trade Exchange: http://10.1.223.93:3002"
|
||||
echo "GPU Registry: http://10.1.223.93:8091"
|
||||
|
||||
# Wait for services
|
||||
wait $COORD_PID $BLOCK_PID $EXCHANGE_PID $REGISTRY_PID $MINER_PID
|
||||
"""
|
||||
|
||||
# Write startup script to container
|
||||
with open('/tmp/startup.sh', 'w') as f:
|
||||
f.write(startup_script)
|
||||
subprocess.run(f"incus file push /tmp/startup.sh {container}/home/oib/aitbc/", shell=True)
|
||||
run_command("chmod +x /home/oib/aitbc/startup.sh", container)
|
||||
|
||||
# Create systemd service
|
||||
print("\n⚙️ Creating systemd service...")
|
||||
service_content = """[Unit]
|
||||
Description=AITBC Services with GPU Miner
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=oib
|
||||
WorkingDirectory=/home/oib/aitbc
|
||||
ExecStart=/home/oib/aitbc/startup.sh
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
"""
|
||||
|
||||
with open('/tmp/aitbc.service', 'w') as f:
|
||||
f.write(service_content)
|
||||
subprocess.run(f"incus file push /tmp/aitbc.service {container}/tmp/", shell=True)
|
||||
run_command("mv /tmp/aitbc.service /etc/systemd/system/", container)
|
||||
run_command("systemctl daemon-reload", container)
|
||||
run_command("systemctl enable aitbc.service", container)
|
||||
run_command("systemctl start aitbc.service", container)
|
||||
|
||||
print("\n✅ Deployment complete!")
|
||||
print(f"\n📊 Service URLs:")
|
||||
print(f" - Coordinator API: http://{container_ip}:8000")
|
||||
print(f" - Blockchain RPC: http://{container_ip}:9080")
|
||||
print(f" - Trade Exchange: http://{container_ip}:3002")
|
||||
print(f" - GPU Registry: http://{container_ip}:8091")
|
||||
print(f"\n🔍 Check GPU status:")
|
||||
print(f" curl http://{container_ip}:8091/miners/list")
|
||||
|
||||
print(f"\n📋 To manage services in container:")
|
||||
print(f" incus exec {container} -- systemctl status aitbc")
|
||||
print(f" incus exec {container} -- journalctl -u aitbc -f")
|
||||
|
||||
if __name__ == "__main__":
|
||||
deploy_to_container()
|
||||
@@ -1,130 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Deploy GPU Miner Integration to AITBC Container
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
def run_in_container(cmd):
|
||||
"""Run command in aitbc container"""
|
||||
full_cmd = f"incus exec aitbc -- {cmd}"
|
||||
print(f"Running: {full_cmd}")
|
||||
result = subprocess.run(full_cmd, shell=True, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
print(f"Error: {result.stderr}")
|
||||
return False, result.stderr
|
||||
return True, result.stdout
|
||||
|
||||
def deploy_gpu_miner_to_container():
|
||||
print("🚀 Deploying GPU Miner Integration to AITBC Container...")
|
||||
|
||||
# Check container access
|
||||
print("\n1. 🔍 Checking container access...")
|
||||
success, output = run_in_container("whoami")
|
||||
if success:
|
||||
print(f" Container user: {output.strip()}")
|
||||
else:
|
||||
print(" ❌ Cannot access container")
|
||||
return
|
||||
|
||||
# Copy GPU miner files to container
|
||||
print("\n2. 📁 Copying GPU miner files...")
|
||||
files_to_copy = [
|
||||
"gpu_miner_with_wait.py",
|
||||
"gpu_registry_demo.py"
|
||||
]
|
||||
|
||||
for file in files_to_copy:
|
||||
cmd = f"incus file push /home/oib/windsurf/aitbc/{file} aitbc/home/oib/"
|
||||
print(f" Copying {file}...")
|
||||
result = subprocess.run(cmd, shell=True)
|
||||
if result.returncode == 0:
|
||||
print(f" ✅ {file} copied")
|
||||
else:
|
||||
print(f" ❌ Failed to copy {file}")
|
||||
|
||||
# Install dependencies in container
|
||||
print("\n3. 📦 Installing dependencies...")
|
||||
run_in_container("pip install httpx fastapi uvicorn psutil")
|
||||
|
||||
# Create GPU miner service in container
|
||||
print("\n4. ⚙️ Creating GPU miner service...")
|
||||
service_content = """[Unit]
|
||||
Description=AITBC GPU Miner Client
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=oib
|
||||
WorkingDirectory=/home/oib
|
||||
ExecStart=/usr/bin/python3 gpu_miner_with_wait.py
|
||||
Restart=always
|
||||
RestartSec=30
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
"""
|
||||
|
||||
# Write service file to container
|
||||
with open('/tmp/gpu-miner.service', 'w') as f:
|
||||
f.write(service_content)
|
||||
subprocess.run("incus file push /tmp/gpu-miner.service aitbc/tmp/", shell=True)
|
||||
run_in_container("sudo mv /tmp/gpu-miner.service /etc/systemd/system/")
|
||||
run_in_container("sudo systemctl daemon-reload")
|
||||
run_in_container("sudo systemctl enable gpu-miner.service")
|
||||
run_in_container("sudo systemctl start gpu-miner.service")
|
||||
|
||||
# Create GPU registry service in container
|
||||
print("\n5. 🎮 Creating GPU registry service...")
|
||||
registry_service = """[Unit]
|
||||
Description=AITBC GPU Registry
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=oib
|
||||
WorkingDirectory=/home/oib
|
||||
ExecStart=/usr/bin/python3 gpu_registry_demo.py
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
"""
|
||||
|
||||
with open('/tmp/gpu-registry.service', 'w') as f:
|
||||
f.write(registry_service)
|
||||
subprocess.run("incus file push /tmp/gpu-registry.service aitbc/tmp/", shell=True)
|
||||
run_in_container("sudo mv /tmp/gpu-registry.service /etc/systemd/system/")
|
||||
run_in_container("sudo systemctl daemon-reload")
|
||||
run_in_container("sudo systemctl enable gpu-registry.service")
|
||||
run_in_container("sudo systemctl start gpu-registry.service")
|
||||
|
||||
# Check services
|
||||
print("\n6. 📊 Checking services...")
|
||||
success, output = run_in_container("sudo systemctl status gpu-miner.service --no-pager")
|
||||
print(output)
|
||||
|
||||
success, output = run_in_container("sudo systemctl status gpu-registry.service --no-pager")
|
||||
print(output)
|
||||
|
||||
# Update coordinator to include miner endpoints
|
||||
print("\n7. 🔗 Updating coordinator API...")
|
||||
|
||||
print("\n✅ GPU Miner deployed to container!")
|
||||
print("\n📊 Access URLs:")
|
||||
print(" - Container IP: 10.1.223.93")
|
||||
print(" - GPU Registry: http://10.1.223.93:8091/miners/list")
|
||||
print(" - Coordinator API: http://10.1.223.93:8000")
|
||||
|
||||
print("\n🔧 To manage services in container:")
|
||||
print(" incus exec aitbc -- sudo systemctl status gpu-miner")
|
||||
print(" incus exec aitbc -- sudo journalctl -u gpu-miner -f")
|
||||
|
||||
if __name__ == "__main__":
|
||||
deploy_gpu_miner_to_container()
|
||||
@@ -1,113 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Setup gossip relay to connect blockchain nodes
|
||||
|
||||
set -e
|
||||
|
||||
echo "🌐 Setting up Gossip Relay for Blockchain Nodes"
|
||||
echo "=============================================="
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
# Stop existing nodes
|
||||
print_status "Stopping blockchain nodes..."
|
||||
sudo systemctl stop blockchain-node blockchain-node-2 blockchain-rpc blockchain-rpc-2 2>/dev/null || true
|
||||
|
||||
# Update node configurations to use broadcast backend
|
||||
print_status "Updating Node 1 configuration..."
|
||||
sudo cat > /opt/blockchain-node/.env << EOF
|
||||
CHAIN_ID=ait-devnet
|
||||
DB_PATH=./data/chain.db
|
||||
RPC_BIND_HOST=127.0.0.1
|
||||
RPC_BIND_PORT=8082
|
||||
P2P_BIND_HOST=0.0.0.0
|
||||
P2P_BIND_PORT=7070
|
||||
PROPOSER_KEY=node1_proposer_key_$(date +%s)
|
||||
MINT_PER_UNIT=1000
|
||||
COORDINATOR_RATIO=0.05
|
||||
GOSSIP_BACKEND=broadcast
|
||||
GOSSIP_BROADCAST_URL=http://127.0.0.1:7070/gossip
|
||||
EOF
|
||||
|
||||
print_status "Updating Node 2 configuration..."
|
||||
sudo cat > /opt/blockchain-node-2/.env << EOF
|
||||
CHAIN_ID=ait-devnet
|
||||
DB_PATH=./data/chain2.db
|
||||
RPC_BIND_HOST=127.0.0.1
|
||||
RPC_BIND_PORT=8081
|
||||
P2P_BIND_HOST=0.0.0.0
|
||||
P2P_BIND_PORT=7071
|
||||
PROPOSER_KEY=node2_proposer_key_$(date +%s)
|
||||
MINT_PER_UNIT=1000
|
||||
COORDINATOR_RATIO=0.05
|
||||
GOSSIP_BACKEND=broadcast
|
||||
GOSSIP_BROADCAST_URL=http://127.0.0.1:7070/gossip
|
||||
EOF
|
||||
|
||||
# Create gossip relay service
|
||||
print_status "Creating gossip relay service..."
|
||||
sudo cat > /etc/systemd/system/blockchain-gossip-relay.service << EOF
|
||||
[Unit]
|
||||
Description=AITBC Blockchain Gossip Relay
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=root
|
||||
WorkingDirectory=/opt/blockchain-node
|
||||
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
|
||||
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.gossip.relay --port 7070 --host 0.0.0.0
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Enable and start gossip relay
|
||||
print_status "Starting gossip relay..."
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable blockchain-gossip-relay
|
||||
sudo systemctl start blockchain-gossip-relay
|
||||
|
||||
# Wait for relay to start
|
||||
sleep 2
|
||||
|
||||
# Check if relay is running
|
||||
print_status "Checking gossip relay status..."
|
||||
sudo systemctl status blockchain-gossip-relay --no-pager | head -10
|
||||
|
||||
# Restart blockchain nodes
|
||||
print_status "Restarting blockchain nodes with shared gossip..."
|
||||
sudo systemctl start blockchain-node blockchain-node-2 blockchain-rpc blockchain-rpc-2
|
||||
|
||||
# Wait for nodes to start
|
||||
sleep 3
|
||||
|
||||
# Check status
|
||||
print_status "Checking node status..."
|
||||
sudo systemctl status blockchain-node blockchain-node-2 --no-pager | grep -E 'Active:|Main PID:'
|
||||
|
||||
echo ""
|
||||
print_status "✅ Gossip relay setup complete!"
|
||||
echo ""
|
||||
echo "Nodes are now connected via shared gossip backend."
|
||||
echo "They should sync blocks and transactions."
|
||||
echo ""
|
||||
echo "To verify connectivity:"
|
||||
echo " 1. Run: python /opt/test_blockchain_simple.py"
|
||||
echo " 2. Check if heights are converging"
|
||||
echo ""
|
||||
echo "Gossip relay logs: sudo journalctl -u blockchain-gossip-relay -f"
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test if blockchain node and explorer are running
|
||||
|
||||
echo "🔍 Testing Blockchain Deployment"
|
||||
echo "==============================="
|
||||
|
||||
# Test blockchain RPC
|
||||
echo "Testing blockchain RPC..."
|
||||
if curl -s http://aitbc.keisanki.net:8082/rpc/head > /dev/null; then
|
||||
echo "✅ Blockchain RPC is accessible"
|
||||
curl -s http://aitbc.keisanki.net:8082/rpc/head | jq '.height'
|
||||
else
|
||||
echo "❌ Blockchain RPC is not accessible"
|
||||
fi
|
||||
|
||||
# Test explorer
|
||||
echo ""
|
||||
echo "Testing blockchain explorer..."
|
||||
if curl -s http://aitbc.keisanki.net:3000 > /dev/null; then
|
||||
echo "✅ Explorer is accessible"
|
||||
else
|
||||
echo "❌ Explorer is not accessible"
|
||||
fi
|
||||
|
||||
# Check services on server
|
||||
echo ""
|
||||
echo "Checking service status on ns3..."
|
||||
ssh ns3-root "systemctl is-active blockchain-node blockchain-rpc nginx" | while read service status; do
|
||||
if [ "$status" = "active" ]; then
|
||||
echo "✅ $service is running"
|
||||
else
|
||||
echo "❌ $service is not running"
|
||||
fi
|
||||
done
|
||||
|
||||
# Check logs if needed
|
||||
echo ""
|
||||
echo "Recent blockchain logs:"
|
||||
ssh ns3-root "journalctl -u blockchain-node -n 5 --no-pager"
|
||||
@@ -1,89 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Deploy GPU Miner to AITBC Container - All in One
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Deploying GPU Miner to AITBC Container..."
|
||||
|
||||
# Step 1: Copy files
|
||||
echo "1. Copying GPU scripts..."
|
||||
scp -o StrictHostKeyChecking=no /home/oib/windsurf/aitbc/gpu_registry_demo.py aitbc:/home/oib/
|
||||
scp -o StrictHostKeyChecking=no /home/oib/windsurf/aitbc/gpu_miner_with_wait.py aitbc:/home/oib/
|
||||
|
||||
# Step 2: Install Python and deps
|
||||
echo "2. Installing Python and dependencies..."
|
||||
ssh aitbc 'sudo apt-get update -qq'
|
||||
ssh aitbc 'sudo apt-get install -y -qq python3 python3-venv python3-pip'
|
||||
ssh aitbc 'python3 -m venv /home/oib/.venv-gpu'
|
||||
ssh aitbc '/home/oib/.venv-gpu/bin/pip install -q fastapi uvicorn httpx psutil'
|
||||
|
||||
# Step 3: Create GPU registry service
|
||||
echo "3. Creating GPU registry service..."
|
||||
ssh aitbc "sudo tee /etc/systemd/system/aitbc-gpu-registry.service >/dev/null <<'EOF'
|
||||
[Unit]
|
||||
Description=AITBC GPU Registry
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=oib
|
||||
WorkingDirectory=/home/oib
|
||||
ExecStart=/home/oib/.venv-gpu/bin/python /home/oib/gpu_registry_demo.py
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF"
|
||||
|
||||
# Step 4: Start GPU registry
|
||||
echo "4. Starting GPU registry..."
|
||||
ssh aitbc 'sudo systemctl daemon-reload'
|
||||
ssh aitbc 'sudo systemctl enable --now aitbc-gpu-registry.service'
|
||||
|
||||
# Step 5: Create GPU miner service
|
||||
echo "5. Creating GPU miner service..."
|
||||
ssh aitbc "sudo tee /etc/systemd/system/aitbc-gpu-miner.service >/dev/null <<'EOF'
|
||||
[Unit]
|
||||
Description=AITBC GPU Miner Client
|
||||
After=network.target aitbc-gpu-registry.service
|
||||
Wants=aitbc-gpu-registry.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=oib
|
||||
WorkingDirectory=/home/oib
|
||||
ExecStart=/home/oib/.venv-gpu/bin/python /home/oib/gpu_miner_with_wait.py
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF"
|
||||
|
||||
# Step 6: Start GPU miner
|
||||
echo "6. Starting GPU miner..."
|
||||
ssh aitbc 'sudo systemctl daemon-reload'
|
||||
ssh aitbc 'sudo systemctl enable --now aitbc-gpu-miner.service'
|
||||
|
||||
# Step 7: Check services
|
||||
echo "7. Checking services..."
|
||||
echo -e "\n=== GPU Registry Service ==="
|
||||
ssh aitbc 'sudo systemctl status aitbc-gpu-registry.service --no-pager'
|
||||
|
||||
echo -e "\n=== GPU Miner Service ==="
|
||||
ssh aitbc 'sudo systemctl status aitbc-gpu-miner.service --no-pager'
|
||||
|
||||
# Step 8: Verify GPU registration
|
||||
echo -e "\n8. Verifying GPU registration..."
|
||||
sleep 3
|
||||
echo " curl http://10.1.223.93:8091/miners/list"
|
||||
curl -s http://10.1.223.93:8091/miners/list | python3 -c "import sys,json; data=json.load(sys.stdin); print(f'✅ Found {len(data.get(\"gpus\", []))} GPU(s)'); [print(f' - {gpu[\"capabilities\"][\"gpu\"][\"model\"]} ({gpu[\"capabilities\"][\"gpu\"][\"memory_gb\"]}GB)') for gpu in data.get('gpus', [])]"
|
||||
|
||||
echo -e "\n✅ Deployment complete!"
|
||||
echo "GPU Registry: http://10.1.223.93:8091"
|
||||
echo "GPU Miner: Running and sending heartbeats"
|
||||
@@ -1,89 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Deploy GPU Miner to AITBC Container
|
||||
|
||||
echo "🚀 Deploying GPU Miner to AITBC Container..."
|
||||
|
||||
# Check if container is accessible
|
||||
echo "1. Checking container access..."
|
||||
sudo incus exec aitbc -- whoami
|
||||
|
||||
# Copy GPU miner files
|
||||
echo "2. Copying GPU miner files..."
|
||||
sudo incus file push /home/oib/windsurf/aitbc/gpu_miner_with_wait.py aitbc/home/oib/
|
||||
sudo incus file push /home/oib/windsurf/aitbc/gpu_registry_demo.py aitbc/home/oib/
|
||||
|
||||
# Install dependencies
|
||||
echo "3. Installing dependencies..."
|
||||
sudo incus exec aitbc -- pip install httpx fastapi uvicorn psutil
|
||||
|
||||
# Create GPU miner service
|
||||
echo "4. Creating GPU miner service..."
|
||||
cat << 'EOF' | sudo tee /tmp/gpu-miner.service
|
||||
[Unit]
|
||||
Description=AITBC GPU Miner Client
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=oib
|
||||
WorkingDirectory=/home/oib
|
||||
ExecStart=/usr/bin/python3 gpu_miner_with_wait.py
|
||||
Restart=always
|
||||
RestartSec=30
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
sudo incus file push /tmp/gpu-miner.service aitbc/tmp/
|
||||
sudo incus exec aitbc -- sudo mv /tmp/gpu-miner.service /etc/systemd/system/
|
||||
sudo incus exec aitbc -- sudo systemctl daemon-reload
|
||||
sudo incus exec aitbc -- sudo systemctl enable gpu-miner.service
|
||||
sudo incus exec aitbc -- sudo systemctl start gpu-miner.service
|
||||
|
||||
# Create GPU registry service
|
||||
echo "5. Creating GPU registry service..."
|
||||
cat << 'EOF' | sudo tee /tmp/gpu-registry.service
|
||||
[Unit]
|
||||
Description=AITBC GPU Registry
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=oib
|
||||
WorkingDirectory=/home/oib
|
||||
ExecStart=/usr/bin/python3 gpu_registry_demo.py
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
sudo incus file push /tmp/gpu-registry.service aitbc/tmp/
|
||||
sudo incus exec aitbc -- sudo mv /tmp/gpu-registry.service /etc/systemd/system/
|
||||
sudo incus exec aitbc -- sudo systemctl daemon-reload
|
||||
sudo incus exec aitbc -- sudo systemctl enable gpu-registry.service
|
||||
sudo incus exec aitbc -- sudo systemctl start gpu-registry.service
|
||||
|
||||
# Check services
|
||||
echo "6. Checking services..."
|
||||
echo "GPU Miner Service:"
|
||||
sudo incus exec aitbc -- sudo systemctl status gpu-miner.service --no-pager
|
||||
|
||||
echo -e "\nGPU Registry Service:"
|
||||
sudo incus exec aitbc -- sudo systemctl status gpu-registry.service --no-pager
|
||||
|
||||
# Show access URLs
|
||||
echo -e "\n✅ Deployment complete!"
|
||||
echo "Access URLs:"
|
||||
echo " - Container IP: 10.1.223.93"
|
||||
echo " - GPU Registry: http://10.1.223.93:8091/miners/list"
|
||||
echo " - Coordinator API: http://10.1.223.93:8000"
|
||||
|
||||
echo -e "\nTo check GPU status:"
|
||||
echo " curl http://10.1.223.93:8091/miners/list"
|
||||
@@ -1,92 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
GPU Exchange Integration Demo
|
||||
Shows how the GPU miner is integrated with the exchange
|
||||
"""
|
||||
|
||||
import json
|
||||
import httpx
|
||||
import subprocess
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
print("🔗 AITBC GPU Exchange Integration")
|
||||
print("=" * 50)
|
||||
|
||||
# Check GPU Registry
|
||||
print("\n1. 📊 Checking GPU Registry...")
|
||||
try:
|
||||
response = httpx.get("http://localhost:8091/miners/list")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
gpus = data.get("gpus", [])
|
||||
print(f" Found {len(gpus)} registered GPU(s)")
|
||||
|
||||
for gpu in gpus:
|
||||
print(f"\n 🎮 GPU Details:")
|
||||
print(f" Model: {gpu['capabilities']['gpu']['model']}")
|
||||
print(f" Memory: {gpu['capabilities']['gpu']['memory_gb']} GB")
|
||||
print(f" CUDA: {gpu['capabilities']['gpu']['cuda_version']}")
|
||||
print(f" Status: {gpu.get('status', 'Unknown')}")
|
||||
print(f" Region: {gpu.get('region', 'Unknown')}")
|
||||
else:
|
||||
print(" ❌ GPU Registry not accessible")
|
||||
except Exception as e:
|
||||
print(f" ❌ Error: {e}")
|
||||
|
||||
# Check Exchange
|
||||
print("\n2. 💰 Checking Trade Exchange...")
|
||||
try:
|
||||
response = httpx.get("http://localhost:3002")
|
||||
if response.status_code == 200:
|
||||
print(" ✅ Trade Exchange is running")
|
||||
print(" 🌐 URL: http://localhost:3002")
|
||||
else:
|
||||
print(" ❌ Trade Exchange not responding")
|
||||
except:
|
||||
print(" ❌ Trade Exchange not accessible")
|
||||
|
||||
# Check Blockchain
|
||||
print("\n3. ⛓️ Checking Blockchain Node...")
|
||||
try:
|
||||
response = httpx.get("http://localhost:9080/rpc/head")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print(f" ✅ Blockchain Node active")
|
||||
print(f" Block Height: {data.get('height', 'Unknown')}")
|
||||
print(f" Block Hash: {data.get('hash', 'Unknown')[:16]}...")
|
||||
else:
|
||||
print(" ❌ Blockchain Node not responding")
|
||||
except:
|
||||
print(" ❌ Blockchain Node not accessible")
|
||||
|
||||
# Show Integration Points
|
||||
print("\n4. 🔌 Integration Points:")
|
||||
print(" • GPU Registry: http://localhost:8091/miners/list")
|
||||
print(" • Trade Exchange: http://localhost:3002")
|
||||
print(" • Blockchain RPC: http://localhost:9080")
|
||||
print(" • GPU Marketplace: Exchange > Browse GPU Marketplace")
|
||||
|
||||
# Show API Usage
|
||||
print("\n5. 📡 API Usage Examples:")
|
||||
print("\n Get registered GPUs:")
|
||||
print(" curl http://localhost:8091/miners/list")
|
||||
print("\n Get GPU details:")
|
||||
print(" curl http://localhost:8091/miners/localhost-gpu-miner")
|
||||
print("\n Get blockchain info:")
|
||||
print(" curl http://localhost:9080/rpc/head")
|
||||
|
||||
# Show Current Status
|
||||
print("\n6. 📈 Current System Status:")
|
||||
print(" ✅ GPU Miner: Running (systemd)")
|
||||
print(" ✅ GPU Registry: Running on port 8091")
|
||||
print(" ✅ Trade Exchange: Running on port 3002")
|
||||
print(" ✅ Blockchain Node: Running on port 9080")
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("🎯 GPU is successfully integrated with the exchange!")
|
||||
print("\nNext steps:")
|
||||
print("1. Open http://localhost:3002 in your browser")
|
||||
print("2. Click 'Browse GPU Marketplace'")
|
||||
print("3. View the registered RTX 4060 Ti GPU")
|
||||
print("4. Purchase GPU compute time with AITBC tokens")
|
||||
@@ -1,396 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Real GPU Miner Client for AITBC - runs on host with actual GPU
|
||||
"""
|
||||
|
||||
import json
|
||||
import time
|
||||
import httpx
|
||||
import logging
|
||||
import sys
|
||||
import subprocess
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
# Configuration
|
||||
COORDINATOR_URL = "http://127.0.0.1:18000"
|
||||
MINER_ID = "${MINER_API_KEY}"
|
||||
AUTH_TOKEN = "${MINER_API_KEY}"
|
||||
HEARTBEAT_INTERVAL = 15
|
||||
MAX_RETRIES = 10
|
||||
RETRY_DELAY = 30
|
||||
|
||||
# Setup logging with explicit configuration
|
||||
LOG_PATH = "/home/oib/windsurf/aitbc/logs/host_gpu_miner.log"
|
||||
os.makedirs(os.path.dirname(LOG_PATH), exist_ok=True)
|
||||
|
||||
class FlushHandler(logging.StreamHandler):
|
||||
def emit(self, record):
|
||||
super().emit(record)
|
||||
self.flush()
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
FlushHandler(sys.stdout),
|
||||
logging.FileHandler(LOG_PATH)
|
||||
]
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Force stdout to be unbuffered
|
||||
sys.stdout.reconfigure(line_buffering=True)
|
||||
sys.stderr.reconfigure(line_buffering=True)
|
||||
|
||||
# GPU capabilities (RTX 4060 Ti)
|
||||
GPU_CAPABILITIES = {
|
||||
"gpu": {
|
||||
"model": "NVIDIA GeForce RTX 4060 Ti",
|
||||
"memory_gb": 16,
|
||||
"cuda_version": "12.4",
|
||||
"platform": "CUDA",
|
||||
"supported_tasks": ["inference", "training", "stable-diffusion", "llama"],
|
||||
"max_concurrent_jobs": 1
|
||||
}
|
||||
}
|
||||
|
||||
def get_gpu_info():
|
||||
"""Get real GPU information"""
|
||||
try:
|
||||
result = subprocess.run(['nvidia-smi', '--query-gpu=name,memory.total,memory.used,utilization.gpu',
|
||||
'--format=csv,noheader,nounits'],
|
||||
capture_output=True, text=True, timeout=5)
|
||||
if result.returncode == 0:
|
||||
info = result.stdout.strip().split(', ')
|
||||
return {
|
||||
"name": info[0],
|
||||
"memory_total": int(info[1]),
|
||||
"memory_used": int(info[2]),
|
||||
"utilization": int(info[3])
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to get GPU info: {e}")
|
||||
return None
|
||||
|
||||
def check_ollama():
|
||||
"""Check if Ollama is running and has models"""
|
||||
try:
|
||||
response = httpx.get("http://localhost:11434/api/tags", timeout=5)
|
||||
if response.status_code == 200:
|
||||
models = response.json().get('models', [])
|
||||
model_names = [m['name'] for m in models]
|
||||
logger.info(f"Ollama running with models: {model_names}")
|
||||
return True, model_names
|
||||
else:
|
||||
logger.error("Ollama not responding")
|
||||
return False, []
|
||||
except Exception as e:
|
||||
logger.error(f"Ollama check failed: {e}")
|
||||
return False, []
|
||||
|
||||
def wait_for_coordinator():
|
||||
"""Wait for coordinator to be available"""
|
||||
for i in range(MAX_RETRIES):
|
||||
try:
|
||||
response = httpx.get(f"{COORDINATOR_URL}/v1/health", timeout=5)
|
||||
if response.status_code == 200:
|
||||
logger.info("Coordinator is available!")
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
|
||||
logger.info(f"Waiting for coordinator... ({i+1}/{MAX_RETRIES})")
|
||||
time.sleep(RETRY_DELAY)
|
||||
|
||||
logger.error("Coordinator not available after max retries")
|
||||
return False
|
||||
|
||||
def register_miner():
|
||||
"""Register the miner with the coordinator"""
|
||||
register_data = {
|
||||
"capabilities": GPU_CAPABILITIES,
|
||||
"concurrency": 1,
|
||||
"region": "localhost"
|
||||
}
|
||||
|
||||
headers = {
|
||||
"X-Api-Key": AUTH_TOKEN,
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
try:
|
||||
response = httpx.post(
|
||||
f"{COORDINATOR_URL}/v1/miners/register?miner_id={MINER_ID}",
|
||||
json=register_data,
|
||||
headers=headers,
|
||||
timeout=10
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
logger.info(f"Successfully registered miner: {data}")
|
||||
return data.get("session_token", "demo-token")
|
||||
else:
|
||||
logger.error(f"Registration failed: {response.status_code} - {response.text}")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Registration error: {e}")
|
||||
return None
|
||||
|
||||
def send_heartbeat():
|
||||
"""Send heartbeat to coordinator with real GPU stats"""
|
||||
gpu_info = get_gpu_info()
|
||||
|
||||
if gpu_info:
|
||||
heartbeat_data = {
|
||||
"status": "active",
|
||||
"current_jobs": 0,
|
||||
"last_seen": datetime.utcnow().isoformat(),
|
||||
"gpu_utilization": gpu_info["utilization"],
|
||||
"memory_used": gpu_info["memory_used"],
|
||||
"memory_total": gpu_info["memory_total"]
|
||||
}
|
||||
else:
|
||||
heartbeat_data = {
|
||||
"status": "active",
|
||||
"current_jobs": 0,
|
||||
"last_seen": datetime.utcnow().isoformat(),
|
||||
"gpu_utilization": 0,
|
||||
"memory_used": 0,
|
||||
}
|
||||
|
||||
headers = {
|
||||
"X-Api-Key": AUTH_TOKEN,
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
try:
|
||||
response = httpx.post(
|
||||
f"{COORDINATOR_URL}/v1/miners/heartbeat?miner_id={MINER_ID}",
|
||||
json=heartbeat_data,
|
||||
headers=headers,
|
||||
timeout=5
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
logger.info(f"Heartbeat sent (GPU: {gpu_info['utilization'] if gpu_info else 'N/A'}%)")
|
||||
else:
|
||||
logger.error(f"Heartbeat failed: {response.status_code} - {response.text}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Heartbeat error: {e}")
|
||||
|
||||
def execute_job(job, available_models):
|
||||
"""Execute a job using real GPU resources"""
|
||||
job_id = job.get('job_id')
|
||||
payload = job.get('payload', {})
|
||||
|
||||
logger.info(f"Executing job {job_id}: {payload}")
|
||||
|
||||
try:
|
||||
if payload.get('type') == 'inference':
|
||||
# Get the prompt and model
|
||||
prompt = payload.get('prompt', '')
|
||||
model = payload.get('model', 'llama3.2:latest')
|
||||
|
||||
# Check if model is available
|
||||
if model not in available_models:
|
||||
# Use first available model
|
||||
if available_models:
|
||||
model = available_models[0]
|
||||
logger.info(f"Using available model: {model}")
|
||||
else:
|
||||
raise Exception("No models available in Ollama")
|
||||
|
||||
# Call Ollama API for real GPU inference
|
||||
logger.info(f"Running inference on GPU with model: {model}")
|
||||
start_time = time.time()
|
||||
|
||||
ollama_response = httpx.post(
|
||||
"http://localhost:11434/api/generate",
|
||||
json={
|
||||
"model": model,
|
||||
"prompt": prompt,
|
||||
"stream": False
|
||||
},
|
||||
timeout=60
|
||||
)
|
||||
|
||||
if ollama_response.status_code == 200:
|
||||
result = ollama_response.json()
|
||||
output = result.get('response', '')
|
||||
execution_time = time.time() - start_time
|
||||
|
||||
# Get GPU stats after execution
|
||||
gpu_after = get_gpu_info()
|
||||
|
||||
# Submit result back to coordinator
|
||||
submit_result(job_id, {
|
||||
"result": {
|
||||
"status": "completed",
|
||||
"output": output,
|
||||
"model": model,
|
||||
"tokens_processed": result.get('eval_count', 0),
|
||||
"execution_time": execution_time,
|
||||
"gpu_used": True
|
||||
},
|
||||
"metrics": {
|
||||
"gpu_utilization": gpu_after["utilization"] if gpu_after else 0,
|
||||
"memory_used": gpu_after["memory_used"] if gpu_after else 0,
|
||||
"memory_peak": max(gpu_after["memory_used"] if gpu_after else 0, 2048)
|
||||
}
|
||||
})
|
||||
|
||||
logger.info(f"Job {job_id} completed in {execution_time:.2f}s")
|
||||
return True
|
||||
else:
|
||||
logger.error(f"Ollama error: {ollama_response.status_code}")
|
||||
submit_result(job_id, {
|
||||
"result": {
|
||||
"status": "failed",
|
||||
"error": f"Ollama error: {ollama_response.text}"
|
||||
}
|
||||
})
|
||||
return False
|
||||
else:
|
||||
# Unsupported job type
|
||||
logger.error(f"Unsupported job type: {payload.get('type')}")
|
||||
submit_result(job_id, {
|
||||
"result": {
|
||||
"status": "failed",
|
||||
"error": f"Unsupported job type: {payload.get('type')}"
|
||||
}
|
||||
})
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Job execution error: {e}")
|
||||
submit_result(job_id, {
|
||||
"result": {
|
||||
"status": "failed",
|
||||
"error": str(e)
|
||||
}
|
||||
})
|
||||
return False
|
||||
|
||||
def submit_result(job_id, result):
|
||||
"""Submit job result to coordinator"""
|
||||
headers = {
|
||||
"X-Api-Key": AUTH_TOKEN,
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
try:
|
||||
response = httpx.post(
|
||||
f"{COORDINATOR_URL}/v1/miners/{job_id}/result",
|
||||
json=result,
|
||||
headers=headers,
|
||||
timeout=10
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
logger.info(f"Result submitted for job {job_id}")
|
||||
else:
|
||||
logger.error(f"Result submission failed: {response.status_code} - {response.text}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Result submission error: {e}")
|
||||
|
||||
def poll_for_jobs():
|
||||
"""Poll for available jobs"""
|
||||
poll_data = {
|
||||
"max_wait_seconds": 5
|
||||
}
|
||||
|
||||
headers = {
|
||||
"X-Api-Key": AUTH_TOKEN,
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
try:
|
||||
response = httpx.post(
|
||||
f"{COORDINATOR_URL}/v1/miners/poll",
|
||||
json=poll_data,
|
||||
headers=headers,
|
||||
timeout=10
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
job = response.json()
|
||||
logger.info(f"Received job: {job}")
|
||||
return job
|
||||
elif response.status_code == 204:
|
||||
return None
|
||||
else:
|
||||
logger.error(f"Poll failed: {response.status_code} - {response.text}")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error polling for jobs: {e}")
|
||||
return None
|
||||
|
||||
def main():
|
||||
"""Main miner loop"""
|
||||
logger.info("Starting Real GPU Miner Client on Host...")
|
||||
|
||||
# Check GPU availability
|
||||
gpu_info = get_gpu_info()
|
||||
if not gpu_info:
|
||||
logger.error("GPU not available, exiting")
|
||||
sys.exit(1)
|
||||
|
||||
logger.info(f"GPU detected: {gpu_info['name']} ({gpu_info['memory_total']}MB)")
|
||||
|
||||
# Check Ollama
|
||||
ollama_available, models = check_ollama()
|
||||
if not ollama_available:
|
||||
logger.error("Ollama not available - please install and start Ollama")
|
||||
sys.exit(1)
|
||||
|
||||
logger.info(f"Ollama models available: {', '.join(models)}")
|
||||
|
||||
# Wait for coordinator
|
||||
if not wait_for_coordinator():
|
||||
sys.exit(1)
|
||||
|
||||
# Register with coordinator
|
||||
session_token = register_miner()
|
||||
if not session_token:
|
||||
logger.error("Failed to register, exiting")
|
||||
sys.exit(1)
|
||||
|
||||
logger.info("Miner registered successfully, starting main loop...")
|
||||
|
||||
# Main loop
|
||||
last_heartbeat = 0
|
||||
last_poll = 0
|
||||
|
||||
try:
|
||||
while True:
|
||||
current_time = time.time()
|
||||
|
||||
# Send heartbeat
|
||||
if current_time - last_heartbeat >= HEARTBEAT_INTERVAL:
|
||||
send_heartbeat()
|
||||
last_heartbeat = current_time
|
||||
|
||||
# Poll for jobs
|
||||
if current_time - last_poll >= 3:
|
||||
job = poll_for_jobs()
|
||||
if job:
|
||||
# Execute the job with real GPU
|
||||
execute_job(job, models)
|
||||
last_poll = current_time
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
logger.info("Shutting down miner...")
|
||||
except Exception as e:
|
||||
logger.error(f"Error in main loop: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Wrapper script for GPU miner to ensure proper logging
|
||||
exec /home/oib/windsurf/aitbc/.venv/bin/python -u /home/oib/windsurf/aitbc/scripts/gpu/gpu_miner_host.py 2>&1
|
||||
@@ -1,72 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simple GPU Registry Server for demonstration
|
||||
"""
|
||||
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from typing import Dict, Any, Optional
|
||||
import uvicorn
|
||||
from datetime import datetime
|
||||
|
||||
app = FastAPI(title="GPU Registry Demo")
|
||||
|
||||
# In-memory storage
|
||||
registered_gpus: Dict[str, Dict] = {}
|
||||
|
||||
class GPURegistration(BaseModel):
|
||||
capabilities: Dict[str, Any]
|
||||
concurrency: int = 1
|
||||
region: Optional[str] = None
|
||||
|
||||
class Heartbeat(BaseModel):
|
||||
inflight: int = 0
|
||||
status: str = "ONLINE"
|
||||
metadata: Dict[str, Any] = {}
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
return {"message": "GPU Registry Demo", "registered_gpus": len(registered_gpus)}
|
||||
|
||||
@app.get("/health")
|
||||
async def health():
|
||||
return {"status": "ok"}
|
||||
|
||||
@app.post("/miners/register")
|
||||
async def register_gpu(miner_id: str, gpu_data: GPURegistration):
|
||||
"""Register a GPU miner"""
|
||||
registered_gpus[miner_id] = {
|
||||
"id": miner_id,
|
||||
"registered_at": datetime.utcnow().isoformat(),
|
||||
"last_heartbeat": datetime.utcnow().isoformat(),
|
||||
**gpu_data.dict()
|
||||
}
|
||||
return {"status": "ok", "message": f"GPU {miner_id} registered successfully"}
|
||||
|
||||
@app.post("/miners/heartbeat")
|
||||
async def heartbeat(miner_id: str, heartbeat_data: Heartbeat):
|
||||
"""Receive heartbeat from GPU miner"""
|
||||
if miner_id not in registered_gpus:
|
||||
raise HTTPException(status_code=404, detail="GPU not registered")
|
||||
|
||||
registered_gpus[miner_id]["last_heartbeat"] = datetime.utcnow().isoformat()
|
||||
registered_gpus[miner_id]["status"] = heartbeat_data.status
|
||||
registered_gpus[miner_id]["metadata"] = heartbeat_data.metadata
|
||||
|
||||
return {"status": "ok"}
|
||||
|
||||
@app.get("/miners/list")
|
||||
async def list_gpus():
|
||||
"""List all registered GPUs"""
|
||||
return {"gpus": list(registered_gpus.values())}
|
||||
|
||||
@app.get("/miners/{miner_id}")
|
||||
async def get_gpu(miner_id: str):
|
||||
"""Get details of a specific GPU"""
|
||||
if miner_id not in registered_gpus:
|
||||
raise HTTPException(status_code=404, detail="GPU not registered")
|
||||
return registered_gpus[miner_id]
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Starting GPU Registry Demo on http://localhost:8091")
|
||||
uvicorn.run(app, host="0.0.0.0", port=8091)
|
||||
@@ -1,146 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Integrate GPU Miner with existing Trade Exchange
|
||||
"""
|
||||
|
||||
import httpx
|
||||
import json
|
||||
import subprocess
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
# Configuration
|
||||
EXCHANGE_URL = "http://localhost:3002"
|
||||
GPU_REGISTRY_URL = "http://localhost:8091"
|
||||
|
||||
def update_exchange_with_gpu():
|
||||
"""Update the exchange frontend to show registered GPUs"""
|
||||
|
||||
# Read the exchange HTML
|
||||
with open('/home/oib/windsurf/aitbc/apps/trade-exchange/index.html', 'r') as f:
|
||||
html_content = f.read()
|
||||
|
||||
# Add GPU marketplace integration
|
||||
gpu_integration = """
|
||||
<script>
|
||||
// GPU Integration
|
||||
async function loadRealGPUOffers() {
|
||||
try {
|
||||
const response = await fetch('http://localhost:8091/miners/list');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.gpus && data.gpus.length > 0) {
|
||||
displayRealGPUOffers(data.gpus);
|
||||
} else {
|
||||
displayDemoOffers();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Using demo GPU offers');
|
||||
displayDemoOffers();
|
||||
}
|
||||
}
|
||||
|
||||
function displayRealGPUOffers(gpus) {
|
||||
const container = document.getElementById('gpuList');
|
||||
container.innerHTML = '';
|
||||
|
||||
gpus.forEach(gpu => {
|
||||
const gpuCard = `
|
||||
<div class="bg-white rounded-lg shadow-lg p-6 card-hover">
|
||||
<div class="flex justify-between items-start mb-4">
|
||||
<h3 class="text-lg font-semibold">${gpu.capabilities.gpu.model}</h3>
|
||||
<span class="bg-green-100 text-green-800 px-2 py-1 rounded text-sm">Available</span>
|
||||
</div>
|
||||
<div class="space-y-2 text-sm text-gray-600 mb-4">
|
||||
<p><i data-lucide="monitor" class="w-4 h-4 inline mr-1"></i>Memory: ${gpu.capabilities.gpu.memory_gb} GB</p>
|
||||
<p><i data-lucide="zap" class="w-4 h-4 inline mr-1"></i>CUDA: ${gpu.capabilities.gpu.cuda_version}</p>
|
||||
<p><i data-lucide="cpu" class="w-4 h-4 inline mr-1"></i>Concurrency: ${gpu.concurrency}</p>
|
||||
<p><i data-lucide="map-pin" class="w-4 h-4 inline mr-1"></i>Region: ${gpu.region}</p>
|
||||
</div>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-2xl font-bold text-purple-600">50 AITBC/hr</span>
|
||||
<button onclick="purchaseGPU('${gpu.id}')" class="bg-purple-600 text-white px-4 py-2 rounded hover:bg-purple-700 transition">
|
||||
Purchase
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
container.innerHTML += gpuCard;
|
||||
});
|
||||
|
||||
lucide.createIcons();
|
||||
}
|
||||
|
||||
// Override the loadGPUOffers function
|
||||
const originalLoadGPUOffers = loadGPUOffers;
|
||||
loadGPUOffers = loadRealGPUOffers;
|
||||
</script>
|
||||
"""
|
||||
|
||||
# Insert before closing body tag
|
||||
if '</body>' in html_content:
|
||||
html_content = html_content.replace('</body>', gpu_integration + '</body>')
|
||||
|
||||
# Write back to file
|
||||
with open('/home/oib/windsurf/aitbc/apps/trade-exchange/index.html', 'w') as f:
|
||||
f.write(html_content)
|
||||
|
||||
print("✅ Updated exchange with GPU integration!")
|
||||
else:
|
||||
print("❌ Could not find </body> tag in exchange HTML")
|
||||
|
||||
def create_gpu_api_endpoint():
|
||||
"""Create an API endpoint in the exchange to serve GPU data"""
|
||||
|
||||
api_code = """
|
||||
@app.get("/api/gpu/offers")
|
||||
async def get_gpu_offers():
|
||||
\"\"\"Get available GPU offers\"\"\"
|
||||
try:
|
||||
# Fetch from GPU registry
|
||||
response = httpx.get("http://localhost:8091/miners/list")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
return {"offers": data.get("gpus", [])}
|
||||
except:
|
||||
pass
|
||||
|
||||
# Return demo data if registry not available
|
||||
return {
|
||||
"offers": [{
|
||||
"id": "demo-gpu-1",
|
||||
"model": "NVIDIA RTX 4060 Ti",
|
||||
"memory_gb": 16,
|
||||
"price_per_hour": 50,
|
||||
"available": True
|
||||
}]
|
||||
}
|
||||
"""
|
||||
|
||||
print("\n📝 To add GPU API endpoint to exchange, add this code to simple_exchange_api.py:")
|
||||
print(api_code)
|
||||
|
||||
def main():
|
||||
print("🔗 Integrating GPU Miner with Trade Exchange...")
|
||||
|
||||
# Update exchange frontend
|
||||
update_exchange_with_gpu()
|
||||
|
||||
# Show API integration code
|
||||
create_gpu_api_endpoint()
|
||||
|
||||
print("\n📊 Integration Summary:")
|
||||
print("1. ✅ Exchange frontend updated to show real GPUs")
|
||||
print("2. 📝 See above for API endpoint code")
|
||||
print("3. 🌐 Access the exchange at: http://localhost:3002")
|
||||
print("4. 🎯 GPU Registry available at: http://localhost:8091/miners/list")
|
||||
|
||||
print("\n🔄 To see the integrated GPU marketplace:")
|
||||
print("1. Restart the trade exchange if needed:")
|
||||
print(" cd /home/oib/windsurf/aitbc/apps/trade-exchange")
|
||||
print(" python simple_exchange_api.py")
|
||||
print("2. Open http://localhost:3002 in browser")
|
||||
print("3. Click 'Browse GPU Marketplace'")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Start GPU Miner Client
|
||||
|
||||
echo "=== AITBC GPU Miner Client Startup ==="
|
||||
echo "Starting GPU miner client..."
|
||||
echo ""
|
||||
|
||||
# Check if GPU is available
|
||||
if ! command -v nvidia-smi &> /dev/null; then
|
||||
echo "WARNING: nvidia-smi not found, GPU may not be available"
|
||||
fi
|
||||
|
||||
# Show GPU info
|
||||
if command -v nvidia-smi &> /dev/null; then
|
||||
echo "=== GPU Status ==="
|
||||
nvidia-smi --query-gpu=name,memory.used,memory.total,utilization.gpu,temperature.gpu --format=csv,noheader,nounits
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Check if coordinator is running
|
||||
echo "=== Checking Coordinator API ==="
|
||||
if curl -s http://localhost:8000/health > /dev/null 2>&1; then
|
||||
echo "✓ Coordinator API is running on port 8000"
|
||||
else
|
||||
echo "✗ Coordinator API is not accessible on port 8000"
|
||||
echo " The miner will wait for the coordinator to start..."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Starting GPU Miner ==="
|
||||
cd /home/oib/windsurf/aitbc
|
||||
python3 gpu_miner_with_wait.py
|
||||
52
scripts/gpu/start_gpu_miner.sh.example
Normal file
52
scripts/gpu/start_gpu_miner.sh.example
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
|
||||
# AITBC GPU Miner Startup Script
|
||||
# Copy to start_gpu_miner.sh and adjust variables for your environment
|
||||
|
||||
set -e
|
||||
|
||||
# === CONFIGURE THESE ===
|
||||
COORDINATOR_URL="http://YOUR_COORDINATOR_IP:18000"
|
||||
MINER_API_KEY="your_miner_api_key"
|
||||
OLLAMA_HOST="http://127.0.0.1:11434"
|
||||
GPU_ID="gpu-0"
|
||||
|
||||
echo "🔧 Starting AITBC GPU Miner"
|
||||
echo "Coordinator: $COORDINATOR_URL"
|
||||
echo "Ollama: $OLLAMA_HOST"
|
||||
echo ""
|
||||
|
||||
# Check Ollama is running
|
||||
if ! curl -s "$OLLAMA_HOST/api/tags" > /dev/null 2>&1; then
|
||||
echo "❌ Ollama not running at $OLLAMA_HOST"
|
||||
echo "Start it with: ollama serve"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Ollama is running"
|
||||
|
||||
# Check GPU
|
||||
if command -v nvidia-smi &> /dev/null; then
|
||||
echo "GPU detected:"
|
||||
nvidia-smi --query-gpu=name,memory.total --format=csv,noheader
|
||||
else
|
||||
echo "⚠️ No NVIDIA GPU detected (CPU-only mode)"
|
||||
fi
|
||||
|
||||
# Register miner
|
||||
echo ""
|
||||
echo "Registering miner with coordinator..."
|
||||
curl -s -X POST "$COORDINATOR_URL/v1/miners/register" \
|
||||
-H "X-Api-Key: $MINER_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"gpu_id\": \"$GPU_ID\", \"ollama_url\": \"$OLLAMA_HOST\"}"
|
||||
|
||||
echo ""
|
||||
echo "✅ Miner registered. Starting heartbeat loop..."
|
||||
|
||||
# Heartbeat + job polling loop
|
||||
while true; do
|
||||
curl -s -X POST "$COORDINATOR_URL/v1/miners/heartbeat" \
|
||||
-H "X-Api-Key: $MINER_API_KEY" > /dev/null 2>&1
|
||||
sleep 10
|
||||
done
|
||||
@@ -1,72 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check what's running in the aitbc container
|
||||
|
||||
echo "🔍 Checking AITBC Container Status"
|
||||
echo "================================="
|
||||
|
||||
# First, let's see if we can access the container
|
||||
if ! groups | grep -q incus; then
|
||||
echo "❌ You're not in the incus group!"
|
||||
echo "Run: sudo usermod -aG incus \$USER"
|
||||
echo "Then log out and log back in"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📋 Container Info:"
|
||||
incus list | grep aitbc
|
||||
|
||||
echo ""
|
||||
echo "🔧 Services in container:"
|
||||
incus exec aitbc -- ps aux | grep -E "(uvicorn|python)" | grep -v grep || echo "No services running"
|
||||
|
||||
echo ""
|
||||
echo "🌐 Ports listening in container:"
|
||||
incus exec aitbc -- ss -tlnp | grep -E "(8000|9080|3001|3002)" || echo "No ports listening"
|
||||
|
||||
echo ""
|
||||
echo "📁 Nginx status:"
|
||||
incus exec aitbc -- systemctl status nginx --no-pager -l | head -20
|
||||
|
||||
echo ""
|
||||
echo "🔍 Nginx config test:"
|
||||
incus exec aitbc -- nginx -t
|
||||
|
||||
echo ""
|
||||
echo "📝 Nginx sites enabled:"
|
||||
incus exec aitbc -- ls -la /etc/nginx/sites-enabled/
|
||||
|
||||
echo ""
|
||||
echo "🚀 Starting services if needed..."
|
||||
|
||||
# Start the services
|
||||
incus exec aitbc -- bash -c "
|
||||
cd /home/oib/aitbc
|
||||
pkill -f uvicorn 2>/dev/null || true
|
||||
pkill -f server.py 2>/dev/null || true
|
||||
|
||||
# Start blockchain node
|
||||
cd apps/blockchain-node
|
||||
source ../../.venv/bin/activate
|
||||
python -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 9080 &
|
||||
|
||||
# Start coordinator API
|
||||
cd ../coordinator-api
|
||||
source ../../.venv/bin/activate
|
||||
python -m uvicorn src.app.main:app --host 0.0.0.0 --port 8000 &
|
||||
|
||||
# Start marketplace UI
|
||||
cd ../marketplace-ui
|
||||
python server.py --port 3001 &
|
||||
|
||||
# Start trade exchange
|
||||
cd ../trade-exchange
|
||||
python server.py --port 3002 &
|
||||
|
||||
sleep 3
|
||||
echo 'Services started!'
|
||||
"
|
||||
|
||||
echo ""
|
||||
echo "✅ Done! Check services:"
|
||||
echo "incus exec aitbc -- ps aux | grep uvicorn"
|
||||
@@ -1,65 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Diagnose AITBC services
|
||||
|
||||
echo "🔍 Diagnosing AITBC Services"
|
||||
echo "=========================="
|
||||
echo ""
|
||||
|
||||
# Check local services
|
||||
echo "📋 Local Services:"
|
||||
echo "Port 8000 (Coordinator API):"
|
||||
lsof -i :8000 2>/dev/null || echo " ❌ Not running"
|
||||
|
||||
echo "Port 9080 (Blockchain Node):"
|
||||
lsof -i :9080 2>/dev/null || echo " ❌ Not running"
|
||||
|
||||
echo "Port 3001 (Marketplace UI):"
|
||||
lsof -i :3001 2>/dev/null || echo " ❌ Not running"
|
||||
|
||||
echo "Port 3002 (Trade Exchange):"
|
||||
lsof -i :3002 2>/dev/null || echo " ❌ Not running"
|
||||
|
||||
echo ""
|
||||
echo "🌐 Testing Endpoints:"
|
||||
|
||||
# Test local endpoints
|
||||
echo "Local API Health:"
|
||||
curl -s http://127.0.0.1:8000/v1/health 2>/dev/null && echo " ✅ OK" || echo " ❌ Failed"
|
||||
|
||||
echo "Local Blockchain:"
|
||||
curl -s http://127.0.0.1:9080/rpc/head 2>/dev/null | head -c 50 && echo "..." || echo " ❌ Failed"
|
||||
|
||||
echo "Local Admin:"
|
||||
curl -s http://127.0.0.1:8000/v1/admin/stats 2>/dev/null | head -c 50 && echo "..." || echo " ❌ Failed"
|
||||
|
||||
echo ""
|
||||
echo "🌐 Remote Endpoints (via domain):"
|
||||
echo "Domain API Health:"
|
||||
curl -s https://aitbc.bubuit.net/health 2>/dev/null && echo " ✅ OK" || echo " ❌ Failed"
|
||||
|
||||
echo "Domain Admin:"
|
||||
curl -s https://aitbc.bubuit.net/admin/stats 2>/dev/null | head -c 50 && echo "..." || echo " ❌ Failed"
|
||||
|
||||
echo ""
|
||||
echo "🔧 Fixing common issues..."
|
||||
|
||||
# Stop any conflicting services
|
||||
echo "Stopping local services..."
|
||||
sudo fuser -k 8000/tcp 2>/dev/null || true
|
||||
sudo fuser -k 9080/tcp 2>/dev/null || true
|
||||
sudo fuser -k 3001/tcp 2>/dev/null || true
|
||||
sudo fuser -k 3002/tcp 2>/dev/null || true
|
||||
|
||||
echo ""
|
||||
echo "📝 Instructions:"
|
||||
echo "1. Make sure you're in the incus group: sudo usermod -aG incus \$USER"
|
||||
echo "2. Log out and log back in"
|
||||
echo "3. Run: incus exec aitbc -- bash"
|
||||
echo "4. Inside container, run: /home/oib/start_aitbc.sh"
|
||||
echo "5. Check services: ps aux | grep uvicorn"
|
||||
echo ""
|
||||
echo "If services are running in container but not accessible:"
|
||||
echo "1. Check port forwarding to 10.1.223.93"
|
||||
echo "2. Check nginx config in container"
|
||||
echo "3. Check firewall rules"
|
||||
@@ -1,58 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Quick fix to start AITBC services in container
|
||||
|
||||
echo "🔧 Starting AITBC Services in Container"
|
||||
echo "====================================="
|
||||
|
||||
# First, let's manually start the services
|
||||
echo "1. Starting Coordinator API..."
|
||||
cd /home/oib/windsurf/aitbc/apps/coordinator-api
|
||||
source ../../.venv/bin/activate 2>/dev/null || source .venv/bin/activate
|
||||
python -m uvicorn src.app.main:app --host 0.0.0.0 --port 8000 &
|
||||
COORD_PID=$!
|
||||
|
||||
echo "2. Starting Blockchain Node..."
|
||||
cd ../blockchain-node
|
||||
python -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 9080 &
|
||||
NODE_PID=$!
|
||||
|
||||
echo "3. Starting Marketplace UI..."
|
||||
cd ../marketplace-ui
|
||||
python server.py --port 3001 &
|
||||
MARKET_PID=$!
|
||||
|
||||
echo "4. Starting Trade Exchange..."
|
||||
cd ../trade-exchange
|
||||
python server.py --port 3002 &
|
||||
EXCHANGE_PID=$!
|
||||
|
||||
echo ""
|
||||
echo "✅ Services started!"
|
||||
echo "Coordinator API: http://127.0.0.1:8000"
|
||||
echo "Blockchain: http://127.0.0.1:9080"
|
||||
echo "Marketplace: http://127.0.0.1:3001"
|
||||
echo "Exchange: http://127.0.0.1:3002"
|
||||
echo ""
|
||||
echo "PIDs:"
|
||||
echo "Coordinator: $COORD_PID"
|
||||
echo "Blockchain: $NODE_PID"
|
||||
echo "Marketplace: $MARKET_PID"
|
||||
echo "Exchange: $EXCHANGE_PID"
|
||||
echo ""
|
||||
echo "To stop: kill $COORD_PID $NODE_PID $MARKET_PID $EXCHANGE_PID"
|
||||
|
||||
# Wait a bit for services to start
|
||||
sleep 3
|
||||
|
||||
# Test endpoints
|
||||
echo ""
|
||||
echo "🧪 Testing endpoints:"
|
||||
echo "API Health:"
|
||||
curl -s http://127.0.0.1:8000/v1/health | head -c 100
|
||||
|
||||
echo -e "\n\nAdmin Stats:"
|
||||
curl -s http://127.0.0.1:8000/v1/admin/stats -H "X-Api-Key: ${ADMIN_API_KEY}" | head -c 100
|
||||
|
||||
echo -e "\n\nMarketplace Offers:"
|
||||
curl -s http://127.0.0.1:8000/v1/marketplace/offers | head -c 100
|
||||
@@ -1,129 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Run AITBC services locally for domain access
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Starting AITBC Services for Domain Access"
|
||||
echo "=========================================="
|
||||
|
||||
# Kill any existing services
|
||||
echo "Cleaning up existing services..."
|
||||
sudo fuser -k 8000/tcp 2>/dev/null || true
|
||||
sudo fuser -k 9080/tcp 2>/dev/null || true
|
||||
sudo fuser -k 3001/tcp 2>/dev/null || true
|
||||
sudo fuser -k 3002/tcp 2>/dev/null || true
|
||||
pkill -f "uvicorn.*aitbc" 2>/dev/null || true
|
||||
pkill -f "server.py" 2>/dev/null || true
|
||||
|
||||
# Wait for ports to be free
|
||||
sleep 2
|
||||
|
||||
# Create logs directory
|
||||
mkdir -p logs
|
||||
|
||||
echo ""
|
||||
echo "📦 Starting Services..."
|
||||
|
||||
# Start Coordinator API
|
||||
echo "1. Starting Coordinator API (port 8000)..."
|
||||
cd apps/coordinator-api
|
||||
source ../.venv/bin/activate 2>/dev/null || python -m venv ../.venv && source ../.venv/bin/activate
|
||||
pip install -q -e . 2>/dev/null || true
|
||||
nohup python -m uvicorn src.app.main:app --host 0.0.0.0 --port 8000 > ../../logs/api.log 2>&1 &
|
||||
API_PID=$!
|
||||
echo " PID: $API_PID"
|
||||
|
||||
# Start Blockchain Node
|
||||
echo "2. Starting Blockchain Node (port 9080)..."
|
||||
cd ../blockchain-node
|
||||
nohup python -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 9080 > ../../logs/blockchain.log 2>&1 &
|
||||
NODE_PID=$!
|
||||
echo " PID: $NODE_PID"
|
||||
|
||||
# Start Marketplace UI
|
||||
echo "3. Starting Marketplace UI (port 3001)..."
|
||||
cd ../marketplace-ui
|
||||
nohup python server.py --port 3001 > ../../logs/marketplace.log 2>&1 &
|
||||
MARKET_PID=$!
|
||||
echo " PID: $MARKET_PID"
|
||||
|
||||
# Start Trade Exchange
|
||||
echo "4. Starting Trade Exchange (port 3002)..."
|
||||
cd ../trade-exchange
|
||||
nohup python server.py --port 3002 > ../../logs/exchange.log 2>&1 &
|
||||
EXCHANGE_PID=$!
|
||||
echo " PID: $EXCHANGE_PID"
|
||||
|
||||
# Save PIDs for cleanup
|
||||
echo "$API_PID $NODE_PID $MARKET_PID $EXCHANGE_PID" > ../.service_pids
|
||||
|
||||
cd ..
|
||||
|
||||
# Wait for services to start
|
||||
echo ""
|
||||
echo "⏳ Waiting for services to initialize..."
|
||||
sleep 5
|
||||
|
||||
# Test services
|
||||
echo ""
|
||||
echo "🧪 Testing Services..."
|
||||
|
||||
echo -n "API Health: "
|
||||
if curl -s http://127.0.0.1:8000/v1/health > /dev/null; then
|
||||
echo "✅ OK"
|
||||
else
|
||||
echo "❌ Failed"
|
||||
fi
|
||||
|
||||
echo -n "Admin API: "
|
||||
if curl -s http://127.0.0.1:8000/v1/admin/stats -H "X-Api-Key: ${ADMIN_API_KEY}" > /dev/null; then
|
||||
echo "✅ OK"
|
||||
else
|
||||
echo "❌ Failed"
|
||||
fi
|
||||
|
||||
echo -n "Blockchain: "
|
||||
if curl -s http://127.0.0.1:9080/rpc/head > /dev/null; then
|
||||
echo "✅ OK"
|
||||
else
|
||||
echo "❌ Failed"
|
||||
fi
|
||||
|
||||
echo -n "Marketplace: "
|
||||
if curl -s http://127.0.0.1:3001 > /dev/null; then
|
||||
echo "✅ OK"
|
||||
else
|
||||
echo "❌ Failed"
|
||||
fi
|
||||
|
||||
echo -n "Exchange: "
|
||||
if curl -s http://127.0.0.1:3002 > /dev/null; then
|
||||
echo "✅ OK"
|
||||
else
|
||||
echo "❌ Failed"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ All services started!"
|
||||
echo ""
|
||||
echo "📋 Local URLs:"
|
||||
echo " API: http://127.0.0.1:8000/v1"
|
||||
echo " RPC: http://127.0.0.1:9080/rpc"
|
||||
echo " Marketplace: http://127.0.0.1:3001"
|
||||
echo " Exchange: http://127.0.0.1:3002"
|
||||
echo ""
|
||||
echo "🌐 Domain URLs (if nginx is configured):"
|
||||
echo " API: https://aitbc.bubuit.net/api"
|
||||
echo " Admin: https://aitbc.bubuit.net/admin"
|
||||
echo " RPC: https://aitbc.bubuit.net/rpc"
|
||||
echo " Marketplace: https://aitbc.bubuit.net/Marketplace"
|
||||
echo " Exchange: https://aitbc.bubuit.net/Exchange"
|
||||
echo ""
|
||||
echo "📝 Logs: ./logs/"
|
||||
echo "🛑 Stop services: ./stop-services.sh"
|
||||
echo ""
|
||||
echo "Press Ctrl+C to stop monitoring (services will keep running)"
|
||||
|
||||
# Monitor logs
|
||||
tail -f logs/*.log
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Download production assets locally
|
||||
echo "Setting up production assets..."
|
||||
|
||||
# Create assets directory
|
||||
mkdir -p /home/oib/windsurf/aitbc/assets/{css,js,icons}
|
||||
|
||||
# Download Tailwind CSS (production build)
|
||||
echo "Downloading Tailwind CSS..."
|
||||
curl -L https://unpkg.com/tailwindcss@3.4.0/lib/tailwind.js -o /home/oib/windsurf/aitbc/assets/js/tailwind.js
|
||||
|
||||
# Download Axios
|
||||
echo "Downloading Axios..."
|
||||
curl -L https://unpkg.com/axios@1.6.2/dist/axios.min.js -o /home/oib/windsurf/aitbc/assets/js/axios.min.js
|
||||
|
||||
# Download Lucide icons
|
||||
echo "Downloading Lucide..."
|
||||
curl -L https://unpkg.com/lucide@latest/dist/umd/lucide.js -o /home/oib/windsurf/aitbc/assets/js/lucide.js
|
||||
|
||||
# Create a custom Tailwind build with only used classes
|
||||
cat > /home/oib/windsurf/aitbc/assets/tailwind.config.js << 'EOF'
|
||||
module.exports = {
|
||||
content: [
|
||||
"./apps/trade-exchange/index.html",
|
||||
"./apps/marketplace-ui/index.html"
|
||||
],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "Assets downloaded to /home/oib/windsurf/aitbc/assets/"
|
||||
echo "Update your HTML files to use local paths:"
|
||||
echo " - /assets/js/tailwind.js"
|
||||
echo " - /assets/js/axios.min.js"
|
||||
echo " - /assets/js/lucide.js"
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "=== Starting AITBC Miner Dashboard ==="
|
||||
echo ""
|
||||
|
||||
# Find available port
|
||||
PORT=8080
|
||||
while [ $PORT -le 8090 ]; do
|
||||
if ! netstat -tuln 2>/dev/null | grep -q ":$PORT "; then
|
||||
echo "✓ Found available port: $PORT"
|
||||
break
|
||||
fi
|
||||
echo "Port $port is in use, trying next..."
|
||||
PORT=$((PORT + 1))
|
||||
done
|
||||
|
||||
if [ $PORT -gt 8090 ]; then
|
||||
echo "❌ No available ports found between 8080-8090"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start the dashboard
|
||||
echo "Starting dashboard on port $PORT..."
|
||||
nohup python3 -m http.server $PORT --bind 0.0.0.0 > dashboard.log 2>&1 &
|
||||
PID=$!
|
||||
|
||||
echo ""
|
||||
echo "✅ Dashboard is running!"
|
||||
echo ""
|
||||
echo "Access URLs:"
|
||||
echo " Local: http://localhost:$PORT"
|
||||
echo " Network: http://$(hostname -I | awk '{print $1}'):$PORT"
|
||||
echo ""
|
||||
echo "Dashboard file: miner-dashboard.html"
|
||||
echo "Process ID: $PID"
|
||||
echo "Log file: dashboard.log"
|
||||
echo ""
|
||||
echo "To stop: kill $PID"
|
||||
echo "To view logs: tail -f dashboard.log"
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Stop all AITBC services
|
||||
|
||||
echo "🛑 Stopping AITBC Services"
|
||||
echo "========================"
|
||||
|
||||
# Stop by PID if file exists
|
||||
if [ -f .service_pids ]; then
|
||||
PIDS=$(cat .service_pids)
|
||||
echo "Found PIDs: $PIDS"
|
||||
for PID in $PIDS; do
|
||||
if kill -0 $PID 2>/dev/null; then
|
||||
echo "Stopping PID $PID..."
|
||||
kill $PID
|
||||
fi
|
||||
done
|
||||
rm -f .service_pids
|
||||
fi
|
||||
|
||||
# Force kill any remaining services
|
||||
echo "Cleaning up any remaining processes..."
|
||||
sudo fuser -k 8000/tcp 2>/dev/null || true
|
||||
sudo fuser -k 9080/tcp 2>/dev/null || true
|
||||
sudo fuser -k 3001/tcp 2>/dev/null || true
|
||||
sudo fuser -k 3002/tcp 2>/dev/null || true
|
||||
pkill -f "uvicorn.*aitbc" 2>/dev/null || true
|
||||
pkill -f "server.py" 2>/dev/null || true
|
||||
|
||||
echo "✅ All services stopped!"
|
||||
Reference in New Issue
Block a user