#!/bin/bash # OpenClaw DevMatrix Environment Setup - ROBUST VERSION # Run this INSIDE the Ubuntu VM (ID: 300) after OS installation # This script verifies, checks, installs, and reports status set -e # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' log() { echo -e "${GREEN}[DevMatrix]${NC} $1"; } warn() { echo -e "${YELLOW}[Warning]${NC} $1"; } error() { echo -e "${RED}[Error]${NC} $1"; } info() { echo -e "${CYAN}[Info]${NC} $1"; } # Status tracking declare -A STATUS STATUS[total]=0 STATUS[success]=0 STATUS[failed]=0 STATUS[skipped]=0 log() { echo -e "${GREEN}[DevMatrix]${NC} $1" ((STATUS[total]++)) } success() { echo -e "${GREEN}[✓]${NC} $1" ((STATUS[success]++)) } fail() { echo -e "${RED}[✗]${NC} $1" ((STATUS[failed]++)) } skip() { echo -e "${YELLOW}[→]${NC} $1" ((STATUS[skipped]++)) } # Don't exit on error set +e log "🚀 Starting DevMatrix Environment Setup (Robust Mode)..." log "This script will verify, install, and report status." echo "" # ============================================ # SYSTEM UPDATE # ============================================ log "📦 Checking system update..." if [ -f /var/lib/apt/periodic/update-success-stamp ] && [ $(($(date +%s) - $(stat -c %Y /var/lib/apt/periodic/update-success-stamp))) -lt 86400 ]; then skip "System recently updated" else sudo apt update && sudo apt upgrade -y if [ $? -eq 0 ]; then success "System updated" else fail "System update failed (continuing...)" fi fi # ============================================ # BASE PACKAGES # ============================================ log "📦 Checking base packages..." PACKAGES="curl wget git git-lfs build-essential software-properties-common apt-transport-https ca-certificates gnupg lsb-release unzip zip jq htop tree vim nano tmux sshpass python3-full python3-pip python3-venv" missing_packages="" for pkg in $PACKAGES; do if ! dpkg -l | grep -q "^ii $pkg "; then missing_packages="$missing_packages $pkg" fi done if [ -n "$missing_packages" ]; then sudo apt install -y $missing_packages if [ $? -eq 0 ]; then success "Installed missing packages" else fail "Some packages failed to install" fi else skip "All base packages already installed" fi # ============================================ # OPENCLAW # ============================================ log "🦞 Checking OpenClaw..." if command -v openclaw &> /dev/null; then skip "OpenClaw already installed" openclaw --version 2>/dev/null | head -1 else # Try to install OpenClaw curl -fsSL https://openclaw.dev/install.sh | bash 2>/dev/null # Add to PATH if [ -d "$HOME/.openclaw/bin" ]; then export PATH="$HOME/.openclaw/bin:$PATH" echo 'export PATH="$HOME/.openclaw/bin:$PATH"' >> ~/.bashrc fi # Verify if command -v openclaw &> /dev/null; then success "OpenClaw installed" openclaw --version 2>/dev/null | head -1 else fail "OpenClaw installation failed" warn "You may need to install manually later" fi fi # ============================================ # NODE.JS # ============================================ log "📦 Checking Node.js..." if command -v node &> /dev/null && node --version | grep -q "v20"; then skip "Node.js 20 already installed" else curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt install -y nodejs if command -v node &> /dev/null; then success "Node.js installed: $(node --version)" else fail "Node.js installation failed" fi fi # ============================================ # PYTHON TOOLS (via pipx to avoid system issues) # ============================================ log "📦 Checking Python tools..." if ! command -v pipx &> /dev/null; then sudo apt install -y pipx pipx ensurepath fi PYTHON_TOOLS="pipenv poetry black flake8 mypy pylint" for tool in $PYTHON_TOOLS; do if pipx list | grep -q "$tool"; then skip "$tool already installed" else pipx install $tool 2>/dev/null if [ $? -eq 0 ]; then success "$tool installed via pipx" else fail "$tool installation failed" fi fi done # ============================================ # DOCKER # ============================================ log "🐳 Checking Docker..." if command -v docker &> /dev/null && docker --version &> /dev/null; then skip "Docker already installed: $(docker --version | cut -d' ' -f3 | tr -d ',')" # Ensure Docker is running if ! sudo systemctl is-active --quiet docker; then sudo systemctl start docker sudo systemctl enable docker fi else sudo apt install -y docker.io docker-compose-plugin sudo usermod -aG docker $USER sudo systemctl enable --now docker if command -v docker &> /dev/null; then success "Docker installed" else fail "Docker installation failed" fi fi # ============================================ # HOMELAB TOOLS (Docker) # ============================================ log "🚀 Installing DevMatrix homelab tools..." # Create Docker network sudo docker network create devmatrix 2>/dev/null if [ $? -eq 0 ]; then success "Docker network 'devmatrix' created" else skip "Docker network 'devmatrix' already exists" fi mkdir -p ~/homelab/{portainer,uptime-kuma,heimdall,n8n,vaultwarden} # Portainer log " Checking Portainer..." if sudo docker ps | grep -q "portainer-devmatrix"; then skip "Portainer already running" else sudo docker run -d --name portainer-devmatrix --restart=always -p 9000:9000 \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_devmatrix_data:/data \ portainer/portainer-ce:latest 2>/dev/null if [ $? -eq 0 ]; then success "Portainer installed (http://$(hostname -I | awk '{print $1}'):9000)" else fail "Portainer installation failed" fi fi # n8n log " Checking n8n..." if sudo docker ps | grep -q "n8n"; then skip "n8n already running" else sudo docker run -d --name n8n --restart=always -p 5678:5678 \ -v ~/homelab/n8n:/home/node/.n8n \ -e GENERIC_TIMEZONE="Europe/Stockholm" \ n8nio/n8n:latest 2>/dev/null if [ $? -eq 0 ]; then success "n8n installed (http://$(hostname -I | awk '{print $1}'):5678)" else fail "n8n installation failed" fi fi # Uptime Kuma log " Checking Uptime Kuma..." if sudo docker ps | grep -q "uptime-kuma"; then skip "Uptime Kuma already running" else sudo docker run -d --name uptime-kuma --restart=always -p 3001:3001 \ -v ~/homelab/uptime-kuma:/app/data \ louislam/uptime-kuma:latest 2>/dev/null if [ $? -eq 0 ]; then success "Uptime Kuma installed (http://$(hostname -I | awk '{print $1}'):3001)" else fail "Uptime Kuma installation failed" fi fi # Heimdall log " Checking Heimdall..." if sudo docker ps | grep -q "heimdall"; then skip "Heimdall already running" else sudo docker run -d --name heimdall --restart=always -p 8081:80 \ -v ~/homelab/heimdall:/config \ linuxserver/heimdall:latest 2>/dev/null if [ $? -eq 0 ]; then success "Heimdall installed (http://$(hostname -I | awk '{print $1}'):8081)" else fail "Heimdall installation failed" fi fi # Vaultwarden log " Checking Vaultwarden..." if sudo docker ps | grep -q "vaultwarden"; then skip "Vaultwarden already running" else sudo docker run -d --name vaultwarden --restart=always -p 8082:80 \ -v ~/homelab/vaultwarden:/data \ vaultwarden/server:latest 2>/dev/null if [ $? -eq 0 ]; then success "Vaultwarden installed (http://$(hostname -I | awk '{print $1}'):8082)" else fail "Vaultwarden installation failed" fi fi # ============================================ # BASH ALIASES # ============================================ log "📝 Setting up bash aliases..." if ! grep -q "devmatrix-status" ~/.bashrc; then cat >> ~/.bashrc << 'EOF' # DevMatrix Aliases alias devmatrix-status='~/scripts/vm_control.sh win-status 2>/dev/null || echo "VM control not set up"' alias devmatrix-win-start='~/scripts/vm_control.sh win-start 2>/dev/null || echo "VM control not set up"' alias devmatrix-win-stop='~/scripts/vm_control.sh win-stop 2>/dev/null || echo "VM control not set up"' alias oc='openclaw 2>/dev/null || echo "OpenClaw not installed"' # DevMatrix Homelab Aliases alias portainer='echo "http://$(hostname -I | awk '"'"'{print $1}'"'"'):9000"' alias n8n='echo "http://$(hostname -I | awk '"'"'{print $1}'"'"'):5678"' alias uptime='echo "http://$(hostname -I | awk '"'"'{print $1}'"'"'):3001"' alias dashboard='echo "http://$(hostname -I | awk '"'"'{print $1}'"'"'):8081"' alias vault='echo "http://$(hostname -I | awk '"'"'{print $1}'"'"'):8082"' # Add paths export PATH="$HOME/.local/bin:$HOME/.openclaw/bin:$PATH" # Welcome message echo "" echo "🦞 DevMatrix Environment" echo "========================" echo "📊 Portainer: http://$(hostname -I | awk '{print $1}'):9000" echo "🔄 n8n: http://$(hostname -I | awk '{print $1}'):5678" echo "📈 Uptime Kuma: http://$(hostname -I | awk '{print $1}'):3001" echo "🗂️ Dashboard: http://$(hostname -I | awk '{print $1}'):8081" echo "🔐 Vaultwarden: http://$(hostname -I | awk '{print $1}'):8082" echo "" EOF success "Bash aliases added" else skip "Bash aliases already configured" fi # ============================================ # STATUS REPORT # ============================================ echo "" echo "╔════════════════════════════════════════════════════════════╗" echo "║ DEVMATRIX SETUP STATUS REPORT ║" echo "╠════════════════════════════════════════════════════════════╣" printf "║ Total Checks/Installations: %-3d ║\n" ${STATUS[total]} printf "║ ✓ Successful: %-3d ║\n" ${STATUS[success]} printf "║ ✗ Failed: %-3d ║\n" ${STATUS[failed]} printf "║ → Skipped (already done): %-3d ║\n" ${STATUS[skipped]} echo "╠════════════════════════════════════════════════════════════╣" echo "║ ║" echo "║ ACCESS YOUR SERVICES: ║" echo "║ ║" echo "║ 📊 Portainer: http://$(hostname -I | awk '{print $1}'):9000 ║" echo "║ 🔄 n8n: http://$(hostname -I | awk '{print $1}'):5678 ║" echo "║ 📈 Uptime Kuma: http://$(hostname -I | awk '{print $1}'):3001 ║" echo "║ 🗂️ Dashboard: http://$(hostname -I | awk '{print $1}'):8081 ║" echo "║ 🔐 Vaultwarden: http://$(hostname -I | awk '{print $1}'):8082 ║" echo "║ ║" echo "╠════════════════════════════════════════════════════════════╣" if [ ${STATUS[failed]} -gt 0 ]; then echo "║ ⚠️ SOME INSTALLATIONS FAILED ║" echo "║ Review the output above for details ║" echo "║ You can re-run this script to retry failed items ║" fi echo "║ ║" echo "║ NEXT STEPS: ║" if ! command -v openclaw &> /dev/null; then echo "║ 1. Install OpenClaw manually if needed ║" fi echo "║ 2. Configure API keys: ~/scripts/configure_api_keys.sh ║" echo "║ 3. Mount TrueNAS shares: ~/scripts/setup_truenas.sh ║" echo "║ 4. Reload shell: source ~/.bashrc ║" echo "║ ║" echo "╚════════════════════════════════════════════════════════════╝" echo ""