Some checks failed
Coverage Phase 1 (70% Target) / test-coverage-70 (push) Has been cancelled
Coverage Phase 2 (85% Target) / test-coverage-85 (push) Has been cancelled
Cross-Node Transaction Testing / transaction-test (push) Has been cancelled
Deploy to Testnet / deploy-testnet (push) Has been cancelled
Integration Tests / test-service-integration (push) Has been cancelled
Multi-Node Stress Testing / stress-test (push) Has been cancelled
Python Tests / test-python (push) Has been cancelled
Security Scanning / security-scan (push) Has been cancelled
Documentation Validation / validate-docs (push) Has been cancelled
Documentation Validation / validate-policies-strict (push) Has been cancelled
CLI Tests / test-cli (push) Has been cancelled
Package Tests / Python package - aitbc-agent-sdk (push) Has been cancelled
Package Tests / Python package - aitbc-core (push) Has been cancelled
Package Tests / Python package - aitbc-crypto (push) Has been cancelled
Package Tests / Python package - aitbc-sdk (push) Has been cancelled
Package Tests / JavaScript package - aitbc-sdk-js (push) Has been cancelled
Package Tests / JavaScript package - aitbc-token (push) Has been cancelled
Smart Contract Tests / test-solidity (map[name:aitbc-contracts path:contracts]) (push) Has been cancelled
Smart Contract Tests / test-solidity (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Has been cancelled
Smart Contract Tests / test-foundry (push) Has been cancelled
Smart Contract Tests / lint-solidity (push) Has been cancelled
Smart Contract Tests / deploy-contracts (push) Has been cancelled
- Updated CI workflows to track poetry.lock instead of requirements.txt - Removed check-requirements-sync.py step from python-tests.yml - Updated dependency_scanner.py default from requirements.txt to pyproject.toml - Replaced all print() with click.echo() in deploy_edge_node.py (CLI script) - Replaced print() with logger.warning() in zk_cache.py - Updated setup.py files to read dependencies from pyproject.toml via tomli - Removed
434 lines
13 KiB
Bash
Executable File
434 lines
13 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# AITBC Systemd Deployment Script
|
|
# One-command setup for AITBC services using systemd
|
|
# This script handles automated deployment of AITBC services on Linux servers
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
source "$SCRIPT_DIR/../utils/deploy_common.sh"
|
|
|
|
# Configuration
|
|
REPO_ROOT="${REPO_ROOT:-/opt/aitbc}"
|
|
VENV_DIR="$REPO_ROOT/venv"
|
|
PYTHON_VERSION="3.13"
|
|
BACKUP_DIR="$REPO_ROOT/.backup"
|
|
|
|
# Check prerequisites
|
|
check_prerequisites() {
|
|
log "Checking system prerequisites..."
|
|
|
|
check_root
|
|
|
|
# Check Linux distribution
|
|
if [[ ! -f /etc/os-release ]]; then
|
|
error "Cannot detect Linux distribution"
|
|
fi
|
|
source /etc/os-release
|
|
log "Detected OS: $PRETTY_NAME"
|
|
|
|
# Check Python version
|
|
require_command python3
|
|
|
|
PYTHON_VER=$(python3 --version | awk '{print $2}')
|
|
log "Python version: $PYTHON_VER"
|
|
require_min_version "$PYTHON_VER" "$PYTHON_VERSION" "Python"
|
|
|
|
# Check systemd
|
|
require_command systemctl
|
|
|
|
# Check required system tools
|
|
require_commands git curl jq
|
|
|
|
success "Prerequisites check passed"
|
|
}
|
|
|
|
# Install system dependencies
|
|
install_dependencies() {
|
|
log "Installing system dependencies..."
|
|
|
|
if [[ "$ID" == "ubuntu" ]] || [[ "$ID" == "debian" ]]; then
|
|
apt-get update
|
|
apt-get install -y \
|
|
python3-venv \
|
|
python3-dev \
|
|
build-essential \
|
|
libssl-dev \
|
|
libffi-dev \
|
|
postgresql \
|
|
postgresql-contrib \
|
|
redis-server \
|
|
nginx \
|
|
jq \
|
|
curl \
|
|
git
|
|
elif [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "fedora" ]]; then
|
|
dnf install -y \
|
|
python3-venv \
|
|
python3-devel \
|
|
gcc \
|
|
openssl-devel \
|
|
libffi-devel \
|
|
postgresql-server \
|
|
postgresql-contrib \
|
|
redis \
|
|
nginx \
|
|
jq \
|
|
curl \
|
|
git
|
|
else
|
|
warning "Unsupported distribution. Please install dependencies manually"
|
|
return 0
|
|
fi
|
|
|
|
success "System dependencies installed"
|
|
}
|
|
|
|
# Setup repository
|
|
setup_repository() {
|
|
log "Setting up repository..."
|
|
|
|
# Create backup of existing deployment
|
|
if [[ -d "$REPO_ROOT" ]]; then
|
|
log "Creating backup of existing deployment..."
|
|
BACKUP_TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
BACKUP_PATH="$BACKUP_DIR/backup_$BACKUP_TIMESTAMP"
|
|
mkdir -p "$BACKUP_DIR"
|
|
cp -r "$REPO_ROOT" "$BACKUP_PATH" || warning "Backup failed, continuing anyway"
|
|
log "Backup created at: $BACKUP_PATH"
|
|
fi
|
|
|
|
# Clone or update repository
|
|
if [[ -d "$REPO_ROOT/.git" ]]; then
|
|
log "Updating existing repository..."
|
|
cd "$REPO_ROOT"
|
|
git pull || warning "Git pull failed, continuing with existing code"
|
|
else
|
|
log "Cloning repository..."
|
|
# REPO_URL should be set as environment variable
|
|
REPO_URL="${REPO_URL:-https://github.com/your-org/aitbc.git}"
|
|
git clone "$REPO_URL" "$REPO_ROOT"
|
|
fi
|
|
|
|
success "Repository setup completed"
|
|
}
|
|
|
|
# Create virtual environment
|
|
create_venv() {
|
|
log "Creating Python virtual environment..."
|
|
|
|
if [[ -d "$VENV_DIR" ]]; then
|
|
log "Virtual environment already exists, recreating..."
|
|
rm -rf "$VENV_DIR"
|
|
fi
|
|
|
|
python3 -m venv "$VENV_DIR"
|
|
success "Virtual environment created"
|
|
}
|
|
|
|
# Install Python dependencies
|
|
install_python_dependencies() {
|
|
log "Installing Python dependencies..."
|
|
|
|
# Activate virtual environment
|
|
source "$VENV_DIR/bin/activate"
|
|
|
|
# Upgrade pip
|
|
pip install --upgrade pip setuptools wheel
|
|
|
|
# Install using Poetry
|
|
if [[ -f "$REPO_ROOT/pyproject.toml" ]]; then
|
|
pip install poetry
|
|
cd "$REPO_ROOT" && poetry install
|
|
else
|
|
warning "pyproject.toml not found, installing basic dependencies"
|
|
pip install fastapi uvicorn sqlmodel alembic pydantic httpx requests
|
|
fi
|
|
|
|
success "Python dependencies installed"
|
|
}
|
|
|
|
# Configure environment
|
|
configure_environment() {
|
|
log "Configuring environment variables..."
|
|
|
|
# Create /etc/aitbc directory
|
|
mkdir -p /etc/aitbc
|
|
|
|
# Setup node.env if it doesn't exist
|
|
if [[ ! -f /etc/aitbc/node.env ]] && [[ -f "$REPO_ROOT/examples/node.env.example" ]]; then
|
|
cp "$REPO_ROOT/examples/node.env.example" /etc/aitbc/node.env
|
|
warning "Created /etc/aitbc/node.env from template. Please edit with node-specific values"
|
|
fi
|
|
|
|
# Generate unique node IDs if not set
|
|
if [[ -f /etc/aitbc/node.env ]]; then
|
|
if grep -q "node-<unique-uuid-here>" /etc/aitbc/node.env; then
|
|
log "Generating unique node IDs..."
|
|
UUID=$(uuidgen | tr -d '-')
|
|
sed -i "s/node-<unique-uuid-here>/node-$UUID/g" /etc/aitbc/node.env
|
|
sed -i "s/ait1<unique-uuid-here>/ait1$UUID/g" /etc/aitbc/node.env
|
|
log "Generated node IDs with UUID: $UUID"
|
|
fi
|
|
fi
|
|
|
|
# Setup blockchain.env if it doesn't exist
|
|
if [[ ! -f /etc/aitbc/blockchain.env ]]; then
|
|
if [[ -f "$REPO_ROOT/examples/env.example" ]]; then
|
|
# Extract relevant blockchain configuration from examples/env.example
|
|
grep -E "^(chain_id|CHAIN_ID|rpc_bind_host|rpc_bind_port|p2p_bind_host|p2p_bind_port|enable_block_production|block_time_seconds|proposer_id)" "$REPO_ROOT/examples/env.example" > /etc/aitbc/blockchain.env || true
|
|
fi
|
|
|
|
# Add defaults if file is empty
|
|
if [[ ! -s /etc/aitbc/blockchain.env ]]; then
|
|
cat > /etc/aitbc/blockchain.env << EOF
|
|
# Blockchain Configuration
|
|
chain_id=ait-testnet
|
|
rpc_bind_host=0.0.0.0
|
|
rpc_bind_port=8006
|
|
p2p_bind_host=0.0.0.0
|
|
p2p_bind_port=7070
|
|
enable_block_production=true
|
|
EOF
|
|
fi
|
|
fi
|
|
|
|
# Setup secrets directory
|
|
mkdir -p /run/aitbc/secrets
|
|
touch /run/aitbc/secrets/.env
|
|
|
|
success "Environment configuration completed"
|
|
}
|
|
|
|
# Initialize databases
|
|
initialize_databases() {
|
|
log "Initializing databases..."
|
|
|
|
# Start PostgreSQL if not running
|
|
if systemctl is-active --quiet postgresql || systemctl is-active --quiet postgresql@13-main; then
|
|
log "PostgreSQL is already running"
|
|
else
|
|
log "Starting PostgreSQL..."
|
|
systemctl start postgresql || systemctl start postgresql@13-main || warning "Failed to start PostgreSQL"
|
|
fi
|
|
|
|
# Create databases if they don't exist
|
|
if command -v psql &> /dev/null; then
|
|
for db in aitbc aitbc_coordinator aitbc_marketplace; do
|
|
if ! sudo -u postgres psql -lqt | cut -d \| -f 1 | grep -qw $db; then
|
|
log "Creating database: $db"
|
|
sudo -u postgres createdb $db || warning "Failed to create database $db"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Start Redis if not running
|
|
if systemctl is-active --quiet redis-server || systemctl is-active --quiet redis; then
|
|
log "Redis is already running"
|
|
else
|
|
log "Starting Redis..."
|
|
systemctl start redis-server || systemctl start redis || warning "Failed to start Redis"
|
|
fi
|
|
|
|
success "Database initialization completed"
|
|
}
|
|
|
|
# Setup systemd services
|
|
setup_systemd_services() {
|
|
log "Setting up systemd services..."
|
|
|
|
# Link systemd service files
|
|
if [[ -f "$REPO_ROOT/scripts/utils/link-systemd.sh" ]]; then
|
|
bash "$REPO_ROOT/scripts/utils/link-systemd.sh"
|
|
else
|
|
# Manual linking
|
|
log "Linking systemd service files..."
|
|
mkdir -p /etc/systemd/system
|
|
for service in "$REPO_ROOT/systemd"/*.service; do
|
|
if [[ -f "$service" ]]; then
|
|
ln -sf "$service" "/etc/systemd/system/$(basename $service)"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Reload systemd
|
|
systemctl daemon-reload
|
|
|
|
success "Systemd services setup completed"
|
|
}
|
|
|
|
# Start services in dependency order
|
|
start_services() {
|
|
log "Starting AITBC services..."
|
|
|
|
# Define service startup order
|
|
SERVICES=(
|
|
"postgresql"
|
|
"redis-server"
|
|
"aitbc-blockchain-p2p"
|
|
"aitbc-blockchain-node"
|
|
"aitbc-blockchain-rpc"
|
|
"aitbc-coordinator-api"
|
|
"aitbc-exchange-api"
|
|
"aitbc-wallet"
|
|
"aitbc-agent-daemon"
|
|
"aitbc-agent-coordinator"
|
|
"aitbc-marketplace"
|
|
)
|
|
|
|
for service in "${SERVICES[@]}"; do
|
|
log "Starting $service..."
|
|
if systemctl list-unit-files | grep -q "^$service.service"; then
|
|
systemctl enable "$service" 2>/dev/null || true
|
|
systemctl start "$service" || warning "Failed to start $service"
|
|
sleep 2
|
|
else
|
|
log "$service not found, skipping"
|
|
fi
|
|
done
|
|
|
|
success "Services started"
|
|
}
|
|
|
|
# Run health checks
|
|
run_health_checks() {
|
|
log "Running health checks..."
|
|
|
|
# Wait for services to be ready
|
|
log "Waiting for services to stabilize..."
|
|
sleep 10
|
|
|
|
# Check service status
|
|
FAILED_SERVICES=()
|
|
for service in aitbc-blockchain-node aitbc-blockchain-rpc aitbc-coordinator-api; do
|
|
if systemctl is-active --quiet "$service"; then
|
|
success "$service is running"
|
|
else
|
|
error "$service is not running"
|
|
FAILED_SERVICES+=("$service")
|
|
fi
|
|
done
|
|
|
|
# Check API endpoints if available
|
|
if command -v curl &> /dev/null; then
|
|
log "Checking API endpoints..."
|
|
|
|
# Check blockchain RPC
|
|
if curl -sf http://localhost:8006/health > /dev/null 2>&1; then
|
|
success "Blockchain RPC health check passed"
|
|
else
|
|
warning "Blockchain RPC health check failed"
|
|
fi
|
|
|
|
# Check coordinator API
|
|
if curl -sf http://localhost:8011/health > /dev/null 2>&1; then
|
|
success "Coordinator API health check passed"
|
|
else
|
|
warning "Coordinator API health check failed"
|
|
fi
|
|
fi
|
|
|
|
if [[ ${#FAILED_SERVICES[@]} -gt 0 ]]; then
|
|
error "Some services failed to start: ${FAILED_SERVICES[*]}"
|
|
fi
|
|
|
|
success "Health checks completed"
|
|
}
|
|
|
|
# Rollback deployment
|
|
rollback_deployment() {
|
|
log "Rolling back deployment..."
|
|
|
|
# Find latest backup
|
|
LATEST_BACKUP=$(ls -t "$BACKUP_DIR"/backup_* 2>/dev/null | head -1)
|
|
|
|
if [[ -z "$LATEST_BACKUP" ]]; then
|
|
error "No backup found for rollback"
|
|
fi
|
|
|
|
log "Restoring from: $LATEST_BACKUP"
|
|
|
|
# Stop services
|
|
log "Stopping services..."
|
|
for service in aitbc-*; do
|
|
systemctl stop "$service" 2>/dev/null || true
|
|
done
|
|
|
|
# Restore backup
|
|
rm -rf "$REPO_ROOT"
|
|
cp -r "$LATEST_BACKUP" "$REPO_ROOT"
|
|
|
|
# Restart services
|
|
start_services
|
|
|
|
success "Rollback completed"
|
|
}
|
|
|
|
# Display deployment status
|
|
display_status() {
|
|
log "Deployment Status"
|
|
echo "=================="
|
|
echo "Repository: $REPO_ROOT"
|
|
echo "Virtual Environment: $VENV_DIR"
|
|
echo "Python: $(python3 --version)"
|
|
echo ""
|
|
echo "Service Status:"
|
|
systemctl list-units --type=service --state=running | grep aitbc || echo "No AITBC services running"
|
|
echo ""
|
|
echo "Next Steps:"
|
|
echo "1. Edit /etc/aitbc/blockchain.env with blockchain configuration"
|
|
echo "2. Edit /etc/aitbc/node.env with node-specific values"
|
|
echo "3. Restart services: systemctl restart aitbc-*"
|
|
echo "4. Check logs: journalctl -u aitbc-blockchain-node -f"
|
|
echo "5. Run health checks: $REPO_ROOT/scripts/monitoring/health_check.sh"
|
|
}
|
|
|
|
# Main deployment function
|
|
main() {
|
|
local COMMAND="${1:-deploy}"
|
|
|
|
case "$COMMAND" in
|
|
"deploy")
|
|
log "Starting AITBC deployment..."
|
|
check_prerequisites
|
|
install_dependencies
|
|
setup_repository
|
|
create_venv
|
|
install_python_dependencies
|
|
configure_environment
|
|
initialize_databases
|
|
setup_systemd_services
|
|
start_services
|
|
run_health_checks
|
|
display_status
|
|
success "Deployment completed successfully!"
|
|
;;
|
|
"rollback")
|
|
rollback_deployment
|
|
;;
|
|
"status")
|
|
display_status
|
|
;;
|
|
"health-check")
|
|
run_health_checks
|
|
;;
|
|
*)
|
|
echo "Usage: $0 {deploy|rollback|status|health-check}"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " deploy - Full deployment of AITBC services"
|
|
echo " rollback - Rollback to previous deployment"
|
|
echo " status - Display deployment status"
|
|
echo " health-check - Run health checks on services"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Handle script interruption
|
|
trap 'error "Script interrupted"' INT TERM
|
|
|
|
# Run main function
|
|
main "$@"
|