Update branding assets and deployment configurations
- Enhanced moebius ring logo design in Blender - Updated Docker Compose for website-only deployment with improved config - Enhanced teaser layout with updated branding integration - Added installation and setup documentation - Consolidated planning and reports documentation - Updated gitignore to exclude Next.js build artifacts and archives 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
418
installer/INSTALLER_DOCUMENTATION.md
Normal file
418
installer/INSTALLER_DOCUMENTATION.md
Normal file
@@ -0,0 +1,418 @@
|
||||
# CHORUS Enhanced Installer Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The CHORUS Enhanced Installer (`install-chorus-enhanced.sh`) provides a complete one-command installation solution for the CHORUS distributed AI orchestration platform, addressing the critical gap between binary installation and functional repository configuration.
|
||||
|
||||
## Key Features
|
||||
|
||||
### 🎯 Complete End-to-End Setup
|
||||
- **Binary Installation**: Downloads and installs BZZZ P2P coordination agent
|
||||
- **Repository Integration**: Full GITEA/GitHub configuration with credential management
|
||||
- **Service Management**: SystemD service installation and configuration
|
||||
- **Infrastructure Setup**: Ollama AI models and coordinator components
|
||||
|
||||
### 🔧 Repository Provider Support
|
||||
- **GITEA Integration**: Auto-detection of local GITEA instances
|
||||
- **GitHub Support**: Full GitHub API integration
|
||||
- **Unified Configuration**: Single YAML config for both providers
|
||||
- **Credential Management**: Secure token storage and validation
|
||||
|
||||
### 🚀 Installation Modes
|
||||
- **Worker Node**: Standard agent installation
|
||||
- **Coordinator Node**: Additional components (Docker, Age encryption, WHOOSH)
|
||||
- **Custom Configuration**: Interactive setup with sensible defaults
|
||||
|
||||
## Installation Methods
|
||||
|
||||
### Quick Install (Recommended)
|
||||
```bash
|
||||
curl -fsSL https://chorus.services/install-enhanced.sh | sh
|
||||
```
|
||||
|
||||
### With Options
|
||||
```bash
|
||||
curl -fsSL https://chorus.services/install-enhanced.sh | sh -s -- --coordinator --models "llama3.2,qwen2.5:7b"
|
||||
```
|
||||
|
||||
### Advanced Configuration
|
||||
```bash
|
||||
curl -fsSL https://chorus.services/install-enhanced.sh | sh -s -- --gitea-url "https://git.mycompany.com" --github
|
||||
```
|
||||
|
||||
## Command Line Options
|
||||
|
||||
| Option | Description | Default |
|
||||
|--------|-------------|---------|
|
||||
| `--coordinator` | Install as cluster coordinator | false |
|
||||
| `--models MODEL` | Comma-separated AI models to install | none |
|
||||
| `--skip-deps` | Skip dependency installation | false |
|
||||
| `--quiet` | Minimal output mode | false |
|
||||
| `--github` | Use GitHub instead of GITEA | gitea |
|
||||
| `--gitea-url URL` | Custom GITEA instance URL | http://ironwood:3000 |
|
||||
| `--help` | Show help information | - |
|
||||
|
||||
## Repository Configuration
|
||||
|
||||
### GITEA Setup (Default)
|
||||
```yaml
|
||||
repository:
|
||||
provider: "gitea"
|
||||
config:
|
||||
base_url: "http://ironwood:3000"
|
||||
owner: "tony"
|
||||
repository: "bzzz"
|
||||
task_label: "bzzz-task"
|
||||
in_progress_label: "bzzz-working"
|
||||
completed_label: "bzzz-completed"
|
||||
priority_label: "bzzz-priority"
|
||||
assignee: "tony"
|
||||
base_branch: "main"
|
||||
branch_prefix: "bzzz/task-"
|
||||
token_file: "/home/user/chorus/business/secrets/gitea-token"
|
||||
```
|
||||
|
||||
### GitHub Setup
|
||||
```yaml
|
||||
repository:
|
||||
provider: "github"
|
||||
config:
|
||||
base_url: "https://api.github.com"
|
||||
owner: "username"
|
||||
repository: "project"
|
||||
task_label: "bzzz-task"
|
||||
token_file: "/home/user/chorus/business/secrets/gh-token"
|
||||
```
|
||||
|
||||
## Installation Process
|
||||
|
||||
### Phase 1: System Detection
|
||||
1. **OS Detection**: Linux (apt/yum/pacman) or macOS (brew)
|
||||
2. **Architecture Detection**: amd64, arm64, armv7
|
||||
3. **Dependency Check**: curl, git, jq installation
|
||||
4. **GITEA Discovery**: Auto-detect local instances
|
||||
|
||||
### Phase 2: Credential Setup
|
||||
1. **Token Management**: Secure storage in `~/chorus/business/secrets/`
|
||||
2. **Repository Access**: Interactive token configuration
|
||||
3. **Access Validation**: Test API connectivity
|
||||
4. **Permission Verification**: Ensure required scopes
|
||||
|
||||
### Phase 3: Infrastructure Installation
|
||||
1. **Ollama Setup**: AI model runtime installation
|
||||
2. **Directory Structure**: CHORUS workspace creation
|
||||
3. **Binary Download**: Architecture-specific BZZZ binary
|
||||
4. **Service Files**: SystemD configuration generation
|
||||
|
||||
### Phase 4: BZZZ Configuration
|
||||
1. **Node Configuration**: Interactive hostname, role, ports
|
||||
2. **Repository Integration**: Complete YAML generation
|
||||
3. **Agent Settings**: Capabilities and expertise configuration
|
||||
4. **Security Setup**: Encryption and audit logging
|
||||
|
||||
### Phase 5: Service Installation
|
||||
1. **SystemD Integration**: Service file installation
|
||||
2. **Service Activation**: Enable and start BZZZ
|
||||
3. **Health Verification**: Service status validation
|
||||
4. **Coordinator Setup**: Additional components if needed
|
||||
|
||||
## Generated Configuration
|
||||
|
||||
### Complete BZZZ YAML Configuration
|
||||
```yaml
|
||||
# Node Identity
|
||||
node:
|
||||
id: "hostname"
|
||||
role: "worker|coordinator"
|
||||
|
||||
# API Configuration
|
||||
api:
|
||||
host: "0.0.0.0"
|
||||
port: 8080
|
||||
|
||||
# Health Monitoring
|
||||
health:
|
||||
port: 8081
|
||||
enabled: true
|
||||
|
||||
# P2P Networking
|
||||
p2p:
|
||||
port: 4001
|
||||
discovery:
|
||||
enabled: true
|
||||
bootstrap_nodes: []
|
||||
service_tag: "bzzz-peer-discovery"
|
||||
topics:
|
||||
bzzz: "bzzz/coordination/v1"
|
||||
hmmm: "hmmm/meta-discussion/v1"
|
||||
|
||||
# Agent Configuration
|
||||
agent:
|
||||
id: "hostname-agent"
|
||||
capabilities: ["general", "reasoning", "task-coordination"]
|
||||
poll_interval: "30s"
|
||||
max_tasks: 3
|
||||
specialization: "general_developer"
|
||||
role: "Full Stack Engineer"
|
||||
expertise: ["golang", "typescript", "docker", "kubernetes"]
|
||||
|
||||
# Repository Integration (CORE FEATURE)
|
||||
repository:
|
||||
provider: "gitea|github"
|
||||
config:
|
||||
base_url: "provider-url"
|
||||
owner: "repository-owner"
|
||||
repository: "repository-name"
|
||||
task_label: "bzzz-task"
|
||||
token_file: "path-to-token"
|
||||
|
||||
# Security Configuration
|
||||
security:
|
||||
admin_key_shares:
|
||||
threshold: 3
|
||||
total_shares: 5
|
||||
election_config:
|
||||
heartbeat_timeout: "5s"
|
||||
discovery_timeout: "30s"
|
||||
election_timeout: "15s"
|
||||
minimum_quorum: 3
|
||||
key_rotation_days: 90
|
||||
audit_logging: true
|
||||
|
||||
# Storage and Logging
|
||||
storage:
|
||||
path: "$HOME/.chorus/data"
|
||||
type: "filesystem"
|
||||
|
||||
logging:
|
||||
level: "info"
|
||||
format: "text"
|
||||
output: "stdout"
|
||||
file: "$HOME/.chorus/logs/bzzz.log"
|
||||
```
|
||||
|
||||
## Service Management
|
||||
|
||||
### SystemD Service Configuration
|
||||
```ini
|
||||
[Unit]
|
||||
Description=BZZZ P2P Task Coordination System
|
||||
Documentation=https://chorus.services/docs/bzzz
|
||||
After=network.target
|
||||
Wants=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=username
|
||||
Group=username
|
||||
WorkingDirectory=/path/to/bzzz
|
||||
ExecStart=/path/to/bzzz --config /path/to/config/bzzz.yaml
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
# Security Settings
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=false
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
### Service Commands
|
||||
```bash
|
||||
# Service Management
|
||||
sudo systemctl status bzzz # Check status
|
||||
sudo systemctl restart bzzz # Restart service
|
||||
sudo journalctl -u bzzz -f # Follow logs
|
||||
|
||||
# Health Monitoring
|
||||
curl http://localhost:8081/health # Health check
|
||||
curl http://localhost:8081/metrics # Metrics
|
||||
curl http://localhost:8080 # API endpoint
|
||||
```
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Health and Monitoring
|
||||
- `GET /health` - Service health status
|
||||
- `GET /metrics` - Prometheus metrics
|
||||
- `GET /status` - Agent status and active tasks
|
||||
|
||||
### Task Coordination
|
||||
- Task discovery handled automatically via repository polling
|
||||
- Task claiming through repository provider APIs
|
||||
- Progress updates via repository comments/labels
|
||||
|
||||
## Security Features
|
||||
|
||||
### Credential Management
|
||||
- **Token Storage**: Secure file permissions (600)
|
||||
- **API Validation**: Repository access verification
|
||||
- **Encryption**: Age keys for coordinator nodes
|
||||
- **Audit Logging**: Security event tracking
|
||||
|
||||
### Network Security
|
||||
- **P2P Encryption**: libp2p secure channels
|
||||
- **API Authentication**: Repository token validation
|
||||
- **Local Binding**: Services bound to localhost by default
|
||||
|
||||
## Installation Verification
|
||||
|
||||
### Automatic Checks
|
||||
1. **Service Status**: BZZZ systemd service active
|
||||
2. **Configuration**: Valid YAML configuration file
|
||||
3. **Repository Access**: API connectivity test
|
||||
4. **Ollama Status**: AI runtime availability
|
||||
|
||||
### Manual Verification
|
||||
```bash
|
||||
# Check all services
|
||||
systemctl status bzzz ollama
|
||||
|
||||
# Test API endpoints
|
||||
curl http://localhost:8081/health
|
||||
curl http://localhost:8080/status
|
||||
|
||||
# View configuration
|
||||
cat ~/chorus/project-queues/active/BZZZ/config/bzzz.yaml
|
||||
|
||||
# Check logs
|
||||
sudo journalctl -u bzzz --since "1 hour ago"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Service Not Starting
|
||||
```bash
|
||||
# Check logs
|
||||
sudo journalctl -u bzzz -f
|
||||
|
||||
# Verify binary
|
||||
~/chorus/project-queues/active/BZZZ/bzzz --version
|
||||
|
||||
# Check configuration
|
||||
cat ~/chorus/project-queues/active/BZZZ/config/bzzz.yaml
|
||||
```
|
||||
|
||||
#### Repository Access Issues
|
||||
```bash
|
||||
# Verify token file
|
||||
ls -la ~/chorus/business/secrets/
|
||||
|
||||
# Test API access manually
|
||||
curl -H "Authorization: token $(cat ~/chorus/business/secrets/gitea-token)" \
|
||||
http://ironwood:3000/api/v1/user
|
||||
```
|
||||
|
||||
#### Network Connectivity
|
||||
```bash
|
||||
# Check port availability
|
||||
netstat -tlnp | grep :8080
|
||||
netstat -tlnp | grep :8081
|
||||
|
||||
# Test P2P connectivity
|
||||
netstat -tlnp | grep :4001
|
||||
```
|
||||
|
||||
## Coordinator Features
|
||||
|
||||
### Additional Components
|
||||
- **Docker**: Container runtime for WHOOSH dashboard
|
||||
- **Age Encryption**: Cryptographic key management
|
||||
- **WHOOSH Integration**: Web-based cluster management
|
||||
- **Bootstrap Node**: P2P network discovery
|
||||
|
||||
### Setup Process
|
||||
```bash
|
||||
# Install as coordinator
|
||||
curl -fsSL https://chorus.services/install-enhanced.sh | sh -s -- --coordinator
|
||||
|
||||
# Additional coordinator tasks
|
||||
docker-compose up -d whoosh # Start dashboard
|
||||
age-keygen -o secrets/key # Generate encryption keys
|
||||
```
|
||||
|
||||
## Architecture Integration
|
||||
|
||||
### CHORUS Ecosystem
|
||||
- **BZZZ**: P2P task coordination agent
|
||||
- **WHOOSH**: Web-based cluster dashboard
|
||||
- **Ollama**: Local AI model runtime
|
||||
- **Repository Provider**: Task source (GITEA/GitHub)
|
||||
|
||||
### Data Flow
|
||||
1. **Task Discovery**: Repository polling for labeled issues
|
||||
2. **Task Claiming**: Atomic assignment via API
|
||||
3. **Work Execution**: Local processing with progress updates
|
||||
4. **Task Completion**: Results submission and issue closure
|
||||
|
||||
## Migration and Updates
|
||||
|
||||
### From Previous Versions
|
||||
- Configuration migration handled automatically
|
||||
- Service restart required for updates
|
||||
- Backward compatibility with existing repositories
|
||||
|
||||
### Update Process
|
||||
```bash
|
||||
# Download new installer
|
||||
curl -fsSL https://chorus.services/install-enhanced.sh > install.sh
|
||||
|
||||
# Run update (preserves configuration)
|
||||
chmod +x install.sh && ./install.sh
|
||||
```
|
||||
|
||||
## Performance and Scaling
|
||||
|
||||
### Resource Requirements
|
||||
- **CPU**: 1-2 cores minimum
|
||||
- **Memory**: 2GB RAM minimum
|
||||
- **Storage**: 10GB for binaries, models, and logs
|
||||
- **Network**: Stable internet for repository access
|
||||
|
||||
### Scaling Considerations
|
||||
- **Worker Nodes**: Add with same installer
|
||||
- **Load Balancing**: Automatic via P2P discovery
|
||||
- **High Availability**: Multi-coordinator setup supported
|
||||
|
||||
## Integration Points
|
||||
|
||||
### Repository Providers
|
||||
- **GITEA**: Self-hosted Git service
|
||||
- **GitHub**: Cloud-based Git service
|
||||
- **Custom**: Extensible provider architecture
|
||||
|
||||
### AI Models
|
||||
- **Ollama Integration**: Local model runtime
|
||||
- **Model Management**: Automatic pulling and updates
|
||||
- **Custom Models**: Support for specialized models
|
||||
|
||||
### Monitoring
|
||||
- **SystemD**: Native service monitoring
|
||||
- **Health Endpoints**: HTTP health checks
|
||||
- **Metrics**: Prometheus-compatible metrics
|
||||
- **Logs**: Structured logging to journald
|
||||
|
||||
## Comparison with Basic Installer
|
||||
|
||||
### Enhanced Features (install-chorus-enhanced.sh)
|
||||
✅ **Repository Configuration**: Complete GITEA/GitHub setup
|
||||
✅ **Credential Management**: Secure token storage
|
||||
✅ **API Validation**: Repository access verification
|
||||
✅ **YAML Configuration**: Complete config generation
|
||||
✅ **Interactive Setup**: User-friendly configuration
|
||||
✅ **Auto-detection**: GITEA instance discovery
|
||||
✅ **Provider Switching**: GitHub/GITEA selection
|
||||
|
||||
### Basic Installer Limitations (install-chorus.sh)
|
||||
❌ **No Repository Setup**: Manual configuration required
|
||||
❌ **No Credentials**: Token management missing
|
||||
❌ **JSON Config**: Basic configuration only
|
||||
❌ **No Validation**: No API connectivity testing
|
||||
❌ **Manual Setup**: Requires post-install configuration
|
||||
|
||||
This enhanced installer completely addresses the critical gap identified during deployment, providing a truly seamless installation experience from download to functional task coordination.
|
||||
171
installer/README.md
Normal file
171
installer/README.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# CHORUS Installer & Release System
|
||||
|
||||
This directory contains the complete installer and release build system for CHORUS.
|
||||
|
||||
## Files Overview
|
||||
|
||||
### Installer System
|
||||
- **`install-chorus.sh`** - Main CLI installer script (like Ollama)
|
||||
- **`chorus-services-landing.html`** - Landing page for chorus.services website
|
||||
|
||||
### Build System
|
||||
- **`build-release.sh`** - Comprehensive cross-platform build system
|
||||
- **`build-bzzz-minimal.sh`** - Minimal BZZZ builder (avoids import cycles)
|
||||
- **`deploy-releases.sh`** - Deploy built binaries to release servers
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Build Binaries
|
||||
|
||||
For a quick minimal build (recommended):
|
||||
```bash
|
||||
./build-bzzz-minimal.sh
|
||||
```
|
||||
|
||||
For full cross-platform build:
|
||||
```bash
|
||||
./build-release.sh
|
||||
```
|
||||
|
||||
### 2. Deploy Locally for Testing
|
||||
|
||||
```bash
|
||||
./deploy-releases.sh --target local
|
||||
```
|
||||
|
||||
This creates a local HTTP server at `http://localhost:8000` and generates `install-chorus-local.sh` for testing.
|
||||
|
||||
### 3. Test the Installer
|
||||
|
||||
Start the local release server:
|
||||
```bash
|
||||
cd ~/chorus/local-releases && ./serve.sh
|
||||
```
|
||||
|
||||
In another terminal, test the installer:
|
||||
```bash
|
||||
./install-chorus-local.sh --coordinator --skip-deps
|
||||
```
|
||||
|
||||
### 4. Deploy to Production
|
||||
|
||||
```bash
|
||||
./deploy-releases.sh --target production
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Binary Distribution URLs
|
||||
|
||||
The installer expects these URLs to be available:
|
||||
|
||||
- `https://releases.chorus.services/bzzz/latest/bzzz-linux-amd64`
|
||||
- `https://releases.chorus.services/bzzz/latest/bzzz-darwin-amd64`
|
||||
- `https://releases.chorus.services/bzzz/latest/bzzz-linux-arm64`
|
||||
- `https://releases.chorus.services/bzzz/latest/bzzz.service`
|
||||
- `https://releases.chorus.services/bzzz/latest/install-service.sh`
|
||||
- `https://releases.chorus.services/whoosh/latest/whoosh-docker-compose.tar.gz`
|
||||
|
||||
### Supported Platforms
|
||||
|
||||
- Linux AMD64 (x86_64)
|
||||
- Linux ARM64 (aarch64)
|
||||
- Linux ARM (armv7)
|
||||
- macOS AMD64 (Intel)
|
||||
- macOS ARM64 (Apple Silicon)
|
||||
|
||||
## Features
|
||||
|
||||
### CLI Installer Features
|
||||
- ✅ One-command installation like Ollama
|
||||
- ✅ Cross-platform support (Linux, macOS)
|
||||
- ✅ Pre-built binary distribution
|
||||
- ✅ Automatic dependency detection
|
||||
- ✅ Coordinator vs worker node setup
|
||||
- ✅ AI model installation
|
||||
- ✅ Systemd service setup
|
||||
- ✅ Age encryption key generation
|
||||
- ✅ Graceful error handling
|
||||
|
||||
### Build System Features
|
||||
- ✅ Cross-platform binary builds
|
||||
- ✅ Minimal BZZZ builder (avoids import cycles)
|
||||
- ✅ Automatic checksums
|
||||
- ✅ Release versioning
|
||||
- ✅ Service file generation
|
||||
- ✅ Install script creation
|
||||
|
||||
### Deployment Features
|
||||
- ✅ Local development server
|
||||
- ✅ Production deployment
|
||||
- ✅ Docker Swarm deployment
|
||||
- ✅ Automatic URL updates for testing
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Build and deploy for local testing:
|
||||
```bash
|
||||
./build-bzzz-minimal.sh
|
||||
./deploy-releases.sh --target local
|
||||
cd ~/chorus/local-releases && ./serve.sh &
|
||||
./install-chorus-local.sh --coordinator
|
||||
```
|
||||
|
||||
### Build specific version:
|
||||
```bash
|
||||
VERSION=v1.0.0 ./build-bzzz-minimal.sh
|
||||
./deploy-releases.sh --target production --channel v1.0.0
|
||||
```
|
||||
|
||||
### Deploy to Docker Swarm:
|
||||
```bash
|
||||
./deploy-releases.sh --target swarm
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
### For Users
|
||||
- Simple one-command installation
|
||||
- No need to install development tools
|
||||
- Fast download and setup
|
||||
- Cross-platform compatibility
|
||||
|
||||
### For Developers
|
||||
- Protected source code
|
||||
- Controlled licensing
|
||||
- Version management
|
||||
- Easy testing and deployment
|
||||
|
||||
### For Business
|
||||
- Professional distribution
|
||||
- Licensing control
|
||||
- Usage analytics potential
|
||||
- Brand consistency
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### If BZZZ build fails with import cycles:
|
||||
Use the minimal builder:
|
||||
```bash
|
||||
./build-bzzz-minimal.sh
|
||||
```
|
||||
|
||||
This creates a basic HTTP server that provides the API endpoints needed by WHOOSH and other components.
|
||||
|
||||
### If installer can't download binaries:
|
||||
1. Check if local server is running: `curl http://localhost:8000/bzzz/latest/bzzz-linux-amd64`
|
||||
2. Use the local installer: `./install-chorus-local.sh`
|
||||
3. Check deployment logs
|
||||
|
||||
### If service won't start:
|
||||
1. Check binary permissions: `ls -la ~/chorus/project-queues/active/BZZZ/bzzz`
|
||||
2. Test binary manually: `~/chorus/project-queues/active/BZZZ/bzzz --version`
|
||||
3. Check service logs: `sudo journalctl -u bzzz -f`
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Set up releases.chorus.services** - Host the release files
|
||||
2. **Automate builds** - CI/CD pipeline for automatic releases
|
||||
3. **Add telemetry** - Track installer usage and success rates
|
||||
4. **Expand platforms** - Windows support, additional architectures
|
||||
5. **Package managers** - Homebrew, APT, etc.
|
||||
324
installer/build-bzzz-minimal.sh
Executable file
324
installer/build-bzzz-minimal.sh
Executable file
@@ -0,0 +1,324 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Minimal BZZZ Binary Builder
|
||||
# Creates a basic BZZZ binary that can be distributed
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() { echo -e "${GREEN}✓${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}⚠${NC} $1"; }
|
||||
log_error() { echo -e "${RED}✗${NC} $1"; }
|
||||
log_step() { echo -e "${BLUE}▶${NC} $1"; }
|
||||
|
||||
# Configuration
|
||||
BZZZ_SOURCE="$HOME/chorus/project-queues/active/BZZZ"
|
||||
BUILD_DIR="$HOME/chorus/releases/bzzz/latest"
|
||||
VERSION="${VERSION:-$(date +%Y%m%d-%H%M%S)}"
|
||||
|
||||
# Create minimal main.go that avoids import cycles
|
||||
create_minimal_main() {
|
||||
local temp_dir="$1"
|
||||
|
||||
cat > "$temp_dir/main.go" << 'EOF'
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
version = "dev"
|
||||
port = flag.String("port", "8080", "API port")
|
||||
host = flag.String("host", "0.0.0.0", "API host")
|
||||
showVersion = flag.Bool("version", false, "Show version")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
if *showVersion {
|
||||
fmt.Printf("BZZZ P2P Task Coordination System v%s\n", version)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("🐝 BZZZ P2P Task Coordination System v%s", version)
|
||||
log.Printf("Starting API server on %s:%s", *host, *port)
|
||||
|
||||
// Basic HTTP server
|
||||
mux := http.NewServeMux()
|
||||
|
||||
// Health check endpoint
|
||||
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprintf(w, `{"status":"ok","service":"bzzz","version":"%s","timestamp":"%s"}`,
|
||||
version, time.Now().UTC().Format(time.RFC3339))
|
||||
})
|
||||
|
||||
// Status endpoint
|
||||
mux.HandleFunc("/api/agent/status", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
hostname, _ := os.Hostname()
|
||||
fmt.Fprintf(w, `{
|
||||
"status":"active",
|
||||
"hostname":"%s",
|
||||
"version":"%s",
|
||||
"capabilities":["coordination","p2p"],
|
||||
"models":[],
|
||||
"uptime":"%s"
|
||||
}`, hostname, version, time.Since(time.Now()).String())
|
||||
})
|
||||
|
||||
// Basic info endpoint
|
||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
fmt.Fprintf(w, `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>BZZZ P2P System</title></head>
|
||||
<body>
|
||||
<h1>🐝 BZZZ P2P Task Coordination System</h1>
|
||||
<p>Version: %s</p>
|
||||
<p>Status: <a href="/health">Health Check</a></p>
|
||||
<p>API: <a href="/api/agent/status">Agent Status</a></p>
|
||||
</body>
|
||||
</html>`, version)
|
||||
})
|
||||
|
||||
server := &http.Server{
|
||||
Addr: *host + ":" + *port,
|
||||
Handler: mux,
|
||||
}
|
||||
|
||||
// Graceful shutdown
|
||||
go func() {
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-sigChan
|
||||
|
||||
log.Println("Shutting down BZZZ...")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
log.Printf("Server shutdown error: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
log.Printf("BZZZ ready at http://%s:%s", *host, *port)
|
||||
|
||||
if err := server.ListenAndServe(); err != http.ErrServerClosed {
|
||||
log.Fatalf("Server error: %v", err)
|
||||
}
|
||||
|
||||
log.Println("BZZZ stopped")
|
||||
}
|
||||
EOF
|
||||
|
||||
cat > "$temp_dir/go.mod" << EOF
|
||||
module github.com/anthonyrawlins/bzzz
|
||||
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
// No external dependencies to avoid import cycles
|
||||
)
|
||||
EOF
|
||||
|
||||
log_info "Created minimal main.go"
|
||||
}
|
||||
|
||||
# Build minimal BZZZ
|
||||
build_minimal_bzzz() {
|
||||
log_step "Building minimal BZZZ binaries..."
|
||||
|
||||
# Create temporary build directory
|
||||
local temp_dir=$(mktemp -d)
|
||||
|
||||
# Create minimal Go files
|
||||
create_minimal_main "$temp_dir"
|
||||
|
||||
cd "$temp_dir"
|
||||
|
||||
# Build for different platforms
|
||||
local platforms=(
|
||||
"linux/amd64"
|
||||
"linux/arm64"
|
||||
"linux/arm"
|
||||
"darwin/amd64"
|
||||
"darwin/arm64"
|
||||
)
|
||||
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
for platform in "${platforms[@]}"; do
|
||||
local os="${platform%/*}"
|
||||
local arch="${platform#*/}"
|
||||
|
||||
log_step "Building for $os/$arch..."
|
||||
|
||||
local output_name="bzzz-$os-$arch"
|
||||
local output_path="$BUILD_DIR/$output_name"
|
||||
|
||||
export GOOS="$os"
|
||||
export GOARCH="$arch"
|
||||
export CGO_ENABLED=0
|
||||
|
||||
if go build -ldflags="-s -w -X main.version=$VERSION" -o "$output_path" .; then
|
||||
log_info "Built $output_name"
|
||||
else
|
||||
log_error "Failed to build $output_name"
|
||||
fi
|
||||
done
|
||||
|
||||
# Reset environment
|
||||
unset GOOS GOARCH CGO_ENABLED
|
||||
|
||||
# Cleanup
|
||||
rm -rf "$temp_dir"
|
||||
|
||||
log_info "Minimal BZZZ binaries built"
|
||||
}
|
||||
|
||||
# Copy support files
|
||||
copy_support_files() {
|
||||
log_step "Copying support files..."
|
||||
|
||||
# Create service file
|
||||
cat > "$BUILD_DIR/bzzz.service" << EOF
|
||||
[Unit]
|
||||
Description=BZZZ P2P Task Coordination System
|
||||
Documentation=https://chorus.services/docs/bzzz
|
||||
After=network.target
|
||||
Wants=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=PLACEHOLDER_USER
|
||||
Group=PLACEHOLDER_USER
|
||||
WorkingDirectory=PLACEHOLDER_BZZZ_DIR
|
||||
ExecStart=PLACEHOLDER_BZZZ_DIR/bzzz
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
KillMode=mixed
|
||||
KillSignal=SIGTERM
|
||||
TimeoutStopSec=30
|
||||
|
||||
# Environment variables
|
||||
Environment=HOME=PLACEHOLDER_HOME
|
||||
Environment=USER=PLACEHOLDER_USER
|
||||
|
||||
# Logging
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=bzzz
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=false
|
||||
ReadWritePaths=PLACEHOLDER_BZZZ_DIR
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65536
|
||||
LimitNPROC=4096
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create install script
|
||||
cat > "$BUILD_DIR/install-service.sh" << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
# BZZZ Service Installation Script
|
||||
set -e
|
||||
|
||||
echo "🐝 Installing BZZZ P2P Task Coordination Service..."
|
||||
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "❌ This script must be run as root or with sudo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BZZZ_DIR="$(pwd)"
|
||||
SERVICE_FILE="$BZZZ_DIR/bzzz.service"
|
||||
SYSTEMD_DIR="/etc/systemd/system"
|
||||
|
||||
# Replace placeholders in service file
|
||||
sed -i "s|PLACEHOLDER_USER|$SUDO_USER|g" "$SERVICE_FILE"
|
||||
sed -i "s|PLACEHOLDER_HOME|$(eval echo ~$SUDO_USER)|g" "$SERVICE_FILE"
|
||||
sed -i "s|PLACEHOLDER_BZZZ_DIR|$BZZZ_DIR|g" "$SERVICE_FILE"
|
||||
|
||||
chmod +x "$BZZZ_DIR/bzzz"
|
||||
cp "$SERVICE_FILE" "$SYSTEMD_DIR/bzzz.service"
|
||||
chmod 644 "$SYSTEMD_DIR/bzzz.service"
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable bzzz.service
|
||||
systemctl start bzzz.service
|
||||
|
||||
echo "✅ BZZZ service installed and started"
|
||||
systemctl status bzzz.service --no-pager -l
|
||||
EOF
|
||||
|
||||
chmod +x "$BUILD_DIR/install-service.sh"
|
||||
|
||||
log_info "Support files created"
|
||||
}
|
||||
|
||||
# Generate checksums
|
||||
generate_checksums() {
|
||||
log_step "Generating checksums..."
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
sha256sum * > checksums.txt
|
||||
|
||||
log_info "Checksums generated"
|
||||
}
|
||||
|
||||
# Show summary
|
||||
show_summary() {
|
||||
echo ""
|
||||
echo -e "${GREEN}🎉 Minimal BZZZ Build Complete!${NC}"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo -e "Build Directory: $BUILD_DIR"
|
||||
echo -e "Version: $VERSION"
|
||||
echo ""
|
||||
echo "Built files:"
|
||||
ls -la "$BUILD_DIR"
|
||||
echo ""
|
||||
echo "Test a binary:"
|
||||
echo " $BUILD_DIR/bzzz-linux-amd64 --version"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
echo -e "${BLUE}🐝 BZZZ Minimal Binary Builder${NC}"
|
||||
echo ""
|
||||
|
||||
build_minimal_bzzz
|
||||
copy_support_files
|
||||
generate_checksums
|
||||
show_summary
|
||||
}
|
||||
|
||||
main "$@"
|
||||
409
installer/build-release.sh
Executable file
409
installer/build-release.sh
Executable file
@@ -0,0 +1,409 @@
|
||||
#!/bin/bash
|
||||
|
||||
# CHORUS Release Build System
|
||||
# Builds cross-platform binaries for distribution
|
||||
|
||||
set -e
|
||||
|
||||
# Colors and formatting
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
PURPLE='\033[0;35m'
|
||||
CYAN='\033[0;36m'
|
||||
WHITE='\033[1;37m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
CHORUS_ROOT="$HOME/chorus/project-queues/active"
|
||||
BZZZ_SOURCE="$CHORUS_ROOT/BZZZ"
|
||||
WHOOSH_SOURCE="$CHORUS_ROOT/WHOOSH"
|
||||
BUILD_DIR="$HOME/chorus/releases"
|
||||
VERSION="${VERSION:-$(date +%Y%m%d-%H%M%S)}"
|
||||
RELEASE_CHANNEL="${RELEASE_CHANNEL:-latest}"
|
||||
|
||||
# Target platforms
|
||||
PLATFORMS=(
|
||||
"linux/amd64"
|
||||
"linux/arm64"
|
||||
"linux/arm"
|
||||
"darwin/amd64"
|
||||
"darwin/arm64"
|
||||
)
|
||||
|
||||
# Logging functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}✓${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}⚠${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}✗${NC} $1"
|
||||
}
|
||||
|
||||
log_step() {
|
||||
echo -e "${BLUE}▶${NC} $1"
|
||||
}
|
||||
|
||||
print_banner() {
|
||||
echo -e "${PURPLE}"
|
||||
cat << 'EOF'
|
||||
██████╗██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
|
||||
██╔════╝██║ ██║██╔═══██╗██╔══██╗██║ ██║██╔════╝
|
||||
██║ ███████║██║ ██║██████╔╝██║ ██║███████╗
|
||||
██║ ██╔══██║██║ ██║██╔══██╗██║ ██║╚════██║
|
||||
╚██████╗██║ ██║╚██████╔╝██║ ██║╚██████╔╝███████║
|
||||
╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝
|
||||
|
||||
🏗️ Release Build System
|
||||
EOF
|
||||
echo -e "${NC}"
|
||||
echo -e "${CYAN} Building cross-platform binaries for distribution${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Clean previous builds
|
||||
clean_build_dir() {
|
||||
log_step "Cleaning build directory..."
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir -p "$BUILD_DIR"/{bzzz,whoosh}/"$RELEASE_CHANNEL"
|
||||
log_info "Build directory cleaned"
|
||||
}
|
||||
|
||||
# Check prerequisites
|
||||
check_prerequisites() {
|
||||
log_step "Checking prerequisites..."
|
||||
|
||||
# Check Go installation
|
||||
if ! command -v go >/dev/null 2>&1; then
|
||||
log_error "Go is not installed. Please install Go first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check Docker for WHOOSH
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
log_warn "Docker not found - WHOOSH builds will be skipped"
|
||||
fi
|
||||
|
||||
# Check source directories
|
||||
if [[ ! -d "$BZZZ_SOURCE" ]]; then
|
||||
log_error "BZZZ source not found at $BZZZ_SOURCE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -d "$WHOOSH_SOURCE" ]]; then
|
||||
log_warn "WHOOSH source not found at $WHOOSH_SOURCE - skipping WHOOSH build"
|
||||
fi
|
||||
|
||||
log_info "Prerequisites checked"
|
||||
}
|
||||
|
||||
# Build BZZZ binaries
|
||||
build_bzzz() {
|
||||
log_step "Building BZZZ binaries..."
|
||||
|
||||
cd "$BZZZ_SOURCE"
|
||||
|
||||
# Fix import cycles first
|
||||
log_step "Attempting to fix import cycles..."
|
||||
if ! fix_import_cycles; then
|
||||
log_warn "Could not automatically fix import cycles"
|
||||
fi
|
||||
|
||||
# Clean module cache
|
||||
go clean -modcache 2>/dev/null || true
|
||||
go mod tidy
|
||||
|
||||
# Build for each platform
|
||||
for platform in "${PLATFORMS[@]}"; do
|
||||
local os="${platform%/*}"
|
||||
local arch="${platform#*/}"
|
||||
|
||||
log_step "Building BZZZ for $os/$arch..."
|
||||
|
||||
local output_name="bzzz-$os-$arch"
|
||||
if [[ "$os" == "windows" ]]; then
|
||||
output_name="$output_name.exe"
|
||||
fi
|
||||
|
||||
local output_path="$BUILD_DIR/bzzz/$RELEASE_CHANNEL/$output_name"
|
||||
|
||||
# Set build environment
|
||||
export GOOS="$os"
|
||||
export GOARCH="$arch"
|
||||
export CGO_ENABLED=0
|
||||
|
||||
# Build with minimal dependencies to avoid import cycles
|
||||
if go build -tags="minimal,release" -ldflags="-s -w -X main.version=$VERSION" -o "$output_path" . 2>/dev/null; then
|
||||
log_info "Built $output_name successfully"
|
||||
else
|
||||
log_warn "Failed to build $output_name - trying alternative approach"
|
||||
|
||||
# Try building with main.go only
|
||||
if go build -tags="minimal" -ldflags="-s -w" -o "$output_path" main.go 2>/dev/null; then
|
||||
log_info "Built $output_name (minimal version)"
|
||||
else
|
||||
log_error "Failed to build $output_name"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Reset environment
|
||||
unset GOOS GOARCH CGO_ENABLED
|
||||
|
||||
log_info "BZZZ binaries build completed"
|
||||
}
|
||||
|
||||
# Fix import cycles (basic attempt)
|
||||
fix_import_cycles() {
|
||||
log_step "Attempting to fix Go import cycles..."
|
||||
|
||||
# Look for common import cycle patterns and try to fix them
|
||||
# This is a basic approach - may need manual intervention for complex cycles
|
||||
|
||||
# Create a backup
|
||||
cp -r . "${BZZZ_SOURCE}.backup.$(date +%s)" 2>/dev/null || true
|
||||
|
||||
# Try to build and capture errors
|
||||
local build_output
|
||||
if build_output=$(go build . 2>&1); then
|
||||
log_info "No import cycles detected"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if echo "$build_output" | grep -q "import cycle"; then
|
||||
log_warn "Import cycles detected - manual intervention may be required"
|
||||
echo "$build_output" | grep "import cycle" | head -5
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Copy service files
|
||||
copy_service_files() {
|
||||
log_step "Copying service files..."
|
||||
|
||||
local bzzz_release_dir="$BUILD_DIR/bzzz/$RELEASE_CHANNEL"
|
||||
|
||||
# Copy systemd service file
|
||||
if [[ -f "$BZZZ_SOURCE/bzzz.service" ]]; then
|
||||
cp "$BZZZ_SOURCE/bzzz.service" "$bzzz_release_dir/"
|
||||
log_info "Copied bzzz.service"
|
||||
else
|
||||
log_warn "bzzz.service not found in source"
|
||||
fi
|
||||
|
||||
# Copy install script
|
||||
if [[ -f "$BZZZ_SOURCE/install-service.sh" ]]; then
|
||||
cp "$BZZZ_SOURCE/install-service.sh" "$bzzz_release_dir/"
|
||||
chmod +x "$bzzz_release_dir/install-service.sh"
|
||||
log_info "Copied install-service.sh"
|
||||
else
|
||||
log_warn "install-service.sh not found in source"
|
||||
fi
|
||||
|
||||
log_info "Service files copied"
|
||||
}
|
||||
|
||||
# Build WHOOSH package
|
||||
build_whoosh() {
|
||||
if [[ ! -d "$WHOOSH_SOURCE" ]]; then
|
||||
log_warn "WHOOSH source not found - skipping"
|
||||
return
|
||||
fi
|
||||
|
||||
log_step "Building WHOOSH package..."
|
||||
|
||||
cd "$WHOOSH_SOURCE"
|
||||
|
||||
local whoosh_release_dir="$BUILD_DIR/whoosh/$RELEASE_CHANNEL"
|
||||
|
||||
# Create docker-compose package
|
||||
if [[ -f "docker-compose.yml" ]] || [[ -f "docker-compose.swarm.yml" ]]; then
|
||||
log_step "Creating WHOOSH Docker Compose package..."
|
||||
|
||||
# Create temporary directory for packaging
|
||||
local temp_dir=$(mktemp -d)
|
||||
|
||||
# Copy relevant files
|
||||
cp -r . "$temp_dir/whoosh/"
|
||||
|
||||
# Create tarball
|
||||
cd "$temp_dir"
|
||||
tar -czf "$whoosh_release_dir/whoosh-docker-compose.tar.gz" whoosh/
|
||||
|
||||
# Cleanup
|
||||
rm -rf "$temp_dir"
|
||||
|
||||
log_info "WHOOSH package created"
|
||||
else
|
||||
log_warn "No Docker Compose files found for WHOOSH"
|
||||
fi
|
||||
}
|
||||
|
||||
# Generate checksums
|
||||
generate_checksums() {
|
||||
log_step "Generating checksums..."
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
# Generate checksums for BZZZ binaries
|
||||
if [[ -d "bzzz/$RELEASE_CHANNEL" ]]; then
|
||||
cd "bzzz/$RELEASE_CHANNEL"
|
||||
sha256sum * > checksums.txt
|
||||
log_info "BZZZ checksums generated"
|
||||
cd "$BUILD_DIR"
|
||||
fi
|
||||
|
||||
# Generate checksums for WHOOSH
|
||||
if [[ -d "whoosh/$RELEASE_CHANNEL" ]]; then
|
||||
cd "whoosh/$RELEASE_CHANNEL"
|
||||
sha256sum * > checksums.txt 2>/dev/null || true
|
||||
log_info "WHOOSH checksums generated"
|
||||
cd "$BUILD_DIR"
|
||||
fi
|
||||
|
||||
log_info "Checksums generated"
|
||||
}
|
||||
|
||||
# Create release info
|
||||
create_release_info() {
|
||||
log_step "Creating release information..."
|
||||
|
||||
local release_info="$BUILD_DIR/release-info.json"
|
||||
|
||||
cat > "$release_info" << EOF
|
||||
{
|
||||
"version": "$VERSION",
|
||||
"channel": "$RELEASE_CHANNEL",
|
||||
"build_time": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||||
"platforms": [
|
||||
$(printf ' "%s"' "${PLATFORMS[@]}" | paste -sd ',' -)
|
||||
],
|
||||
"components": {
|
||||
"bzzz": {
|
||||
"description": "P2P Task Coordination System",
|
||||
"binaries": [
|
||||
$(find "$BUILD_DIR/bzzz/$RELEASE_CHANNEL" -name "bzzz-*" -type f | sed 's|.*/||' | sed 's/^/ "/' | sed 's/$/"/' | paste -sd ',' -)
|
||||
]
|
||||
},
|
||||
"whoosh": {
|
||||
"description": "Web Dashboard and Management Interface",
|
||||
"packages": [
|
||||
$(find "$BUILD_DIR/whoosh/$RELEASE_CHANNEL" -name "*.tar.gz" -type f 2>/dev/null | sed 's|.*/||' | sed 's/^/ "/' | sed 's/$/"/' | paste -sd ',' - || echo '')
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
log_info "Release information created"
|
||||
}
|
||||
|
||||
# Show build summary
|
||||
show_summary() {
|
||||
echo ""
|
||||
echo -e "${GREEN}🎉 Release Build Complete!${NC}"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo -e "${WHITE}Build Information:${NC}"
|
||||
echo " • Version: $VERSION"
|
||||
echo " • Channel: $RELEASE_CHANNEL"
|
||||
echo " • Build Directory: $BUILD_DIR"
|
||||
echo ""
|
||||
echo -e "${WHITE}Built Components:${NC}"
|
||||
|
||||
# List BZZZ binaries
|
||||
local bzzz_count=$(find "$BUILD_DIR/bzzz/$RELEASE_CHANNEL" -name "bzzz-*" -type f 2>/dev/null | wc -l)
|
||||
echo " • BZZZ binaries: $bzzz_count"
|
||||
|
||||
# List WHOOSH packages
|
||||
local whoosh_count=$(find "$BUILD_DIR/whoosh/$RELEASE_CHANNEL" -name "*.tar.gz" -type f 2>/dev/null | wc -l)
|
||||
echo " • WHOOSH packages: $whoosh_count"
|
||||
|
||||
echo ""
|
||||
echo -e "${WHITE}Next Steps:${NC}"
|
||||
echo " 1. Test binaries: $BUILD_DIR/bzzz/$RELEASE_CHANNEL/bzzz-linux-amd64 --version"
|
||||
echo " 2. Upload to releases.chorus.services"
|
||||
echo " 3. Update installer URLs if needed"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--version)
|
||||
VERSION="$2"
|
||||
shift 2
|
||||
;;
|
||||
--channel)
|
||||
RELEASE_CHANNEL="$2"
|
||||
shift 2
|
||||
;;
|
||||
--bzzz-only)
|
||||
BUILD_WHOOSH=false
|
||||
shift
|
||||
;;
|
||||
--whoosh-only)
|
||||
BUILD_BZZZ=false
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
echo "CHORUS Release Build System"
|
||||
echo ""
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --version VERSION Set release version (default: timestamp)"
|
||||
echo " --channel CHANNEL Set release channel (default: latest)"
|
||||
echo " --bzzz-only Build only BZZZ binaries"
|
||||
echo " --whoosh-only Build only WHOOSH packages"
|
||||
echo " --help Show this help"
|
||||
echo ""
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Default build flags
|
||||
BUILD_BZZZ=${BUILD_BZZZ:-true}
|
||||
BUILD_WHOOSH=${BUILD_WHOOSH:-true}
|
||||
|
||||
# Main build process
|
||||
main() {
|
||||
print_banner
|
||||
|
||||
echo -e "${WHITE}Starting CHORUS release build...${NC}"
|
||||
echo " Version: $VERSION"
|
||||
echo " Channel: $RELEASE_CHANNEL"
|
||||
echo ""
|
||||
|
||||
check_prerequisites
|
||||
clean_build_dir
|
||||
|
||||
if [[ "$BUILD_BZZZ" == "true" ]]; then
|
||||
build_bzzz
|
||||
copy_service_files
|
||||
fi
|
||||
|
||||
if [[ "$BUILD_WHOOSH" == "true" ]]; then
|
||||
build_whoosh
|
||||
fi
|
||||
|
||||
generate_checksums
|
||||
create_release_info
|
||||
|
||||
show_summary
|
||||
}
|
||||
|
||||
# Run main build process
|
||||
main "$@"
|
||||
252
installer/chorus-services-landing.html
Normal file
252
installer/chorus-services-landing.html
Normal file
@@ -0,0 +1,252 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CHORUS - Distributed AI Orchestration Platform</title>
|
||||
<meta name="description" content="One-command installation for distributed AI collaboration. Get started with CHORUS in seconds.">
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.hero {
|
||||
text-align: center;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 4rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 1rem;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
.tagline {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: 3rem;
|
||||
line-height: 1.6;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.install-section {
|
||||
background: rgba(255,255,255,0.1);
|
||||
padding: 2rem;
|
||||
border-radius: 15px;
|
||||
backdrop-filter: blur(10px);
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.install-title {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.code-block {
|
||||
background: #1a1a1a;
|
||||
color: #00ff00;
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 0.9rem;
|
||||
margin: 1rem 0;
|
||||
overflow-x: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.copy-btn:hover {
|
||||
background: #45a049;
|
||||
}
|
||||
|
||||
.options {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 1rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.option-card {
|
||||
background: rgba(255,255,255,0.1);
|
||||
padding: 1.5rem;
|
||||
border-radius: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.option-title {
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: #FFD700;
|
||||
}
|
||||
|
||||
.features {
|
||||
margin: 2rem 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.features h3 {
|
||||
margin-bottom: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.feature-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 1rem;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.feature-list li {
|
||||
padding: 0.5rem 0;
|
||||
border-left: 3px solid #FFD700;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
opacity: 0.7;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.logo {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.tagline {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.install-section {
|
||||
padding: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="hero">
|
||||
<div class="logo">🎵 CHORUS</div>
|
||||
<div class="tagline">Distributed AI Orchestration Platform</div>
|
||||
<div class="description">
|
||||
A living knowledge fabric where agents and humans collaborate across time and domains
|
||||
with zero friction and complete auditability. One-command installation with pre-built binaries.
|
||||
</div>
|
||||
|
||||
<div class="install-section">
|
||||
<h2 class="install-title">⚡ One-Command Installation</h2>
|
||||
|
||||
<div class="code-block">
|
||||
<button class="copy-btn" onclick="copyToClipboard(this, 'curl -fsSL https://chorus.services/install.sh | sh')">Copy</button>
|
||||
curl -fsSL https://chorus.services/install.sh | sh
|
||||
</div>
|
||||
|
||||
<div class="options">
|
||||
<div class="option-card">
|
||||
<div class="option-title">🎯 Coordinator Node</div>
|
||||
<p>Install as cluster coordinator with WHOOSH dashboard:</p>
|
||||
<div class="code-block">
|
||||
<button class="copy-btn" onclick="copyToClipboard(this, 'curl -fsSL https://chorus.services/install.sh | sh -s -- --coordinator')">Copy</button>
|
||||
curl -fsSL https://chorus.services/install.sh | sh -s -- --coordinator
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option-card">
|
||||
<div class="option-title">🤖 With AI Models</div>
|
||||
<p>Install with specific AI models:</p>
|
||||
<div class="code-block">
|
||||
<button class="copy-btn" onclick="copyToClipboard(this, 'curl -fsSL https://chorus.services/install.sh | sh -s -- --models \"llama3.2,qwen2.5:7b\"')">Copy</button>
|
||||
curl -fsSL https://chorus.services/install.sh | sh -s -- --models "llama3.2,qwen2.5:7b"
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="features">
|
||||
<h3>🚀 What You Get</h3>
|
||||
<ul class="feature-list">
|
||||
<li>🐝 <strong>BZZZ</strong> - P2P task coordination</li>
|
||||
<li>🔍 <strong>SLURP</strong> - Context curation</li>
|
||||
<li>📡 <strong>COOEE</strong> - Message queuing</li>
|
||||
<li>🛡️ <strong>SHHH</strong> - Secrets management</li>
|
||||
<li>💭 <strong>HMMM</strong> - Agent collaboration</li>
|
||||
<li>🫧 <strong>BUBBLE</strong> - Knowledge graphs</li>
|
||||
<li>🦙 <strong>PARALLAMA</strong> - Multi-GPU inference</li>
|
||||
<li>🌐 <strong>WHOOSH</strong> - Web dashboard</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="install-section">
|
||||
<h3>📖 Quick Start</h3>
|
||||
<ol style="text-align: left; line-height: 1.8;">
|
||||
<li><strong>Install coordinator:</strong> Run with <code>--coordinator</code> flag</li>
|
||||
<li><strong>Add workers:</strong> Run script on additional machines</li>
|
||||
<li><strong>Deploy agents:</strong> Use WHOOSH dashboard to manage</li>
|
||||
<li><strong>Collaborate:</strong> Agents work together automatically</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>🎵 CHORUS - Where AI agents collaborate like a symphony</p>
|
||||
<p>Documentation • GitHub • Community</p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function copyToClipboard(button, text) {
|
||||
navigator.clipboard.writeText(text).then(function() {
|
||||
const originalText = button.textContent;
|
||||
button.textContent = 'Copied!';
|
||||
button.style.background = '#4CAF50';
|
||||
setTimeout(function() {
|
||||
button.textContent = originalText;
|
||||
button.style.background = '#4CAF50';
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
340
installer/deploy-releases.sh
Executable file
340
installer/deploy-releases.sh
Executable file
@@ -0,0 +1,340 @@
|
||||
#!/bin/bash
|
||||
|
||||
# CHORUS Release Deployment Script
|
||||
# Deploys built binaries to the release distribution system
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
PURPLE='\033[0;35m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() { echo -e "${GREEN}✓${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}⚠${NC} $1"; }
|
||||
log_error() { echo -e "${RED}✗${NC} $1"; }
|
||||
log_step() { echo -e "${BLUE}▶${NC} $1"; }
|
||||
|
||||
# Configuration
|
||||
BUILD_DIR="$HOME/chorus/releases"
|
||||
DEPLOYMENT_TARGET="${DEPLOYMENT_TARGET:-local}"
|
||||
RELEASE_CHANNEL="${RELEASE_CHANNEL:-latest}"
|
||||
|
||||
# Deployment targets
|
||||
CHORUS_SERVICES_ROOT="/var/www/releases.chorus.services"
|
||||
LOCAL_SERVE_DIR="$HOME/chorus/local-releases"
|
||||
|
||||
print_banner() {
|
||||
echo -e "${PURPLE}"
|
||||
cat << 'EOF'
|
||||
██████╗██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
|
||||
██╔════╝██║ ██║██╔═══██╗██╔══██╗██║ ██║██╔════╝
|
||||
██║ ███████║██║ ██║██████╔╝██║ ██║███████╗
|
||||
██║ ██╔══██║██║ ██║██╔══██╗██║ ██║╚════██║
|
||||
╚██████╗██║ ██║╚██████╔╝██║ ██║╚██████╔╝███████║
|
||||
╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝
|
||||
|
||||
🚀 Release Deployment System
|
||||
EOF
|
||||
echo -e "${NC}"
|
||||
echo -e " Deploying to: $DEPLOYMENT_TARGET"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Check if builds exist
|
||||
check_builds() {
|
||||
log_step "Checking for built releases..."
|
||||
|
||||
if [[ ! -d "$BUILD_DIR" ]]; then
|
||||
log_error "Build directory not found: $BUILD_DIR"
|
||||
log_info "Run build-release.sh or build-bzzz-minimal.sh first"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local bzzz_dir="$BUILD_DIR/bzzz/$RELEASE_CHANNEL"
|
||||
local whoosh_dir="$BUILD_DIR/whoosh/$RELEASE_CHANNEL"
|
||||
|
||||
if [[ -d "$bzzz_dir" ]]; then
|
||||
local bzzz_count=$(find "$bzzz_dir" -name "bzzz-*" -type f 2>/dev/null | wc -l)
|
||||
log_info "Found $bzzz_count BZZZ binaries"
|
||||
else
|
||||
log_warn "No BZZZ builds found"
|
||||
fi
|
||||
|
||||
if [[ -d "$whoosh_dir" ]]; then
|
||||
local whoosh_count=$(find "$whoosh_dir" -name "*.tar.gz" -type f 2>/dev/null | wc -l)
|
||||
log_info "Found $whoosh_count WHOOSH packages"
|
||||
else
|
||||
log_warn "No WHOOSH builds found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Deploy to local development server
|
||||
deploy_local() {
|
||||
log_step "Deploying to local development server..."
|
||||
|
||||
mkdir -p "$LOCAL_SERVE_DIR"/{bzzz,whoosh}/"$RELEASE_CHANNEL"
|
||||
|
||||
# Copy BZZZ files
|
||||
if [[ -d "$BUILD_DIR/bzzz/$RELEASE_CHANNEL" ]]; then
|
||||
cp -r "$BUILD_DIR/bzzz/$RELEASE_CHANNEL"/* "$LOCAL_SERVE_DIR/bzzz/$RELEASE_CHANNEL/"
|
||||
log_info "BZZZ files copied to local server"
|
||||
fi
|
||||
|
||||
# Copy WHOOSH files
|
||||
if [[ -d "$BUILD_DIR/whoosh/$RELEASE_CHANNEL" ]]; then
|
||||
cp -r "$BUILD_DIR/whoosh/$RELEASE_CHANNEL"/* "$LOCAL_SERVE_DIR/whoosh/$RELEASE_CHANNEL/"
|
||||
log_info "WHOOSH files copied to local server"
|
||||
fi
|
||||
|
||||
# Create simple HTTP server script
|
||||
cat > "$LOCAL_SERVE_DIR/serve.sh" << 'EOF'
|
||||
#!/bin/bash
|
||||
echo "🎵 CHORUS Local Release Server"
|
||||
echo "Serving releases at http://localhost:8000"
|
||||
echo "URLs:"
|
||||
echo " http://localhost:8000/bzzz/latest/bzzz-linux-amd64"
|
||||
echo " http://localhost:8000/bzzz/latest/bzzz.service"
|
||||
echo " http://localhost:8000/bzzz/latest/install-service.sh"
|
||||
echo ""
|
||||
echo "Press Ctrl+C to stop"
|
||||
python3 -m http.server 8000
|
||||
EOF
|
||||
chmod +x "$LOCAL_SERVE_DIR/serve.sh"
|
||||
|
||||
log_info "Local deployment completed"
|
||||
echo ""
|
||||
echo -e "${YELLOW}To start local release server:${NC}"
|
||||
echo " cd $LOCAL_SERVE_DIR && ./serve.sh"
|
||||
echo ""
|
||||
echo -e "${YELLOW}To test installer with local server:${NC}"
|
||||
echo " # Edit install-chorus.sh and change:"
|
||||
echo " # GITEA_URL=\"http://localhost:8000\""
|
||||
echo " # Then run the installer"
|
||||
}
|
||||
|
||||
# Deploy to production server
|
||||
deploy_production() {
|
||||
log_step "Deploying to production server..."
|
||||
|
||||
if [[ ! -d "$CHORUS_SERVICES_ROOT" ]]; then
|
||||
log_error "Production deployment directory not found: $CHORUS_SERVICES_ROOT"
|
||||
log_info "Make sure you have access to the production server"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create production directory structure
|
||||
mkdir -p "$CHORUS_SERVICES_ROOT"/{bzzz,whoosh}/"$RELEASE_CHANNEL"
|
||||
|
||||
# Copy BZZZ files
|
||||
if [[ -d "$BUILD_DIR/bzzz/$RELEASE_CHANNEL" ]]; then
|
||||
cp -r "$BUILD_DIR/bzzz/$RELEASE_CHANNEL"/* "$CHORUS_SERVICES_ROOT/bzzz/$RELEASE_CHANNEL/"
|
||||
log_info "BZZZ files deployed to production"
|
||||
fi
|
||||
|
||||
# Copy WHOOSH files
|
||||
if [[ -d "$BUILD_DIR/whoosh/$RELEASE_CHANNEL" ]]; then
|
||||
cp -r "$BUILD_DIR/whoosh/$RELEASE_CHANNEL"/* "$CHORUS_SERVICES_ROOT/whoosh/$RELEASE_CHANNEL/"
|
||||
log_info "WHOOSH files deployed to production"
|
||||
fi
|
||||
|
||||
# Set proper permissions
|
||||
chmod -R 644 "$CHORUS_SERVICES_ROOT"/{bzzz,whoosh}/"$RELEASE_CHANNEL"/*
|
||||
find "$CHORUS_SERVICES_ROOT" -name "*.sh" -exec chmod 755 {} \;
|
||||
find "$CHORUS_SERVICES_ROOT" -name "bzzz-*" -exec chmod 755 {} \;
|
||||
|
||||
log_info "Production deployment completed"
|
||||
}
|
||||
|
||||
# Deploy to Docker Swarm (if available)
|
||||
deploy_swarm() {
|
||||
log_step "Deploying to Docker Swarm..."
|
||||
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
log_error "Docker not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create a simple nginx container to serve releases
|
||||
cat > "$BUILD_DIR/nginx.conf" << 'EOF'
|
||||
server {
|
||||
listen 80;
|
||||
server_name releases.chorus.services;
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
location / {
|
||||
autoindex on;
|
||||
autoindex_exact_size off;
|
||||
autoindex_localtime on;
|
||||
}
|
||||
|
||||
location ~* \.(sh|exe)$ {
|
||||
add_header Content-Type application/octet-stream;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
cat > "$BUILD_DIR/Dockerfile.releases" << 'EOF'
|
||||
FROM nginx:alpine
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY bzzz/ /usr/share/nginx/html/bzzz/
|
||||
COPY whoosh/ /usr/share/nginx/html/whoosh/
|
||||
EXPOSE 80
|
||||
EOF
|
||||
|
||||
cat > "$BUILD_DIR/docker-compose.releases.yml" << 'EOF'
|
||||
version: '3.8'
|
||||
services:
|
||||
releases:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.releases
|
||||
image: chorus/releases:latest
|
||||
ports:
|
||||
- "8080:80"
|
||||
deploy:
|
||||
replicas: 2
|
||||
placement:
|
||||
constraints:
|
||||
- node.role == worker
|
||||
networks:
|
||||
default:
|
||||
external: true
|
||||
name: chorus_network
|
||||
EOF
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
# Build and deploy
|
||||
docker build -f Dockerfile.releases -t chorus/releases:latest .
|
||||
|
||||
if docker stack ls | grep -q chorus-releases; then
|
||||
docker stack rm chorus-releases
|
||||
sleep 5
|
||||
fi
|
||||
|
||||
docker stack deploy -c docker-compose.releases.yml chorus-releases
|
||||
|
||||
log_info "Docker Swarm deployment completed"
|
||||
log_info "Releases available at http://your-swarm-manager:8080"
|
||||
}
|
||||
|
||||
# Update installer URLs for local testing
|
||||
update_installer_urls() {
|
||||
if [[ "$DEPLOYMENT_TARGET" == "local" ]]; then
|
||||
log_step "Updating installer URLs for local testing..."
|
||||
|
||||
local installer_file="install-chorus.sh"
|
||||
if [[ -f "$installer_file" ]]; then
|
||||
# Create a local version
|
||||
cp "$installer_file" "install-chorus-local.sh"
|
||||
|
||||
# Update URLs in the local version
|
||||
sed -i 's|https://releases.chorus.services|http://localhost:8000|g' "install-chorus-local.sh"
|
||||
|
||||
log_info "Created install-chorus-local.sh for local testing"
|
||||
echo ""
|
||||
echo -e "${YELLOW}To test with local server:${NC}"
|
||||
echo " 1. Start local server: cd $LOCAL_SERVE_DIR && ./serve.sh"
|
||||
echo " 2. In another terminal: ./install-chorus-local.sh --coordinator"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Show deployment summary
|
||||
show_summary() {
|
||||
echo ""
|
||||
echo -e "${GREEN}🎉 Deployment Complete!${NC}"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo -e "${BLUE}Deployment Target:${NC} $DEPLOYMENT_TARGET"
|
||||
echo -e "${BLUE}Release Channel:${NC} $RELEASE_CHANNEL"
|
||||
echo ""
|
||||
|
||||
case $DEPLOYMENT_TARGET in
|
||||
local)
|
||||
echo -e "${YELLOW}Local URLs:${NC}"
|
||||
echo " http://localhost:8000/bzzz/$RELEASE_CHANNEL/bzzz-linux-amd64"
|
||||
echo " http://localhost:8000/bzzz/$RELEASE_CHANNEL/bzzz.service"
|
||||
echo " http://localhost:8000/bzzz/$RELEASE_CHANNEL/install-service.sh"
|
||||
;;
|
||||
production)
|
||||
echo -e "${YELLOW}Production URLs:${NC}"
|
||||
echo " https://releases.chorus.services/bzzz/$RELEASE_CHANNEL/bzzz-linux-amd64"
|
||||
echo " https://releases.chorus.services/bzzz/$RELEASE_CHANNEL/bzzz.service"
|
||||
echo " https://releases.chorus.services/bzzz/$RELEASE_CHANNEL/install-service.sh"
|
||||
;;
|
||||
swarm)
|
||||
echo -e "${YELLOW}Swarm URLs:${NC}"
|
||||
echo " http://your-swarm-manager:8080/bzzz/$RELEASE_CHANNEL/bzzz-linux-amd64"
|
||||
;;
|
||||
esac
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--target)
|
||||
DEPLOYMENT_TARGET="$2"
|
||||
shift 2
|
||||
;;
|
||||
--channel)
|
||||
RELEASE_CHANNEL="$2"
|
||||
shift 2
|
||||
;;
|
||||
--help)
|
||||
echo "CHORUS Release Deployment Script"
|
||||
echo ""
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --target TARGET Deployment target: local, production, swarm (default: local)"
|
||||
echo " --channel CHANNEL Release channel (default: latest)"
|
||||
echo " --help Show this help"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 --target local"
|
||||
echo " $0 --target production --channel v1.0.0"
|
||||
echo " $0 --target swarm"
|
||||
echo ""
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Main deployment process
|
||||
main() {
|
||||
print_banner
|
||||
|
||||
check_builds
|
||||
|
||||
case $DEPLOYMENT_TARGET in
|
||||
local)
|
||||
deploy_local
|
||||
update_installer_urls
|
||||
;;
|
||||
production)
|
||||
deploy_production
|
||||
;;
|
||||
swarm)
|
||||
deploy_swarm
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown deployment target: $DEPLOYMENT_TARGET"
|
||||
log_info "Valid targets: local, production, swarm"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
show_summary
|
||||
}
|
||||
|
||||
main "$@"
|
||||
959
installer/install-chorus-enhanced.sh
Normal file
959
installer/install-chorus-enhanced.sh
Normal file
@@ -0,0 +1,959 @@
|
||||
#!/bin/bash
|
||||
|
||||
# CHORUS Distributed AI System Installer (Enhanced)
|
||||
# One-command installation script for the CHORUS cluster with repository configuration
|
||||
#
|
||||
# Usage:
|
||||
# curl -fsSL https://chorus.services/install.sh | sh
|
||||
#
|
||||
# Or with options:
|
||||
# curl -fsSL https://chorus.services/install.sh | sh -s -- --coordinator --models "llama3.2,qwen2.5:7b"
|
||||
|
||||
set -e
|
||||
|
||||
# Colors and formatting
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
PURPLE='\033[0;35m'
|
||||
CYAN='\033[0;36m'
|
||||
WHITE='\033[1;37m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# ASCII Art Banner
|
||||
print_banner() {
|
||||
echo -e "${PURPLE}"
|
||||
cat << 'EOF'
|
||||
██████╗██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
|
||||
██╔════╝██║ ██║██╔═══██╗██╔══██╗██║ ██║██╔════╝
|
||||
██║ ███████║██║ ██║██████╔╝██║ ██║███████╗
|
||||
██║ ██╔══██║██║ ██║██╔══██╗██║ ██║╚════██║
|
||||
╚██████╗██║ ██║╚██████╔╝██║ ██║╚██████╔╝███████║
|
||||
╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝
|
||||
|
||||
🎵 Distributed AI Orchestration Platform
|
||||
EOF
|
||||
echo -e "${NC}"
|
||||
echo -e "${CYAN} A living knowledge fabric for collaborative AI agents${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Configuration
|
||||
CHORUS_VERSION="latest"
|
||||
CHORUS_USER="$USER"
|
||||
CHORUS_HOME="$HOME/chorus"
|
||||
BZZZ_DIR="$CHORUS_HOME/project-queues/active/BZZZ"
|
||||
WHOOSH_DIR="$CHORUS_HOME/project-queues/active/WHOOSH"
|
||||
GITEA_URL="https://gitea.deepblack.cloud"
|
||||
REGISTRY_URL="registry.home.deepblack.cloud"
|
||||
|
||||
# Installation flags
|
||||
IS_COORDINATOR=false
|
||||
INSTALL_MODELS=""
|
||||
SKIP_DEPENDENCIES=false
|
||||
QUIET_MODE=false
|
||||
|
||||
# Repository configuration
|
||||
REPO_PROVIDER="gitea"
|
||||
REPO_BASE_URL="http://ironwood:3000"
|
||||
REPO_OWNER="tony"
|
||||
REPO_NAME="bzzz"
|
||||
REPO_TOKEN_FILE="$CHORUS_HOME/business/secrets/gitea-token"
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--coordinator)
|
||||
IS_COORDINATOR=true
|
||||
shift
|
||||
;;
|
||||
--models)
|
||||
INSTALL_MODELS="$2"
|
||||
shift 2
|
||||
;;
|
||||
--skip-deps)
|
||||
SKIP_DEPENDENCIES=true
|
||||
shift
|
||||
;;
|
||||
--quiet)
|
||||
QUIET_MODE=true
|
||||
shift
|
||||
;;
|
||||
--github)
|
||||
REPO_PROVIDER="github"
|
||||
shift
|
||||
;;
|
||||
--gitea-url)
|
||||
REPO_BASE_URL="$2"
|
||||
shift 2
|
||||
;;
|
||||
--help)
|
||||
echo "CHORUS Installation Script (Enhanced)"
|
||||
echo ""
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --coordinator Install as cluster coordinator node"
|
||||
echo " --models MODEL Comma-separated list of models to install"
|
||||
echo " --skip-deps Skip dependency installation"
|
||||
echo " --quiet Minimal output"
|
||||
echo " --github Use GitHub instead of GITEA"
|
||||
echo " --gitea-url URL Custom GITEA URL (default: http://ironwood:3000)"
|
||||
echo " --help Show this help"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 --coordinator --models \"llama3.2,qwen2.5:7b\""
|
||||
echo " $0 --github --models \"codellama:7b\""
|
||||
echo " $0 --gitea-url \"https://git.mycompany.com\""
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Logging functions
|
||||
log_info() {
|
||||
if [[ "$QUIET_MODE" != "true" ]]; then
|
||||
echo -e "${GREEN}✓${NC} $1"
|
||||
fi
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}⚠${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}✗${NC} $1"
|
||||
}
|
||||
|
||||
log_step() {
|
||||
if [[ "$QUIET_MODE" != "true" ]]; then
|
||||
echo -e "${BLUE}▶${NC} $1"
|
||||
fi
|
||||
}
|
||||
|
||||
# System detection
|
||||
detect_system() {
|
||||
log_step "Detecting system..."
|
||||
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
PACKAGE_MANAGER="apt"
|
||||
INSTALL_CMD="sudo apt-get update && sudo apt-get install -y"
|
||||
elif command -v yum >/dev/null 2>&1; then
|
||||
PACKAGE_MANAGER="yum"
|
||||
INSTALL_CMD="sudo yum install -y"
|
||||
elif command -v pacman >/dev/null 2>&1; then
|
||||
PACKAGE_MANAGER="pacman"
|
||||
INSTALL_CMD="sudo pacman -S --noconfirm"
|
||||
else
|
||||
log_error "Unsupported Linux distribution"
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
PACKAGE_MANAGER="brew"
|
||||
INSTALL_CMD="brew install"
|
||||
else
|
||||
log_error "Unsupported operating system: $OSTYPE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Detected system: $OSTYPE with $PACKAGE_MANAGER"
|
||||
}
|
||||
|
||||
# Check prerequisites
|
||||
check_prerequisites() {
|
||||
log_step "Checking prerequisites..."
|
||||
|
||||
local missing_deps=()
|
||||
|
||||
# Check for required commands
|
||||
for cmd in curl git jq; do
|
||||
if ! command -v $cmd >/dev/null 2>&1; then
|
||||
missing_deps+=($cmd)
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#missing_deps[@]} -gt 0 ]] && [[ "$SKIP_DEPENDENCIES" != "true" ]]; then
|
||||
log_step "Installing missing dependencies: ${missing_deps[*]}"
|
||||
case $PACKAGE_MANAGER in
|
||||
apt)
|
||||
$INSTALL_CMD ${missing_deps[*]}
|
||||
;;
|
||||
yum)
|
||||
$INSTALL_CMD ${missing_deps[*]}
|
||||
;;
|
||||
pacman)
|
||||
$INSTALL_CMD ${missing_deps[*]}
|
||||
;;
|
||||
brew)
|
||||
brew install ${missing_deps[*]}
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
log_info "Prerequisites satisfied"
|
||||
}
|
||||
|
||||
# Detect GITEA instance
|
||||
detect_gitea() {
|
||||
log_step "Detecting local GITEA instance..."
|
||||
|
||||
# Try different common GITEA endpoints
|
||||
local gitea_endpoints=(
|
||||
"http://ironwood:3000"
|
||||
"http://localhost:3000"
|
||||
"http://gitea.deepblack.cloud"
|
||||
"https://gitea.deepblack.cloud"
|
||||
)
|
||||
|
||||
for endpoint in "${gitea_endpoints[@]}"; do
|
||||
if curl -s --connect-timeout 5 "$endpoint/api/v1/version" >/dev/null 2>&1; then
|
||||
REPO_BASE_URL="$endpoint"
|
||||
log_info "Found GITEA instance at: $endpoint"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
log_warn "No GITEA instance detected, will use configured URL: $REPO_BASE_URL"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Setup repository credentials
|
||||
setup_repo_credentials() {
|
||||
log_step "Setting up repository credentials..."
|
||||
|
||||
# Create secrets directory
|
||||
mkdir -p "$CHORUS_HOME/business/secrets"
|
||||
|
||||
if [[ "$REPO_PROVIDER" == "gitea" ]]; then
|
||||
# Check if GITEA token exists
|
||||
if [[ ! -f "$REPO_TOKEN_FILE" ]]; then
|
||||
echo ""
|
||||
echo -e "${CYAN}GITEA Authentication Setup${NC}"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "To configure repository integration, BZZZ needs a GITEA access token."
|
||||
echo ""
|
||||
echo "Please create a token at: $REPO_BASE_URL/user/settings/applications"
|
||||
echo "Required permissions: read:repository, write:issue"
|
||||
echo ""
|
||||
read -s -p "Enter your GITEA access token: " gitea_token
|
||||
echo ""
|
||||
|
||||
if [[ -n "$gitea_token" ]]; then
|
||||
echo "$gitea_token" > "$REPO_TOKEN_FILE"
|
||||
chmod 600 "$REPO_TOKEN_FILE"
|
||||
log_info "GITEA token saved"
|
||||
else
|
||||
log_warn "No token provided - repository integration will be disabled"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_info "GITEA token already exists"
|
||||
fi
|
||||
else
|
||||
# GitHub setup
|
||||
local github_token_file="$CHORUS_HOME/business/secrets/gh-token"
|
||||
if [[ ! -f "$github_token_file" ]]; then
|
||||
echo ""
|
||||
echo -e "${CYAN}GitHub Authentication Setup${NC}"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "To configure repository integration, BZZZ needs a GitHub access token."
|
||||
echo ""
|
||||
echo "Please create a token at: https://github.com/settings/tokens"
|
||||
echo "Required permissions: repo, read:org"
|
||||
echo ""
|
||||
read -s -p "Enter your GitHub access token: " github_token
|
||||
echo ""
|
||||
|
||||
if [[ -n "$github_token" ]]; then
|
||||
echo "$github_token" > "$github_token_file"
|
||||
chmod 600 "$github_token_file"
|
||||
log_info "GitHub token saved"
|
||||
REPO_TOKEN_FILE="$github_token_file"
|
||||
else
|
||||
log_warn "No token provided - repository integration will be disabled"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_info "GitHub token already exists"
|
||||
REPO_TOKEN_FILE="$github_token_file"
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Configure repository integration
|
||||
configure_repositories() {
|
||||
log_step "Configuring repository integration..."
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}Repository Configuration${NC}"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
if [[ "$REPO_PROVIDER" == "gitea" ]]; then
|
||||
echo "Provider: GITEA"
|
||||
echo "Base URL: $REPO_BASE_URL"
|
||||
|
||||
read -p "Repository owner [$REPO_OWNER]: " repo_owner_input
|
||||
repo_owner_input=${repo_owner_input:-$REPO_OWNER}
|
||||
REPO_OWNER="$repo_owner_input"
|
||||
|
||||
read -p "Repository name [$REPO_NAME]: " repo_name_input
|
||||
repo_name_input=${repo_name_input:-$REPO_NAME}
|
||||
REPO_NAME="$repo_name_input"
|
||||
else
|
||||
echo "Provider: GitHub"
|
||||
echo "Base URL: https://api.github.com"
|
||||
|
||||
read -p "Repository owner: " repo_owner_input
|
||||
REPO_OWNER="$repo_owner_input"
|
||||
|
||||
read -p "Repository name: " repo_name_input
|
||||
REPO_NAME="$repo_name_input"
|
||||
fi
|
||||
|
||||
# Test repository access
|
||||
if test_repository_access; then
|
||||
log_info "Repository access verified: $REPO_OWNER/$REPO_NAME"
|
||||
else
|
||||
log_warn "Could not verify repository access - will continue with configuration"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Test repository access
|
||||
test_repository_access() {
|
||||
if [[ ! -f "$REPO_TOKEN_FILE" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
local token=$(cat "$REPO_TOKEN_FILE" | tr -d '\n')
|
||||
|
||||
if [[ "$REPO_PROVIDER" == "gitea" ]]; then
|
||||
local api_url="$REPO_BASE_URL/api/v1/repos/$REPO_OWNER/$REPO_NAME"
|
||||
if curl -s -H "Authorization: token $token" "$api_url" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
local api_url="https://api.github.com/repos/$REPO_OWNER/$REPO_NAME"
|
||||
if curl -s -H "Authorization: token $token" "$api_url" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Install Ollama
|
||||
install_ollama() {
|
||||
if command -v ollama >/dev/null 2>&1; then
|
||||
log_info "Ollama already installed"
|
||||
return
|
||||
fi
|
||||
|
||||
log_step "Installing Ollama..."
|
||||
curl -fsSL https://ollama.com/install.sh | sh
|
||||
|
||||
# Start Ollama service
|
||||
sudo systemctl enable ollama || true
|
||||
sudo systemctl start ollama || true
|
||||
|
||||
log_info "Ollama installed and started"
|
||||
}
|
||||
|
||||
# Setup CHORUS directory structure
|
||||
setup_chorus_structure() {
|
||||
log_step "Setting up CHORUS directory structure..."
|
||||
|
||||
mkdir -p "$CHORUS_HOME"/{docs,business/secrets,project-queues/active}
|
||||
mkdir -p "$HOME/.chorus"/{logs,config,cache}
|
||||
|
||||
log_info "Directory structure created"
|
||||
}
|
||||
|
||||
# Download CHORUS binaries
|
||||
download_binaries() {
|
||||
log_step "Downloading CHORUS binaries..."
|
||||
|
||||
# Create BZZZ directory structure
|
||||
mkdir -p "$BZZZ_DIR"/{config,logs}
|
||||
cd "$BZZZ_DIR"
|
||||
|
||||
# Detect system architecture
|
||||
local arch=""
|
||||
case $(uname -m) in
|
||||
x86_64) arch="amd64" ;;
|
||||
aarch64|arm64) arch="arm64" ;;
|
||||
armv7l) arch="armv7" ;;
|
||||
*)
|
||||
log_error "Unsupported architecture: $(uname -m)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
local os="linux"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
os="darwin"
|
||||
fi
|
||||
|
||||
# Download BZZZ binary
|
||||
local bzzz_url="https://chorus.services/releases/bzzz/latest/bzzz-${os}-${arch}"
|
||||
log_step "Downloading BZZZ binary for ${os}-${arch}..."
|
||||
|
||||
if curl -fsSL -o bzzz "$bzzz_url"; then
|
||||
chmod +x bzzz
|
||||
log_info "BZZZ binary downloaded successfully"
|
||||
else
|
||||
log_error "Failed to download BZZZ binary from $bzzz_url"
|
||||
log_info "Falling back to minimal installation..."
|
||||
# Create a placeholder binary that will be updated later
|
||||
echo '#!/bin/bash' > bzzz
|
||||
echo 'echo "BZZZ binary not available for this platform"' >> bzzz
|
||||
chmod +x bzzz
|
||||
fi
|
||||
|
||||
# Download systemd service file
|
||||
local service_url="https://chorus.services/releases/bzzz/latest/bzzz.service"
|
||||
if curl -fsSL -o bzzz.service "$service_url"; then
|
||||
log_info "BZZZ service file downloaded"
|
||||
else
|
||||
log_warn "Failed to download service file, creating default..."
|
||||
create_default_service_file
|
||||
fi
|
||||
|
||||
# Download install script
|
||||
local install_script_url="https://chorus.services/releases/bzzz/latest/install-service.sh"
|
||||
if curl -fsSL -o install-service.sh "$install_script_url"; then
|
||||
chmod +x install-service.sh
|
||||
log_info "Install script downloaded"
|
||||
else
|
||||
log_warn "Failed to download install script, creating default..."
|
||||
create_default_install_script
|
||||
fi
|
||||
|
||||
log_info "Binary downloads completed"
|
||||
}
|
||||
|
||||
# Create default service file
|
||||
create_default_service_file() {
|
||||
cat > bzzz.service << 'EOF'
|
||||
[Unit]
|
||||
Description=BZZZ P2P Task Coordination System
|
||||
Documentation=https://chorus.services/docs/bzzz
|
||||
After=network.target
|
||||
Wants=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=PLACEHOLDER_USER
|
||||
Group=PLACEHOLDER_USER
|
||||
WorkingDirectory=PLACEHOLDER_BZZZ_DIR
|
||||
ExecStart=PLACEHOLDER_BZZZ_DIR/bzzz --config PLACEHOLDER_BZZZ_DIR/config/bzzz.yaml
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
KillMode=mixed
|
||||
KillSignal=SIGTERM
|
||||
TimeoutStopSec=30
|
||||
|
||||
# Environment variables
|
||||
Environment=HOME=PLACEHOLDER_HOME
|
||||
Environment=USER=PLACEHOLDER_USER
|
||||
|
||||
# Logging
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=bzzz
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=false
|
||||
ReadWritePaths=PLACEHOLDER_BZZZ_DIR
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65536
|
||||
LimitNPROC=4096
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Replace placeholders
|
||||
sed -i "s|PLACEHOLDER_USER|$USER|g" bzzz.service
|
||||
sed -i "s|PLACEHOLDER_HOME|$HOME|g" bzzz.service
|
||||
sed -i "s|PLACEHOLDER_BZZZ_DIR|$BZZZ_DIR|g" bzzz.service
|
||||
|
||||
log_info "Default service file created"
|
||||
}
|
||||
|
||||
# Create default install script
|
||||
create_default_install_script() {
|
||||
cat > install-service.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
# BZZZ Service Installation Script
|
||||
# Installs BZZZ as a systemd service
|
||||
|
||||
set -e
|
||||
|
||||
echo "🐝 Installing BZZZ P2P Task Coordination Service..."
|
||||
|
||||
# Check if running as root or with sudo
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "❌ This script must be run as root or with sudo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Define paths
|
||||
BZZZ_DIR="$(pwd)"
|
||||
SERVICE_FILE="$BZZZ_DIR/bzzz.service"
|
||||
SYSTEMD_DIR="/etc/systemd/system"
|
||||
|
||||
# Check if BZZZ binary exists
|
||||
if [ ! -f "$BZZZ_DIR/bzzz" ]; then
|
||||
echo "❌ BZZZ binary not found at $BZZZ_DIR/bzzz"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make binary executable
|
||||
chmod +x "$BZZZ_DIR/bzzz"
|
||||
echo "✅ Made BZZZ binary executable"
|
||||
|
||||
# Copy service file to systemd directory
|
||||
cp "$SERVICE_FILE" "$SYSTEMD_DIR/bzzz.service"
|
||||
echo "✅ Copied service file to $SYSTEMD_DIR/bzzz.service"
|
||||
|
||||
# Set proper permissions
|
||||
chmod 644 "$SYSTEMD_DIR/bzzz.service"
|
||||
echo "✅ Set service file permissions"
|
||||
|
||||
# Reload systemd daemon
|
||||
systemctl daemon-reload
|
||||
echo "✅ Reloaded systemd daemon"
|
||||
|
||||
# Enable service to start on boot
|
||||
systemctl enable bzzz.service
|
||||
echo "✅ Enabled BZZZ service for auto-start"
|
||||
|
||||
# Start the service
|
||||
systemctl start bzzz.service
|
||||
echo "✅ Started BZZZ service"
|
||||
|
||||
echo ""
|
||||
echo "🎉 BZZZ P2P Task Coordination Service installed successfully!"
|
||||
EOF
|
||||
|
||||
chmod +x install-service.sh
|
||||
log_info "Default install script created"
|
||||
}
|
||||
|
||||
# Configure BZZZ with repository integration
|
||||
configure_bzzz() {
|
||||
log_step "Configuring BZZZ with repository integration..."
|
||||
|
||||
# Interactive configuration
|
||||
echo ""
|
||||
echo -e "${CYAN}BZZZ Node Configuration${NC}"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
read -p "Node hostname [$(hostname)]: " node_hostname
|
||||
node_hostname=${node_hostname:-$(hostname)}
|
||||
|
||||
read -p "Node role [worker]: " node_role
|
||||
node_role=${node_role:-worker}
|
||||
|
||||
if [[ "$IS_COORDINATOR" == "true" ]]; then
|
||||
node_role="coordinator"
|
||||
echo "Setting role to coordinator (--coordinator flag provided)"
|
||||
fi
|
||||
|
||||
read -p "API port [8080]: " api_port
|
||||
api_port=${api_port:-8080}
|
||||
|
||||
read -p "Health port [8081]: " health_port
|
||||
health_port=${health_port:-8081}
|
||||
|
||||
read -p "P2P port [4001]: " p2p_port
|
||||
p2p_port=${p2p_port:-4001}
|
||||
|
||||
# Generate YAML configuration with repository integration
|
||||
cat > "$BZZZ_DIR/config/bzzz.yaml" << EOF
|
||||
# BZZZ Configuration - Auto-generated by CHORUS installer
|
||||
node:
|
||||
id: "$node_hostname"
|
||||
role: "$node_role"
|
||||
|
||||
# API Configuration
|
||||
api:
|
||||
host: "0.0.0.0"
|
||||
port: $api_port
|
||||
|
||||
# Health Monitoring
|
||||
health:
|
||||
port: $health_port
|
||||
enabled: true
|
||||
|
||||
# P2P Networking
|
||||
p2p:
|
||||
port: $p2p_port
|
||||
discovery:
|
||||
enabled: true
|
||||
bootstrap_nodes: []
|
||||
service_tag: "bzzz-peer-discovery"
|
||||
topics:
|
||||
bzzz: "bzzz/coordination/v1"
|
||||
hmmm: "hmmm/meta-discussion/v1"
|
||||
|
||||
# Agent Configuration
|
||||
agent:
|
||||
id: "$node_hostname-agent"
|
||||
capabilities: ["general", "reasoning", "task-coordination"]
|
||||
poll_interval: "30s"
|
||||
max_tasks: 3
|
||||
specialization: "general_developer"
|
||||
role: "Full Stack Engineer"
|
||||
expertise: ["golang", "typescript", "docker", "kubernetes"]
|
||||
|
||||
# Repository Configuration
|
||||
repository:
|
||||
provider: "$REPO_PROVIDER"
|
||||
config:
|
||||
base_url: "$REPO_BASE_URL"
|
||||
owner: "$REPO_OWNER"
|
||||
repository: "$REPO_NAME"
|
||||
task_label: "bzzz-task"
|
||||
in_progress_label: "bzzz-working"
|
||||
completed_label: "bzzz-completed"
|
||||
priority_label: "bzzz-priority"
|
||||
assignee: "$USER"
|
||||
base_branch: "main"
|
||||
branch_prefix: "bzzz/task-"
|
||||
EOF
|
||||
|
||||
# Add token file path if it exists
|
||||
if [[ -f "$REPO_TOKEN_FILE" ]]; then
|
||||
cat >> "$BZZZ_DIR/config/bzzz.yaml" << EOF
|
||||
token_file: "$REPO_TOKEN_FILE"
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Continue with rest of configuration
|
||||
cat >> "$BZZZ_DIR/config/bzzz.yaml" << EOF
|
||||
|
||||
# GitHub/GITEA Integration (Legacy support)
|
||||
github:
|
||||
token_file: "$REPO_TOKEN_FILE"
|
||||
user_agent: "BZZZ-P2P-Agent/2.0"
|
||||
timeout: "30s"
|
||||
rate_limit: true
|
||||
assignee: "$USER"
|
||||
|
||||
# Logging Configuration
|
||||
logging:
|
||||
level: "info"
|
||||
format: "text"
|
||||
output: "stdout"
|
||||
structured: false
|
||||
file: "$HOME/.chorus/logs/bzzz.log"
|
||||
|
||||
# Storage Configuration
|
||||
storage:
|
||||
path: "$HOME/.chorus/data"
|
||||
type: "filesystem"
|
||||
|
||||
# Coordinator Settings
|
||||
coordinator: $([ "$IS_COORDINATOR" == "true" ] && echo "true" || echo "false")
|
||||
|
||||
# SLURP Configuration (AI Intelligence System)
|
||||
slurp:
|
||||
enabled: true
|
||||
base_url: "http://localhost:8082"
|
||||
intelligence:
|
||||
enabled: true
|
||||
context_window: 4096
|
||||
reasoning_depth: 3
|
||||
storage:
|
||||
type: "filesystem"
|
||||
directory: "$HOME/.chorus/slurp-storage"
|
||||
|
||||
# Security Configuration
|
||||
security:
|
||||
admin_key_shares:
|
||||
threshold: 3
|
||||
total_shares: 5
|
||||
election_config:
|
||||
heartbeat_timeout: "5s"
|
||||
discovery_timeout: "30s"
|
||||
election_timeout: "15s"
|
||||
minimum_quorum: 3
|
||||
key_rotation_days: 90
|
||||
audit_logging: true
|
||||
audit_path: "$HOME/.chorus/security-audit.log"
|
||||
|
||||
# UCXL Protocol (Unified Content Exchange Layer)
|
||||
ucxl:
|
||||
enabled: false
|
||||
server:
|
||||
port: 8081
|
||||
base_path: "/bzzz"
|
||||
enabled: true
|
||||
|
||||
# V2 Protocol Features
|
||||
v2:
|
||||
enabled: false
|
||||
protocol_version: "2.0.0"
|
||||
dht:
|
||||
enabled: false
|
||||
mode: "auto"
|
||||
protocol_prefix: "/bzzz"
|
||||
auto_bootstrap: false
|
||||
EOF
|
||||
|
||||
log_info "BZZZ configured with repository integration"
|
||||
|
||||
# Display configuration summary
|
||||
echo ""
|
||||
echo -e "${WHITE}Configuration Summary:${NC}"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " Node: $node_hostname ($node_role)"
|
||||
echo " API: http://localhost:$api_port"
|
||||
echo " Health: http://localhost:$health_port/health"
|
||||
echo " Repository: $REPO_PROVIDER - $REPO_OWNER/$REPO_NAME"
|
||||
echo " Config: $BZZZ_DIR/config/bzzz.yaml"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Install BZZZ service
|
||||
install_bzzz_service() {
|
||||
log_step "Installing BZZZ as systemd service..."
|
||||
|
||||
cd "$BZZZ_DIR"
|
||||
|
||||
# Check if BZZZ binary exists
|
||||
if [[ ! -f "bzzz" ]]; then
|
||||
log_error "BZZZ binary not found - cannot install service"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if install script exists
|
||||
if [[ ! -f "install-service.sh" ]]; then
|
||||
log_error "install-service.sh not found - cannot install service"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Make sure install script is executable
|
||||
chmod +x install-service.sh
|
||||
|
||||
# Install the service
|
||||
if sudo ./install-service.sh; then
|
||||
log_info "BZZZ service installed and started"
|
||||
return 0
|
||||
else
|
||||
log_error "Failed to install BZZZ service"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Install AI models
|
||||
install_models() {
|
||||
if [[ -z "$INSTALL_MODELS" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
log_step "Installing AI models..."
|
||||
|
||||
IFS=',' read -ra MODELS <<< "$INSTALL_MODELS"
|
||||
for model in "${MODELS[@]}"; do
|
||||
model=$(echo "$model" | xargs) # trim whitespace
|
||||
log_step "Pulling model: $model"
|
||||
ollama pull "$model"
|
||||
log_info "Model $model installed"
|
||||
done
|
||||
}
|
||||
|
||||
# Setup coordinator-specific components
|
||||
setup_coordinator() {
|
||||
if [[ "$IS_COORDINATOR" != "true" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
log_step "Setting up coordinator components..."
|
||||
|
||||
# Install Docker for WHOOSH
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
sudo usermod -aG docker "$USER"
|
||||
log_info "Docker installed"
|
||||
fi
|
||||
|
||||
# Generate Age encryption keys
|
||||
if ! command -v age >/dev/null 2>&1; then
|
||||
# Install age
|
||||
wget -O /tmp/age.tar.gz https://github.com/FiloSottile/age/releases/download/v1.1.1/age-v1.1.1-linux-amd64.tar.gz
|
||||
tar -xzf /tmp/age.tar.gz -C /tmp
|
||||
sudo cp /tmp/age/age* /usr/local/bin/
|
||||
sudo chmod +x /usr/local/bin/age*
|
||||
rm -rf /tmp/age*
|
||||
fi
|
||||
|
||||
# Generate keys
|
||||
mkdir -p "$CHORUS_HOME/business/secrets"
|
||||
age-keygen -o "$CHORUS_HOME/business/secrets/age-key.txt"
|
||||
|
||||
log_info "Coordinator setup completed"
|
||||
}
|
||||
|
||||
# Verify installation
|
||||
verify_installation() {
|
||||
log_step "Verifying installation..."
|
||||
|
||||
local issues=()
|
||||
|
||||
# Check BZZZ service
|
||||
if ! systemctl is-active bzzz >/dev/null 2>&1; then
|
||||
issues+=("BZZZ service not running")
|
||||
fi
|
||||
|
||||
# Check configuration file
|
||||
if [[ ! -f "$BZZZ_DIR/config/bzzz.yaml" ]]; then
|
||||
issues+=("BZZZ configuration missing")
|
||||
fi
|
||||
|
||||
# Check repository access
|
||||
if [[ -f "$REPO_TOKEN_FILE" ]] && ! test_repository_access; then
|
||||
issues+=("Repository access verification failed")
|
||||
fi
|
||||
|
||||
# Check Ollama
|
||||
if ! systemctl is-active ollama >/dev/null 2>&1; then
|
||||
issues+=("Ollama service not running")
|
||||
fi
|
||||
|
||||
if [[ ${#issues[@]} -eq 0 ]]; then
|
||||
log_info "Installation verification passed"
|
||||
return 0
|
||||
else
|
||||
log_warn "Installation issues detected:"
|
||||
for issue in "${issues[@]}"; do
|
||||
echo " • $issue"
|
||||
done
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Show completion message
|
||||
show_completion() {
|
||||
echo ""
|
||||
echo -e "${GREEN}🎉 CHORUS Installation Complete!${NC}"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo -e "${WHITE}Services Status:${NC}"
|
||||
local bzzz_status=$(systemctl is-active bzzz 2>/dev/null || echo 'inactive')
|
||||
echo " • BZZZ Agent: $bzzz_status"
|
||||
echo " • Ollama: $(systemctl is-active ollama 2>/dev/null || echo 'inactive')"
|
||||
echo " • Repository: $REPO_PROVIDER ($REPO_OWNER/$REPO_NAME)"
|
||||
|
||||
if [[ "$bzzz_status" == "active" ]]; then
|
||||
echo ""
|
||||
echo -e "${WHITE}API Endpoints:${NC}"
|
||||
echo " • Health: http://localhost:8081/health"
|
||||
echo " • API: http://localhost:8080"
|
||||
echo " • Metrics: http://localhost:8081/metrics"
|
||||
else
|
||||
echo ""
|
||||
echo -e "${YELLOW}⚠ BZZZ Service Issues:${NC}"
|
||||
echo " The BZZZ service may not be running."
|
||||
echo " This could be due to configuration or binary compatibility issues."
|
||||
echo ""
|
||||
echo -e "${WHITE}Troubleshooting:${NC}"
|
||||
echo " 1. Check logs: sudo journalctl -u bzzz -f"
|
||||
echo " 2. Test binary: $BZZZ_DIR/bzzz --version"
|
||||
echo " 3. Restart service: sudo systemctl restart bzzz"
|
||||
echo " 4. Check config: $BZZZ_DIR/config/bzzz.yaml"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${WHITE}Useful Commands:${NC}"
|
||||
echo " sudo systemctl status bzzz - Check BZZZ status"
|
||||
echo " sudo journalctl -u bzzz -f - Follow BZZZ logs"
|
||||
echo " ollama list - List installed models"
|
||||
echo " curl http://localhost:8081/health - Test BZZZ health"
|
||||
echo ""
|
||||
|
||||
if [[ "$IS_COORDINATOR" == "true" ]]; then
|
||||
echo -e "${WHITE}Coordinator Setup:${NC}"
|
||||
echo " • Age encryption keys: $CHORUS_HOME/business/secrets/age-key.txt"
|
||||
echo " • Repository integration: $REPO_PROVIDER"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo -e "${WHITE}Repository Integration:${NC}"
|
||||
echo " • Provider: $REPO_PROVIDER"
|
||||
echo " • Repository: $REPO_OWNER/$REPO_NAME"
|
||||
echo " • Token file: $REPO_TOKEN_FILE"
|
||||
echo " • Task label: bzzz-task"
|
||||
echo ""
|
||||
|
||||
echo -e "${WHITE}Documentation:${NC}"
|
||||
echo " • CHORUS Docs: $CHORUS_HOME/docs/"
|
||||
echo " • BZZZ Config: $BZZZ_DIR/config/bzzz.yaml"
|
||||
echo ""
|
||||
echo -e "${CYAN}Next Steps:${NC}"
|
||||
echo " 1. Create an issue in $REPO_OWNER/$REPO_NAME with label 'bzzz-task'"
|
||||
echo " 2. BZZZ will automatically detect and claim the task"
|
||||
echo " 3. Monitor progress: sudo journalctl -u bzzz -f"
|
||||
|
||||
if [[ "$IS_COORDINATOR" == "true" ]]; then
|
||||
echo " 4. Add worker nodes by running this script on other machines"
|
||||
echo " 5. Monitor cluster: curl http://localhost:8081/health"
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Error handling
|
||||
cleanup_on_error() {
|
||||
log_error "Installation failed. Cleaning up..."
|
||||
# Cleanup logic here
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Main installation flow
|
||||
main() {
|
||||
print_banner
|
||||
|
||||
echo -e "${WHITE}Starting CHORUS installation with repository integration...${NC}"
|
||||
echo ""
|
||||
|
||||
detect_system
|
||||
check_prerequisites
|
||||
|
||||
if [[ "$REPO_PROVIDER" == "gitea" ]]; then
|
||||
detect_gitea
|
||||
fi
|
||||
|
||||
setup_chorus_structure
|
||||
setup_repo_credentials
|
||||
configure_repositories
|
||||
|
||||
install_ollama
|
||||
download_binaries
|
||||
configure_bzzz
|
||||
install_bzzz_service
|
||||
|
||||
install_models
|
||||
setup_coordinator
|
||||
|
||||
verify_installation
|
||||
show_completion
|
||||
}
|
||||
|
||||
# Run main installation
|
||||
main "$@"
|
||||
625
installer/install-chorus.sh
Executable file
625
installer/install-chorus.sh
Executable file
@@ -0,0 +1,625 @@
|
||||
#!/bin/bash
|
||||
|
||||
# CHORUS Distributed AI System Installer
|
||||
# One-command installation script for the CHORUS cluster
|
||||
#
|
||||
# Usage:
|
||||
# curl -fsSL https://chorus.services/install.sh | sh
|
||||
#
|
||||
# Or with options:
|
||||
# curl -fsSL https://chorus.services/install.sh | sh -s -- --coordinator --models "llama3.2,qwen2.5:7b"
|
||||
|
||||
set -e
|
||||
|
||||
# Colors and formatting
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
PURPLE='\033[0;35m'
|
||||
CYAN='\033[0;36m'
|
||||
WHITE='\033[1;37m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# ASCII Art Banner
|
||||
print_banner() {
|
||||
echo -e "${PURPLE}"
|
||||
cat << 'EOF'
|
||||
██████╗██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
|
||||
██╔════╝██║ ██║██╔═══██╗██╔══██╗██║ ██║██╔════╝
|
||||
██║ ███████║██║ ██║██████╔╝██║ ██║███████╗
|
||||
██║ ██╔══██║██║ ██║██╔══██╗██║ ██║╚════██║
|
||||
╚██████╗██║ ██║╚██████╔╝██║ ██║╚██████╔╝███████║
|
||||
╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝
|
||||
|
||||
🎵 Distributed AI Orchestration Platform
|
||||
EOF
|
||||
echo -e "${NC}"
|
||||
echo -e "${CYAN} A living knowledge fabric for collaborative AI agents${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Configuration
|
||||
CHORUS_VERSION="latest"
|
||||
CHORUS_USER="$USER"
|
||||
CHORUS_HOME="$HOME/chorus"
|
||||
BZZZ_DIR="$CHORUS_HOME/project-queues/active/BZZZ"
|
||||
WHOOSH_DIR="$CHORUS_HOME/project-queues/active/WHOOSH"
|
||||
GITEA_URL="https://gitea.deepblack.cloud"
|
||||
REGISTRY_URL="registry.home.deepblack.cloud"
|
||||
|
||||
# Installation flags
|
||||
IS_COORDINATOR=false
|
||||
INSTALL_MODELS=""
|
||||
SKIP_DEPENDENCIES=false
|
||||
QUIET_MODE=false
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--coordinator)
|
||||
IS_COORDINATOR=true
|
||||
shift
|
||||
;;
|
||||
--models)
|
||||
INSTALL_MODELS="$2"
|
||||
shift 2
|
||||
;;
|
||||
--skip-deps)
|
||||
SKIP_DEPENDENCIES=true
|
||||
shift
|
||||
;;
|
||||
--quiet)
|
||||
QUIET_MODE=true
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
echo "CHORUS Installation Script"
|
||||
echo ""
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --coordinator Install as cluster coordinator node"
|
||||
echo " --models MODEL Comma-separated list of models to install"
|
||||
echo " --skip-deps Skip dependency installation"
|
||||
echo " --quiet Minimal output"
|
||||
echo " --help Show this help"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 --coordinator --models \"llama3.2,qwen2.5:7b\""
|
||||
echo " $0 --models \"codellama:7b\""
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Logging functions
|
||||
log_info() {
|
||||
if [[ "$QUIET_MODE" != "true" ]]; then
|
||||
echo -e "${GREEN}✓${NC} $1"
|
||||
fi
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}⚠${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}✗${NC} $1"
|
||||
}
|
||||
|
||||
log_step() {
|
||||
if [[ "$QUIET_MODE" != "true" ]]; then
|
||||
echo -e "${BLUE}▶${NC} $1"
|
||||
fi
|
||||
}
|
||||
|
||||
# System detection
|
||||
detect_system() {
|
||||
log_step "Detecting system..."
|
||||
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
PACKAGE_MANAGER="apt"
|
||||
INSTALL_CMD="sudo apt-get update && sudo apt-get install -y"
|
||||
elif command -v yum >/dev/null 2>&1; then
|
||||
PACKAGE_MANAGER="yum"
|
||||
INSTALL_CMD="sudo yum install -y"
|
||||
elif command -v pacman >/dev/null 2>&1; then
|
||||
PACKAGE_MANAGER="pacman"
|
||||
INSTALL_CMD="sudo pacman -S --noconfirm"
|
||||
else
|
||||
log_error "Unsupported Linux distribution"
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
PACKAGE_MANAGER="brew"
|
||||
INSTALL_CMD="brew install"
|
||||
else
|
||||
log_error "Unsupported operating system: $OSTYPE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Detected system: $OSTYPE with $PACKAGE_MANAGER"
|
||||
}
|
||||
|
||||
# Check prerequisites
|
||||
check_prerequisites() {
|
||||
log_step "Checking prerequisites..."
|
||||
|
||||
local missing_deps=()
|
||||
|
||||
# Check for required commands
|
||||
for cmd in curl git; do
|
||||
if ! command -v $cmd >/dev/null 2>&1; then
|
||||
missing_deps+=($cmd)
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#missing_deps[@]} -gt 0 ]] && [[ "$SKIP_DEPENDENCIES" != "true" ]]; then
|
||||
log_step "Installing missing dependencies: ${missing_deps[*]}"
|
||||
case $PACKAGE_MANAGER in
|
||||
apt)
|
||||
$INSTALL_CMD ${missing_deps[*]}
|
||||
;;
|
||||
yum)
|
||||
$INSTALL_CMD ${missing_deps[*]}
|
||||
;;
|
||||
pacman)
|
||||
$INSTALL_CMD ${missing_deps[*]}
|
||||
;;
|
||||
brew)
|
||||
brew install ${missing_deps[*]}
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
log_info "Prerequisites satisfied"
|
||||
}
|
||||
|
||||
|
||||
# Install Ollama
|
||||
install_ollama() {
|
||||
if command -v ollama >/dev/null 2>&1; then
|
||||
log_info "Ollama already installed"
|
||||
return
|
||||
fi
|
||||
|
||||
log_step "Installing Ollama..."
|
||||
curl -fsSL https://ollama.com/install.sh | sh
|
||||
|
||||
# Start Ollama service
|
||||
sudo systemctl enable ollama || true
|
||||
sudo systemctl start ollama || true
|
||||
|
||||
log_info "Ollama installed and started"
|
||||
}
|
||||
|
||||
# Setup CHORUS directory structure
|
||||
setup_chorus_structure() {
|
||||
log_step "Setting up CHORUS directory structure..."
|
||||
|
||||
mkdir -p "$CHORUS_HOME"/{docs,business/secrets,project-queues/active}
|
||||
mkdir -p "$HOME/.chorus"/{logs,config,cache}
|
||||
|
||||
log_info "Directory structure created"
|
||||
}
|
||||
|
||||
# Download CHORUS binaries
|
||||
download_binaries() {
|
||||
log_step "Downloading CHORUS binaries..."
|
||||
|
||||
# Create BZZZ directory structure
|
||||
mkdir -p "$BZZZ_DIR"/{config,logs}
|
||||
cd "$BZZZ_DIR"
|
||||
|
||||
# Detect system architecture
|
||||
local arch=""
|
||||
case $(uname -m) in
|
||||
x86_64) arch="amd64" ;;
|
||||
aarch64|arm64) arch="arm64" ;;
|
||||
armv7l) arch="armv7" ;;
|
||||
*)
|
||||
log_error "Unsupported architecture: $(uname -m)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
local os="linux"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
os="darwin"
|
||||
fi
|
||||
|
||||
# Download BZZZ binary
|
||||
local bzzz_url="https://chorus.services/releases/bzzz/latest/bzzz-${os}-${arch}"
|
||||
log_step "Downloading BZZZ binary for ${os}-${arch}..."
|
||||
|
||||
if curl -fsSL -o bzzz "$bzzz_url"; then
|
||||
chmod +x bzzz
|
||||
log_info "BZZZ binary downloaded successfully"
|
||||
else
|
||||
log_error "Failed to download BZZZ binary from $bzzz_url"
|
||||
log_info "Falling back to minimal installation..."
|
||||
# Create a placeholder binary that will be updated later
|
||||
echo '#!/bin/bash' > bzzz
|
||||
echo 'echo "BZZZ binary not available for this platform"' >> bzzz
|
||||
chmod +x bzzz
|
||||
fi
|
||||
|
||||
# Download systemd service file
|
||||
local service_url="https://chorus.services/releases/bzzz/latest/bzzz.service"
|
||||
if curl -fsSL -o bzzz.service "$service_url"; then
|
||||
log_info "BZZZ service file downloaded"
|
||||
else
|
||||
log_warn "Failed to download service file, creating default..."
|
||||
create_default_service_file
|
||||
fi
|
||||
|
||||
# Download install script
|
||||
local install_script_url="https://chorus.services/releases/bzzz/latest/install-service.sh"
|
||||
if curl -fsSL -o install-service.sh "$install_script_url"; then
|
||||
chmod +x install-service.sh
|
||||
log_info "Install script downloaded"
|
||||
else
|
||||
log_warn "Failed to download install script, creating default..."
|
||||
create_default_install_script
|
||||
fi
|
||||
|
||||
# Download WHOOSH if coordinator
|
||||
if [[ "$IS_COORDINATOR" == "true" ]]; then
|
||||
log_step "Downloading WHOOSH dashboard..."
|
||||
mkdir -p "$WHOOSH_DIR"
|
||||
|
||||
local whoosh_url="https://chorus.services/releases/whoosh/latest/whoosh-docker-compose.tar.gz"
|
||||
if curl -fsSL "$whoosh_url" | tar -xzf - -C "$WHOOSH_DIR" 2>/dev/null; then
|
||||
log_info "WHOOSH dashboard downloaded"
|
||||
else
|
||||
log_warn "Failed to download WHOOSH dashboard"
|
||||
fi
|
||||
fi
|
||||
|
||||
log_info "Binary downloads completed"
|
||||
}
|
||||
|
||||
# Create default service file
|
||||
create_default_service_file() {
|
||||
cat > bzzz.service << 'EOF'
|
||||
[Unit]
|
||||
Description=BZZZ P2P Task Coordination System
|
||||
Documentation=https://chorus.services/docs/bzzz
|
||||
After=network.target
|
||||
Wants=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=PLACEHOLDER_USER
|
||||
Group=PLACEHOLDER_USER
|
||||
WorkingDirectory=PLACEHOLDER_BZZZ_DIR
|
||||
ExecStart=PLACEHOLDER_BZZZ_DIR/bzzz
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
KillMode=mixed
|
||||
KillSignal=SIGTERM
|
||||
TimeoutStopSec=30
|
||||
|
||||
# Environment variables
|
||||
Environment=HOME=PLACEHOLDER_HOME
|
||||
Environment=USER=PLACEHOLDER_USER
|
||||
|
||||
# Logging
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=bzzz
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=false
|
||||
ReadWritePaths=PLACEHOLDER_BZZZ_DIR
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65536
|
||||
LimitNPROC=4096
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Replace placeholders
|
||||
sed -i "s|PLACEHOLDER_USER|$USER|g" bzzz.service
|
||||
sed -i "s|PLACEHOLDER_HOME|$HOME|g" bzzz.service
|
||||
sed -i "s|PLACEHOLDER_BZZZ_DIR|$BZZZ_DIR|g" bzzz.service
|
||||
|
||||
log_info "Default service file created"
|
||||
}
|
||||
|
||||
# Create default install script
|
||||
create_default_install_script() {
|
||||
cat > install-service.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
# BZZZ Service Installation Script
|
||||
# Installs BZZZ as a systemd service
|
||||
|
||||
set -e
|
||||
|
||||
echo "🐝 Installing BZZZ P2P Task Coordination Service..."
|
||||
|
||||
# Check if running as root or with sudo
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "❌ This script must be run as root or with sudo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Define paths
|
||||
BZZZ_DIR="$(pwd)"
|
||||
SERVICE_FILE="$BZZZ_DIR/bzzz.service"
|
||||
SYSTEMD_DIR="/etc/systemd/system"
|
||||
|
||||
# Check if BZZZ binary exists
|
||||
if [ ! -f "$BZZZ_DIR/bzzz" ]; then
|
||||
echo "❌ BZZZ binary not found at $BZZZ_DIR/bzzz"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make binary executable
|
||||
chmod +x "$BZZZ_DIR/bzzz"
|
||||
echo "✅ Made BZZZ binary executable"
|
||||
|
||||
# Copy service file to systemd directory
|
||||
cp "$SERVICE_FILE" "$SYSTEMD_DIR/bzzz.service"
|
||||
echo "✅ Copied service file to $SYSTEMD_DIR/bzzz.service"
|
||||
|
||||
# Set proper permissions
|
||||
chmod 644 "$SYSTEMD_DIR/bzzz.service"
|
||||
echo "✅ Set service file permissions"
|
||||
|
||||
# Reload systemd daemon
|
||||
systemctl daemon-reload
|
||||
echo "✅ Reloaded systemd daemon"
|
||||
|
||||
# Enable service to start on boot
|
||||
systemctl enable bzzz.service
|
||||
echo "✅ Enabled BZZZ service for auto-start"
|
||||
|
||||
# Start the service
|
||||
systemctl start bzzz.service
|
||||
echo "✅ Started BZZZ service"
|
||||
|
||||
echo ""
|
||||
echo "🎉 BZZZ P2P Task Coordination Service installed successfully!"
|
||||
EOF
|
||||
|
||||
chmod +x install-service.sh
|
||||
log_info "Default install script created"
|
||||
}
|
||||
|
||||
# Configure BZZZ
|
||||
configure_bzzz() {
|
||||
log_step "Configuring BZZZ..."
|
||||
|
||||
# Interactive configuration
|
||||
echo ""
|
||||
echo -e "${CYAN}BZZZ Node Configuration${NC}"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
read -p "Node hostname [$(hostname)]: " node_hostname
|
||||
node_hostname=${node_hostname:-$(hostname)}
|
||||
|
||||
read -p "Node role [worker]: " node_role
|
||||
node_role=${node_role:-worker}
|
||||
|
||||
if [[ "$IS_COORDINATOR" == "true" ]]; then
|
||||
node_role="coordinator"
|
||||
echo "Setting role to coordinator (--coordinator flag provided)"
|
||||
fi
|
||||
|
||||
read -p "API port [8080]: " api_port
|
||||
api_port=${api_port:-8080}
|
||||
|
||||
read -p "P2P port [4001]: " p2p_port
|
||||
p2p_port=${p2p_port:-4001}
|
||||
|
||||
# Generate configuration
|
||||
cat > "$BZZZ_DIR/config/bzzz.json" << EOF
|
||||
{
|
||||
"node": {
|
||||
"id": "$node_hostname",
|
||||
"role": "$node_role"
|
||||
},
|
||||
"api": {
|
||||
"host": "0.0.0.0",
|
||||
"port": $api_port
|
||||
},
|
||||
"p2p": {
|
||||
"port": $p2p_port,
|
||||
"discovery": {
|
||||
"enabled": true,
|
||||
"bootstrap_nodes": []
|
||||
}
|
||||
},
|
||||
"coordinator": $([ "$IS_COORDINATOR" == "true" ] && echo "true" || echo "false"),
|
||||
"logging": {
|
||||
"level": "info",
|
||||
"file": "$HOME/.chorus/logs/bzzz.log"
|
||||
},
|
||||
"storage": {
|
||||
"path": "$HOME/.chorus/data"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
log_info "BZZZ configured"
|
||||
}
|
||||
|
||||
# Install BZZZ service
|
||||
install_bzzz_service() {
|
||||
log_step "Installing BZZZ as systemd service..."
|
||||
|
||||
cd "$BZZZ_DIR"
|
||||
|
||||
# Check if BZZZ binary exists
|
||||
if [[ ! -f "bzzz" ]]; then
|
||||
log_error "BZZZ binary not found - cannot install service"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if install script exists
|
||||
if [[ ! -f "install-service.sh" ]]; then
|
||||
log_error "install-service.sh not found - cannot install service"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Make sure install script is executable
|
||||
chmod +x install-service.sh
|
||||
|
||||
# Install the service
|
||||
if sudo ./install-service.sh; then
|
||||
log_info "BZZZ service installed and started"
|
||||
return 0
|
||||
else
|
||||
log_error "Failed to install BZZZ service"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Install AI models
|
||||
install_models() {
|
||||
if [[ -z "$INSTALL_MODELS" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
log_step "Installing AI models..."
|
||||
|
||||
IFS=',' read -ra MODELS <<< "$INSTALL_MODELS"
|
||||
for model in "${MODELS[@]}"; do
|
||||
model=$(echo "$model" | xargs) # trim whitespace
|
||||
log_step "Pulling model: $model"
|
||||
ollama pull "$model"
|
||||
log_info "Model $model installed"
|
||||
done
|
||||
}
|
||||
|
||||
# Setup coordinator-specific components
|
||||
setup_coordinator() {
|
||||
if [[ "$IS_COORDINATOR" != "true" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
log_step "Setting up coordinator components..."
|
||||
|
||||
# Install Docker for WHOOSH
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
sudo usermod -aG docker "$USER"
|
||||
log_info "Docker installed"
|
||||
fi
|
||||
|
||||
# Generate Age encryption keys
|
||||
if ! command -v age >/dev/null 2>&1; then
|
||||
# Install age
|
||||
wget -O /tmp/age.tar.gz https://github.com/FiloSottile/age/releases/download/v1.1.1/age-v1.1.1-linux-amd64.tar.gz
|
||||
tar -xzf /tmp/age.tar.gz -C /tmp
|
||||
sudo cp /tmp/age/age* /usr/local/bin/
|
||||
sudo chmod +x /usr/local/bin/age*
|
||||
rm -rf /tmp/age*
|
||||
fi
|
||||
|
||||
# Generate keys
|
||||
mkdir -p "$CHORUS_HOME/business/secrets"
|
||||
age-keygen -o "$CHORUS_HOME/business/secrets/age-key.txt"
|
||||
|
||||
log_info "Coordinator setup completed"
|
||||
}
|
||||
|
||||
# Show completion message
|
||||
show_completion() {
|
||||
echo ""
|
||||
echo -e "${GREEN}🎉 CHORUS Installation Complete!${NC}"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo -e "${WHITE}Services Status:${NC}"
|
||||
local bzzz_status=$(systemctl is-active bzzz 2>/dev/null || echo 'inactive')
|
||||
echo " • BZZZ Agent: $bzzz_status"
|
||||
echo " • Ollama: $(systemctl is-active ollama 2>/dev/null || echo 'inactive')"
|
||||
|
||||
if [[ "$bzzz_status" == "inactive" ]]; then
|
||||
echo ""
|
||||
echo -e "${YELLOW}⚠ BZZZ Service Issues:${NC}"
|
||||
echo " The BZZZ service may not be running."
|
||||
echo " This could be due to configuration or binary compatibility issues."
|
||||
echo ""
|
||||
echo -e "${WHITE}Troubleshooting:${NC}"
|
||||
echo " 1. Check logs: sudo journalctl -u bzzz -f"
|
||||
echo " 2. Test binary: $BZZZ_DIR/bzzz --version"
|
||||
echo " 3. Restart service: sudo systemctl restart bzzz"
|
||||
echo " 4. Check config: $BZZZ_DIR/config/bzzz.json"
|
||||
fi
|
||||
echo ""
|
||||
echo -e "${WHITE}Useful Commands:${NC}"
|
||||
echo " sudo systemctl status bzzz - Check BZZZ status"
|
||||
echo " sudo journalctl -u bzzz -f - Follow BZZZ logs"
|
||||
echo " ollama list - List installed models"
|
||||
echo " curl http://localhost:8080/health - Test BZZZ API"
|
||||
echo ""
|
||||
if [[ "$IS_COORDINATOR" == "true" ]]; then
|
||||
echo -e "${WHITE}Coordinator Setup:${NC}"
|
||||
echo " • Age encryption keys: $CHORUS_HOME/business/secrets/age-key.txt"
|
||||
echo " • WHOOSH dashboard will be available after Docker deployment"
|
||||
echo ""
|
||||
fi
|
||||
echo -e "${WHITE}Documentation:${NC}"
|
||||
echo " • CHORUS Docs: $CHORUS_HOME/docs/"
|
||||
echo " • BZZZ Config: $BZZZ_DIR/config/bzzz.json"
|
||||
echo ""
|
||||
echo -e "${CYAN}Next Steps:${NC}"
|
||||
if [[ "$IS_COORDINATOR" == "true" ]]; then
|
||||
echo " 1. Deploy WHOOSH dashboard: cd $WHOOSH_DIR && docker-compose up -d"
|
||||
echo " 2. Access dashboard at: http://$(hostname):3001"
|
||||
echo " 3. Add worker nodes by running this script on other machines"
|
||||
else
|
||||
echo " 1. Configure coordinator endpoint in BZZZ config"
|
||||
echo " 2. Restart BZZZ: sudo systemctl restart bzzz"
|
||||
echo " 3. Check connection: curl http://localhost:8080/health"
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Error handling
|
||||
cleanup_on_error() {
|
||||
log_error "Installation failed. Cleaning up..."
|
||||
# Cleanup logic here
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Disable strict error handling for controlled failure management
|
||||
set +e
|
||||
|
||||
# Main installation flow
|
||||
main() {
|
||||
print_banner
|
||||
|
||||
echo -e "${WHITE}Starting CHORUS installation...${NC}"
|
||||
echo ""
|
||||
|
||||
detect_system
|
||||
check_prerequisites
|
||||
install_ollama
|
||||
setup_chorus_structure
|
||||
download_binaries
|
||||
configure_bzzz
|
||||
install_bzzz_service
|
||||
|
||||
install_models
|
||||
setup_coordinator
|
||||
|
||||
show_completion
|
||||
}
|
||||
|
||||
# Run main installation
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user