343 lines
13 KiB
Bash
Executable File
343 lines
13 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# provisioning/bootstrap/install.sh
|
|
# Bootstrap script for provisioning platform (POSIX Bash + Nushell)
|
|
# Pure Bash implementation to avoid Nushell IR mode limitations
|
|
|
|
set -e
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
# Configuration
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
WORKSPACE_NAME="workspace_librecloud"
|
|
WORKSPACE_PATH="$PROJECT_ROOT/$WORKSPACE_NAME"
|
|
|
|
# Helper functions
|
|
print_header() {
|
|
echo -e "${GREEN}╔════════════════════════════════════════════════════════════════╗${NC}"
|
|
echo -e "${GREEN}║ PROVISIONING BOOTSTRAP (Bash) ║${NC}"
|
|
echo -e "${GREEN}╚════════════════════════════════════════════════════════════════╝${NC}"
|
|
}
|
|
|
|
print_stage() {
|
|
local stage="$1"
|
|
local description="$2"
|
|
echo ""
|
|
echo "$stage $description"
|
|
echo "─────────────────────────────────────────────────────────────────"
|
|
}
|
|
|
|
print_success() {
|
|
echo " ✅ $1"
|
|
}
|
|
|
|
print_warning() {
|
|
echo " ⚠️ $1"
|
|
}
|
|
|
|
print_error() {
|
|
echo " ❌ $1"
|
|
}
|
|
|
|
check_command() {
|
|
command -v "$1" &> /dev/null
|
|
}
|
|
|
|
# Main bootstrap logic
|
|
|
|
print_header
|
|
echo ""
|
|
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
# STAGE 1: SYSTEM DETECTION
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
|
|
print_stage "📊" "Stage 1: System Detection"
|
|
|
|
OS=$(uname -s)
|
|
ARCH=$(uname -m)
|
|
CPU_COUNT=$(sysctl -n hw.physicalcpu 2>/dev/null || nproc 2>/dev/null || echo "unknown")
|
|
|
|
# Get RAM in GB
|
|
if [[ "$OS" == "Darwin" ]]; then
|
|
MEM_GB=$(($(sysctl -n hw.memsize) / 1024 / 1024 / 1024))
|
|
else
|
|
MEM_GB=$(($(grep MemTotal /proc/meminfo | awk '{print $2}') / 1024 / 1024))
|
|
fi
|
|
|
|
echo " OS: $OS"
|
|
echo " Architecture: $ARCH"
|
|
echo " CPU Cores: $CPU_COUNT"
|
|
echo " Memory: ${MEM_GB} GB"
|
|
|
|
# Validate minimum requirements
|
|
MIN_RAM=2
|
|
if [[ $MEM_GB -lt $MIN_RAM ]]; then
|
|
print_error "Requires at least $MIN_RAM GB RAM (have $MEM_GB GB)"
|
|
exit 1
|
|
fi
|
|
|
|
print_success "System requirements met"
|
|
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
# STAGE 2: DEPENDENCY CHECK
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
|
|
print_stage "📦" "Stage 2: Checking Dependencies"
|
|
|
|
REQUIRED_TOOLS=("git" "docker" "rustc" "cargo" "nu")
|
|
MISSING_TOOLS=()
|
|
|
|
for tool in "${REQUIRED_TOOLS[@]}"; do
|
|
if ! check_command "$tool"; then
|
|
MISSING_TOOLS+=("$tool")
|
|
fi
|
|
done
|
|
|
|
if [[ ${#MISSING_TOOLS[@]} -gt 0 ]]; then
|
|
print_warning "Missing tools:"
|
|
for tool in "${MISSING_TOOLS[@]}"; do
|
|
echo " - $tool"
|
|
done
|
|
|
|
if [[ " ${MISSING_TOOLS[*]} " =~ " docker " ]]; then
|
|
echo ""
|
|
echo " 📥 Docker is required. Install from: https://docs.docker.com/get-docker/"
|
|
fi
|
|
|
|
if [[ " ${MISSING_TOOLS[*]} " =~ " rustc " ]]; then
|
|
echo ""
|
|
echo " 📥 Rust is required. Install from: https://rustup.rs/"
|
|
echo " Then run: rustup default stable"
|
|
fi
|
|
|
|
echo ""
|
|
print_error "Please install missing dependencies and run again"
|
|
exit 1
|
|
fi
|
|
|
|
print_success "All dependencies found"
|
|
|
|
# Show versions
|
|
echo ""
|
|
echo " Versions:"
|
|
echo " Docker: $(docker --version)"
|
|
echo " Rust: $(rustc --version)"
|
|
echo " Nushell: $(nu --version)"
|
|
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
# STAGE 3: INSTALL TYPEDIALOG (Configuration Forms & Tools)
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
|
|
print_stage "🎨" "Stage 3: Installing TypeDialog (Forms & Tools)"
|
|
|
|
TYPEDIALOG_INSTALLER="$PROJECT_ROOT/provisioning/scripts/install-typedialog.sh"
|
|
|
|
# Check if TypeDialog is already installed
|
|
if check_command "typedialog"; then
|
|
TYPEDIALOG_VERSION=$(typedialog --version 2>/dev/null | head -1)
|
|
print_success "TypeDialog already installed ($TYPEDIALOG_VERSION)"
|
|
else
|
|
print_warning "TypeDialog not found - installing..."
|
|
|
|
if [[ ! -f "$TYPEDIALOG_INSTALLER" ]]; then
|
|
print_error "TypeDialog installer not found at $TYPEDIALOG_INSTALLER"
|
|
exit 1
|
|
fi
|
|
|
|
# Install TypeDialog with all components (backends + tools)
|
|
if bash "$TYPEDIALOG_INSTALLER" --components all --skip-validation; then
|
|
print_success "TypeDialog installed successfully"
|
|
|
|
# Verify installation
|
|
if check_command "typedialog"; then
|
|
TYPEDIALOG_VERSION=$(typedialog --version 2>/dev/null | head -1)
|
|
echo " Installed: $TYPEDIALOG_VERSION"
|
|
fi
|
|
else
|
|
print_error "Failed to install TypeDialog"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
# STAGE 4: CREATE DIRECTORY STRUCTURE
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
|
|
print_stage "📁" "Stage 4: Creating Directory Structure"
|
|
|
|
mkdir -p "$WORKSPACE_PATH/config/generated/providers"
|
|
mkdir -p "$WORKSPACE_PATH/config/generated/platform"
|
|
mkdir -p "$WORKSPACE_PATH/.orchestrator/data/queue"
|
|
mkdir -p "$WORKSPACE_PATH/.kms"
|
|
mkdir -p "$WORKSPACE_PATH/.providers"
|
|
mkdir -p "$WORKSPACE_PATH/.taskservs"
|
|
mkdir -p "$WORKSPACE_PATH/.clusters"
|
|
|
|
print_success "Directory structure created"
|
|
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
# STAGE 5: VALIDATE CONFIGURATION
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
|
|
print_stage "⚙️ " "Stage 5: Validating Configuration"
|
|
|
|
CONFIG_NCL="$WORKSPACE_PATH/config/config.ncl"
|
|
|
|
if [[ ! -f "$CONFIG_NCL" ]]; then
|
|
print_warning "config.ncl not found at $CONFIG_NCL"
|
|
echo " Creating default config..."
|
|
|
|
TEMPLATE="$PROJECT_ROOT/workspace_librecloud/config/config.ncl"
|
|
if [[ -f "$TEMPLATE" ]]; then
|
|
cp "$TEMPLATE" "$CONFIG_NCL"
|
|
print_success "Copied from template"
|
|
else
|
|
print_error "Cannot find config template"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Validate Nickel syntax
|
|
if ! nickel typecheck "$CONFIG_NCL" > /dev/null 2>&1; then
|
|
print_error "Nickel configuration validation failed"
|
|
nickel typecheck "$CONFIG_NCL"
|
|
exit 1
|
|
fi
|
|
|
|
print_success "Configuration syntax valid"
|
|
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
# STAGE 6: EXPORT CONFIGURATION
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
|
|
print_stage "📤" "Stage 6: Exporting Configuration to TOML"
|
|
|
|
cd "$PROJECT_ROOT"
|
|
|
|
# Use Nushell for config export (IT requires module imports)
|
|
if nu -c "
|
|
use provisioning/core/nulib/lib_provisioning/config/export.nu *
|
|
export-all-configs '$WORKSPACE_PATH'
|
|
" 2>/dev/null; then
|
|
print_success "Configuration exported"
|
|
else
|
|
print_warning "Configuration export encountered issues (may continue)"
|
|
fi
|
|
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
# STAGE 7: INITIALIZE ORCHESTRATOR
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
|
|
print_stage "🚀" "Stage 7: Initializing Orchestrator Service"
|
|
|
|
ORCHESTRATOR_PATH="$PROJECT_ROOT/provisioning/platform/orchestrator"
|
|
|
|
if [[ -d "$ORCHESTRATOR_PATH" ]]; then
|
|
echo " Starting orchestrator service in background..."
|
|
|
|
if cd "$ORCHESTRATOR_PATH" && \
|
|
./scripts/start-orchestrator.nu --background \
|
|
--provisioning-path "$PROJECT_ROOT/provisioning/core/cli/provisioning" 2>/dev/null; then
|
|
print_success "Orchestrator started"
|
|
echo " 📝 Check logs: tail -f $ORCHESTRATOR_PATH/data/orchestrator.log"
|
|
else
|
|
print_warning "Orchestrator may not have started (check logs)"
|
|
fi
|
|
else
|
|
print_warning "Orchestrator not found at $ORCHESTRATOR_PATH"
|
|
fi
|
|
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
# STAGE 8: VERIFY INSTALLATION
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
|
|
print_stage "✅" "Stage 8: Verification"
|
|
|
|
FILES_CHECK=(
|
|
"config/generated/workspace.toml"
|
|
"config/generated/providers/upcloud.toml"
|
|
"config/generated/platform/orchestrator.toml"
|
|
)
|
|
|
|
MISSING_FILES=()
|
|
for file in "${FILES_CHECK[@]}"; do
|
|
if [[ ! -f "$WORKSPACE_PATH/$file" ]]; then
|
|
MISSING_FILES+=("$file")
|
|
fi
|
|
done
|
|
|
|
if [[ ${#MISSING_FILES[@]} -gt 0 ]]; then
|
|
print_warning "Missing generated files:"
|
|
for file in "${MISSING_FILES[@]}"; do
|
|
echo " - $file"
|
|
done
|
|
else
|
|
print_success "All configuration files generated"
|
|
fi
|
|
|
|
DIRECTORIES_CHECK=(
|
|
".orchestrator/data/queue"
|
|
".kms"
|
|
".providers"
|
|
".taskservs"
|
|
".clusters"
|
|
)
|
|
|
|
ALL_DIRS_EXIST=true
|
|
for dir in "${DIRECTORIES_CHECK[@]}"; do
|
|
if [[ ! -d "$WORKSPACE_PATH/$dir" ]]; then
|
|
ALL_DIRS_EXIST=false
|
|
break
|
|
fi
|
|
done
|
|
|
|
if $ALL_DIRS_EXIST; then
|
|
print_success "All required directories created"
|
|
else
|
|
print_warning "Some directories missing"
|
|
fi
|
|
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
# FINAL STATUS
|
|
# ════════════════════════════════════════════════════════════════════════
|
|
|
|
echo ""
|
|
echo -e "${GREEN}╔════════════════════════════════════════════════════════════════╗${NC}"
|
|
echo -e "${GREEN}║ BOOTSTRAP COMPLETE ✅ ║${NC}"
|
|
echo -e "${GREEN}╚════════════════════════════════════════════════════════════════╝${NC}"
|
|
echo ""
|
|
|
|
echo "📍 Next Steps:"
|
|
echo ""
|
|
echo "1. Verify TypeDialog is available:"
|
|
echo " typedialog --version && typedialog-web --version"
|
|
echo ""
|
|
echo "2. Configure platform services:"
|
|
echo " $PROJECT_ROOT/provisioning/scripts/setup-platform-config.sh"
|
|
echo ""
|
|
echo "3. Verify configuration:"
|
|
echo " cat $WORKSPACE_PATH/config/config.ncl"
|
|
echo ""
|
|
echo "4. Check orchestrator is running:"
|
|
echo " curl http://localhost:9090/health"
|
|
echo ""
|
|
echo "5. Start provisioning:"
|
|
echo " provisioning server create --infra sgoyol --name web-01"
|
|
echo ""
|
|
echo "6. Monitor workflow:"
|
|
echo " provisioning workflow monitor <workflow_id>"
|
|
echo ""
|
|
echo "📚 Documentation:"
|
|
echo " - TypeDialog Forms: $PROJECT_ROOT/provisioning/.typedialog/platform/README.md"
|
|
echo " - Setup Guide: $PROJECT_ROOT/provisioning/scripts/setup-platform-config.sh --help"
|
|
echo " - User Guide: docs/user/TYPEDIALOG_PLATFORM_CONFIG_GUIDE.md"
|
|
echo " - Architecture: ARCHITECTURE_CLARIFICATION.md"
|
|
echo " - Workflow: PROVISIONING_WORKFLOW.md"
|
|
echo ""
|