Prepare for v2 development: Add MCP integration and future development planning

- Add FUTURE_DEVELOPMENT.md with comprehensive v2 protocol specification
- Add MCP integration design and implementation foundation
- Add infrastructure and deployment configurations
- Update system architecture for v2 evolution

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
anthonyrawlins
2025-08-07 14:38:22 +10:00
parent 5f94288fbb
commit 065dddf8d5
41 changed files with 14970 additions and 161 deletions

View File

@@ -0,0 +1,514 @@
#!/bin/bash
set -euo pipefail
# BZZZ v1 to v2 Migration Script
# This script handles the complete migration from BZZZ v1 (SystemD) to v2 (Docker Swarm)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_FILE="/var/log/bzzz-migration-$(date +%Y%m%d-%H%M%S).log"
BACKUP_DIR="/rust/bzzz-v2/backup/$(date +%Y%m%d-%H%M%S)"
DRY_RUN=${DRY_RUN:-false}
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
log() {
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE"
}
error() {
echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"
exit 1
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1" | tee -a "$LOG_FILE"
}
success() {
echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE"
}
check_prerequisites() {
log "Checking prerequisites..."
# Check if running as root for some operations
if [[ $EUID -eq 0 ]]; then
error "This script should not be run as root. Run as tony user with sudo access."
fi
# Check required commands
local commands=("docker" "systemctl" "pg_dump" "rsync" "curl")
for cmd in "${commands[@]}"; do
if ! command -v "$cmd" &> /dev/null; then
error "Required command '$cmd' not found"
fi
done
# Check Docker Swarm status
if ! docker info | grep -q "Swarm: active"; then
error "Docker Swarm is not active. Please initialize swarm first."
fi
# Check available disk space
local available=$(df /rust | awk 'NR==2 {print $4}')
local required=10485760 # 10GB in KB
if [[ $available -lt $required ]]; then
error "Insufficient disk space. Need at least 10GB available in /rust"
fi
success "Prerequisites check passed"
}
backup_v1_data() {
log "Creating backup of v1 data..."
if [[ "$DRY_RUN" == "true" ]]; then
log "[DRY RUN] Would create backup at: $BACKUP_DIR"
return 0
fi
mkdir -p "$BACKUP_DIR"
# Backup v1 configuration
if [[ -d "/home/tony/chorus/project-queues/active/BZZZ" ]]; then
rsync -av "/home/tony/chorus/project-queues/active/BZZZ/" "$BACKUP_DIR/v1-source/"
fi
# Backup systemd service files
sudo cp /etc/systemd/system/bzzz.service "$BACKUP_DIR/" 2>/dev/null || true
# Backup hypercore logs (if any)
if [[ -d "/home/tony/.config/bzzz" ]]; then
rsync -av "/home/tony/.config/bzzz/" "$BACKUP_DIR/config/"
fi
# Backup any existing data directories
for node in walnut ironwood acacia; do
if [[ -d "/rust/bzzz/$node" ]]; then
rsync -av "/rust/bzzz/$node/" "$BACKUP_DIR/data/$node/"
fi
done
success "Backup completed at: $BACKUP_DIR"
}
stop_v1_services() {
log "Stopping BZZZ v1 services..."
if [[ "$DRY_RUN" == "true" ]]; then
log "[DRY RUN] Would stop v1 systemd services"
return 0
fi
local nodes=("walnut" "ironwood" "acacia")
for node in "${nodes[@]}"; do
if sudo systemctl is-active --quiet "bzzz@$node" 2>/dev/null || sudo systemctl is-active --quiet bzzz 2>/dev/null; then
log "Stopping BZZZ service on $node..."
sudo systemctl stop "bzzz@$node" 2>/dev/null || sudo systemctl stop bzzz 2>/dev/null || true
sudo systemctl disable "bzzz@$node" 2>/dev/null || sudo systemctl disable bzzz 2>/dev/null || true
fi
done
# Wait for services to fully stop
sleep 10
success "v1 services stopped"
}
setup_v2_infrastructure() {
log "Setting up v2 infrastructure..."
if [[ "$DRY_RUN" == "true" ]]; then
log "[DRY RUN] Would create v2 directory structure"
return 0
fi
# Create directory structure
mkdir -p /rust/bzzz-v2/{config,data,logs}
mkdir -p /rust/bzzz-v2/data/{blobs,conversations,dht,postgres,redis}
mkdir -p /rust/bzzz-v2/data/blobs/{data,index,temp}
mkdir -p /rust/bzzz-v2/data/dht/{walnut,ironwood,acacia}
mkdir -p /rust/bzzz-v2/config/{swarm,systemd,secrets}
mkdir -p /rust/bzzz-v2/logs/{application,p2p,monitoring}
# Set permissions
sudo chown -R tony:tony /rust/bzzz-v2
chmod -R 755 /rust/bzzz-v2
# Create placeholder configuration files
cat > /rust/bzzz-v2/config/bzzz-config.yaml << 'EOF'
agent:
id: ""
specialization: "advanced_reasoning"
capabilities: ["code_generation", "debugging", "analysis"]
models: ["llama3.2:70b", "qwen2.5:72b"]
max_tasks: 3
hive_api:
base_url: "http://hive.deepblack.cloud"
api_key: ""
dht:
bootstrap_nodes:
- "walnut:9101"
- "ironwood:9102"
- "acacia:9103"
content_store:
path: "/app/data/blobs"
replication_factor: 3
shard_depth: 2
openai:
rate_limit_rpm: 1000
rate_limit_tpm: 100000
cost_tracking: true
EOF
success "v2 infrastructure setup completed"
}
migrate_conversation_data() {
log "Migrating conversation data..."
if [[ "$DRY_RUN" == "true" ]]; then
log "[DRY RUN] Would migrate hypercore logs to content-addressed storage"
return 0
fi
# Check if there are any hypercore logs to migrate
local log_files=()
for node in walnut ironwood acacia; do
if [[ -f "/home/tony/.config/bzzz/hypercore-$node.log" ]]; then
log_files+=("/home/tony/.config/bzzz/hypercore-$node.log")
fi
done
if [[ ${#log_files[@]} -eq 0 ]]; then
warn "No hypercore logs found for migration"
return 0
fi
# Process each log file and create content-addressed blobs
local migration_script="$SCRIPT_DIR/convert-hypercore-to-cas.py"
if [[ -f "$migration_script" ]]; then
python3 "$migration_script" "${log_files[@]}" --output-dir "/rust/bzzz-v2/data/blobs/data"
success "Conversation data migrated to content-addressed storage"
else
warn "Migration script not found, skipping conversation data migration"
fi
}
setup_docker_secrets() {
log "Setting up Docker secrets..."
if [[ "$DRY_RUN" == "true" ]]; then
log "[DRY RUN] Would create Docker secrets"
return 0
fi
# Create PostgreSQL password secret
if [[ -f "/home/tony/chorus/business/secrets/postgres-bzzz-password" ]]; then
docker secret create bzzz_postgres_password /home/tony/chorus/business/secrets/postgres-bzzz-password 2>/dev/null || true
else
# Generate random password
openssl rand -base64 32 | docker secret create bzzz_postgres_password - 2>/dev/null || true
fi
# Create OpenAI API key secret
if [[ -f "/home/tony/chorus/business/secrets/openai-api-key" ]]; then
docker secret create bzzz_openai_api_key /home/tony/chorus/business/secrets/openai-api-key 2>/dev/null || true
else
warn "OpenAI API key not found in secrets directory"
fi
success "Docker secrets configured"
}
setup_docker_configs() {
log "Setting up Docker configs..."
if [[ "$DRY_RUN" == "true" ]]; then
log "[DRY RUN] Would create Docker configs"
return 0
fi
# Create main BZZZ config
docker config create bzzz_v2_config /rust/bzzz-v2/config/bzzz-config.yaml 2>/dev/null || true
# Create MCP server config
cat > /tmp/mcp-config.yaml << 'EOF'
server:
port: 3001
max_connections: 1000
timeout_seconds: 30
tools:
enabled: true
max_execution_time: 300
logging:
level: info
format: json
EOF
docker config create bzzz_mcp_config /tmp/mcp-config.yaml 2>/dev/null || true
rm /tmp/mcp-config.yaml
# Create proxy config
cat > /tmp/proxy-config.yaml << 'EOF'
openai:
rate_limit:
requests_per_minute: 1000
tokens_per_minute: 100000
cost_tracking:
enabled: true
log_requests: true
models:
- "gpt-4"
- "gpt-4-turbo"
- "gpt-3.5-turbo"
server:
port: 3002
timeout: 30s
EOF
docker config create bzzz_proxy_config /tmp/proxy-config.yaml 2>/dev/null || true
rm /tmp/proxy-config.yaml
# Create Redis config
cat > /tmp/redis.conf << 'EOF'
bind 0.0.0.0
port 6379
timeout 0
keepalive 300
maxclients 10000
maxmemory 1gb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
save 60 10000
EOF
docker config create bzzz_redis_config /tmp/redis.conf 2>/dev/null || true
rm /tmp/redis.conf
success "Docker configs created"
}
deploy_v2_stack() {
log "Deploying BZZZ v2 Docker stack..."
if [[ "$DRY_RUN" == "true" ]]; then
log "[DRY RUN] Would deploy Docker stack with: docker stack deploy -c docker-compose.swarm.yml bzzz-v2"
return 0
fi
cd "$SCRIPT_DIR/.."
# Verify compose file
if ! docker-compose -f infrastructure/docker-compose.swarm.yml config > /dev/null; then
error "Docker compose file validation failed"
fi
# Deploy the stack
docker stack deploy -c infrastructure/docker-compose.swarm.yml bzzz-v2
# Wait for services to start
log "Waiting for services to become ready..."
local max_wait=300 # 5 minutes
local wait_time=0
while [[ $wait_time -lt $max_wait ]]; do
local ready_services=$(docker service ls --filter label=com.docker.stack.namespace=bzzz-v2 --format "table {{.Name}}\t{{.Replicas}}" | grep -v "0/" | wc -l)
local total_services=$(docker service ls --filter label=com.docker.stack.namespace=bzzz-v2 --format "table {{.Name}}" | wc -l)
if [[ $ready_services -eq $total_services ]]; then
success "All services are ready"
break
fi
log "Waiting for services... ($ready_services/$total_services ready)"
sleep 10
wait_time=$((wait_time + 10))
done
if [[ $wait_time -ge $max_wait ]]; then
error "Timeout waiting for services to become ready"
fi
}
verify_v2_deployment() {
log "Verifying v2 deployment..."
# Check service health
local services=("bzzz-v2_bzzz-agent" "bzzz-v2_postgres" "bzzz-v2_redis" "bzzz-v2_mcp-server")
for service in "${services[@]}"; do
if ! docker service ps "$service" | grep -q "Running"; then
error "Service $service is not running properly"
fi
done
# Test DHT connectivity
log "Testing DHT connectivity..."
if ! timeout 30 docker exec "$(docker ps -q -f label=com.docker.swarm.service.name=bzzz-v2_dht-bootstrap-walnut)" \
curl -f http://localhost:9101/health > /dev/null 2>&1; then
warn "DHT bootstrap node (walnut) health check failed"
fi
# Test MCP server
log "Testing MCP server..."
if ! timeout 10 curl -f http://localhost:3001/health > /dev/null 2>&1; then
warn "MCP server health check failed"
fi
# Test content resolver
log "Testing content resolver..."
if ! timeout 10 curl -f http://localhost:3003/health > /dev/null 2>&1; then
warn "Content resolver health check failed"
fi
success "v2 deployment verification completed"
}
update_node_labels() {
log "Updating Docker node labels for service placement..."
if [[ "$DRY_RUN" == "true" ]]; then
log "[DRY RUN] Would update node labels"
return 0
fi
# Set node labels for service placement
docker node update --label-add bzzz.role=agent walnut 2>/dev/null || true
docker node update --label-add bzzz.role=agent ironwood 2>/dev/null || true
docker node update --label-add bzzz.role=agent acacia 2>/dev/null || true
success "Node labels updated"
}
cleanup_v1_artifacts() {
log "Cleaning up v1 artifacts..."
if [[ "$DRY_RUN" == "true" ]]; then
log "[DRY RUN] Would clean up v1 systemd files and binaries"
return 0
fi
# Remove systemd service files (but keep backup)
sudo rm -f /etc/systemd/system/bzzz.service
sudo rm -f /etc/systemd/system/bzzz@.service
sudo systemctl daemon-reload
# Move v1 binaries to backup location
if [[ -f "/home/tony/chorus/project-queues/active/BZZZ/bzzz" ]]; then
mv "/home/tony/chorus/project-queues/active/BZZZ/bzzz" "$BACKUP_DIR/bzzz-v1-binary"
fi
success "v1 cleanup completed"
}
print_migration_summary() {
log "Migration Summary:"
log "=================="
log "✅ v1 services stopped and disabled"
log "✅ v2 infrastructure deployed to Docker Swarm"
log "✅ Data migrated to content-addressed storage"
log "✅ DHT network established across 3 nodes"
log "✅ MCP server and OpenAI proxy deployed"
log "✅ Monitoring and health checks configured"
log ""
log "Access Points:"
log "- BZZZ Agent API: https://bzzz.deepblack.cloud"
log "- MCP Server: https://mcp.deepblack.cloud"
log "- Content Resolver: https://resolve.deepblack.cloud"
log "- OpenAI Proxy: https://openai.deepblack.cloud"
log ""
log "Monitoring:"
log "- docker service ls --filter label=com.docker.stack.namespace=bzzz-v2"
log "- docker stack ps bzzz-v2"
log "- docker service logs bzzz-v2_bzzz-agent"
log ""
log "Backup Location: $BACKUP_DIR"
log "Migration Log: $LOG_FILE"
}
rollback_to_v1() {
log "Rolling back to v1..."
# Stop v2 services
docker stack rm bzzz-v2 2>/dev/null || true
sleep 30
# Restore v1 systemd service
if [[ -f "$BACKUP_DIR/bzzz.service" ]]; then
sudo cp "$BACKUP_DIR/bzzz.service" /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable bzzz
sudo systemctl start bzzz
fi
# Restore v1 binary
if [[ -f "$BACKUP_DIR/bzzz-v1-binary" ]]; then
cp "$BACKUP_DIR/bzzz-v1-binary" "/home/tony/chorus/project-queues/active/BZZZ/bzzz"
chmod +x "/home/tony/chorus/project-queues/active/BZZZ/bzzz"
fi
success "Rollback to v1 completed"
}
main() {
log "Starting BZZZ v1 to v2 migration..."
log "DRY_RUN mode: $DRY_RUN"
# Handle rollback if requested
if [[ "${1:-}" == "--rollback" ]]; then
rollback_to_v1
return 0
fi
# Trap to handle errors
trap 'error "Migration failed at line $LINENO"' ERR
check_prerequisites
backup_v1_data
stop_v1_services
setup_v2_infrastructure
migrate_conversation_data
setup_docker_secrets
setup_docker_configs
update_node_labels
deploy_v2_stack
verify_v2_deployment
cleanup_v1_artifacts
print_migration_summary
success "BZZZ v2 migration completed successfully!"
log "Run with --rollback to revert to v1 if needed"
}
# Handle script arguments
case "${1:-}" in
--dry-run)
DRY_RUN=true
main
;;
--rollback)
main --rollback
;;
--help|-h)
echo "Usage: $0 [--dry-run|--rollback|--help]"
echo ""
echo "Options:"
echo " --dry-run Preview migration steps without making changes"
echo " --rollback Rollback to v1 (emergency use only)"
echo " --help Show this help message"
exit 0
;;
*)
main
;;
esac