mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 17:31:09 -05:00
- Add complete backend/ directory with full Django application - Add frontend/ directory with Vite + TypeScript setup ready for Next.js - Add comprehensive shared/ directory with: - Complete documentation and memory-bank archives - Media files and avatars (letters, park/ride images) - Deployment scripts and automation tools - Shared types and utilities - Add architecture/ directory with migration guides - Configure pnpm workspace for monorepo development - Update .gitignore to exclude .django_tailwind_cli/ build artifacts - Preserve all historical documentation in shared/docs/memory-bank/ - Set up proper structure for full-stack development with shared resources
1109 lines
34 KiB
Bash
Executable File
1109 lines
34 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# ThrillWiki Complete Unraid Automation Setup
|
|
# This script automates the entire VM creation and deployment process on Unraid
|
|
#
|
|
# Usage:
|
|
# ./setup-complete-automation.sh # Standard setup
|
|
# ./setup-complete-automation.sh --reset # Delete VM and config, start completely fresh
|
|
# ./setup-complete-automation.sh --reset-vm # Delete VM only, keep configuration
|
|
# ./setup-complete-automation.sh --reset-config # Delete config only, keep VM
|
|
|
|
# Function to show help
|
|
show_help() {
|
|
echo "ThrillWiki CI/CD Automation Setup"
|
|
echo ""
|
|
echo "Usage:"
|
|
echo " $0 Set up or update ThrillWiki automation"
|
|
echo " $0 -y Non-interactive mode, use saved configuration"
|
|
echo " $0 --reset Delete VM and config, start completely fresh"
|
|
echo " $0 --reset-vm Delete VM only, keep configuration"
|
|
echo " $0 --reset-config Delete config only, keep VM"
|
|
echo " $0 --help Show this help message"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " -y, --yes Non-interactive mode - use saved configuration"
|
|
echo " and passwords without prompting. Requires existing"
|
|
echo " configuration file with saved settings."
|
|
echo ""
|
|
echo "Reset Options:"
|
|
echo " --reset Completely removes existing VM, disks, and config"
|
|
echo " before starting fresh installation"
|
|
echo " --reset-vm Removes only the VM and disks, preserves saved"
|
|
echo " configuration to avoid re-entering settings"
|
|
echo " --reset-config Removes only the saved configuration, preserves"
|
|
echo " VM and prompts for fresh configuration input"
|
|
echo " --help Display this help and exit"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " $0 # Normal setup/update"
|
|
echo " $0 -y # Non-interactive setup with saved config"
|
|
echo " $0 --reset # Complete fresh installation"
|
|
echo " $0 --reset-vm # Fresh VM with saved settings"
|
|
echo " $0 --reset-config # Re-configure existing VM"
|
|
exit 0
|
|
}
|
|
|
|
# Check for help flag
|
|
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
|
|
show_help
|
|
fi
|
|
|
|
# Parse command line flags
|
|
RESET_ALL=false
|
|
RESET_VM_ONLY=false
|
|
RESET_CONFIG_ONLY=false
|
|
NON_INTERACTIVE=false
|
|
|
|
# Process all arguments
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
-y|--yes)
|
|
NON_INTERACTIVE=true
|
|
echo "🤖 NON-INTERACTIVE MODE: Using saved configuration only"
|
|
shift
|
|
;;
|
|
--reset)
|
|
RESET_ALL=true
|
|
echo "🔄 COMPLETE RESET MODE: Will delete VM and configuration"
|
|
shift
|
|
;;
|
|
--reset-vm)
|
|
RESET_VM_ONLY=true
|
|
echo "🔄 VM RESET MODE: Will delete VM only, keep configuration"
|
|
shift
|
|
;;
|
|
--reset-config)
|
|
RESET_CONFIG_ONLY=true
|
|
echo "🔄 CONFIG RESET MODE: Will delete configuration only, keep VM"
|
|
shift
|
|
;;
|
|
--help|-h)
|
|
show_help
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1"
|
|
show_help
|
|
;;
|
|
esac
|
|
done
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
log() {
|
|
echo -e "${BLUE}[AUTOMATION]${NC} $1"
|
|
}
|
|
|
|
log_success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
log_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
# Configuration
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
LOG_DIR="$PROJECT_DIR/logs"
|
|
|
|
# Default values
|
|
DEFAULT_UNRAID_HOST=""
|
|
DEFAULT_VM_NAME="thrillwiki-vm"
|
|
DEFAULT_VM_MEMORY="4096"
|
|
DEFAULT_VM_VCPUS="2"
|
|
DEFAULT_VM_DISK_SIZE="50"
|
|
DEFAULT_WEBHOOK_PORT="9000"
|
|
|
|
# Configuration file
|
|
CONFIG_FILE="$PROJECT_DIR/.thrillwiki-config"
|
|
|
|
# Function to save configuration
|
|
save_config() {
|
|
log "Saving configuration to $CONFIG_FILE..."
|
|
cat > "$CONFIG_FILE" << EOF
|
|
# ThrillWiki Automation Configuration
|
|
# This file stores your settings to avoid re-entering them each time
|
|
|
|
# Unraid Server Configuration
|
|
UNRAID_HOST="$UNRAID_HOST"
|
|
UNRAID_USER="$UNRAID_USER"
|
|
VM_NAME="$VM_NAME"
|
|
VM_MEMORY="$VM_MEMORY"
|
|
VM_VCPUS="$VM_VCPUS"
|
|
VM_DISK_SIZE="$VM_DISK_SIZE"
|
|
|
|
# Network Configuration
|
|
VM_IP="$VM_IP"
|
|
VM_GATEWAY="$VM_GATEWAY"
|
|
VM_NETMASK="$VM_NETMASK"
|
|
VM_NETWORK="$VM_NETWORK"
|
|
|
|
# GitHub Configuration
|
|
REPO_URL="$REPO_URL"
|
|
GITHUB_USERNAME="$GITHUB_USERNAME"
|
|
GITHUB_API_ENABLED="$GITHUB_API_ENABLED"
|
|
GITHUB_AUTH_METHOD="$GITHUB_AUTH_METHOD"
|
|
|
|
# Webhook Configuration
|
|
WEBHOOK_PORT="$WEBHOOK_PORT"
|
|
WEBHOOK_ENABLED="$WEBHOOK_ENABLED"
|
|
|
|
# SSH Configuration (path to key, not the key content)
|
|
SSH_KEY_PATH="$HOME/.ssh/thrillwiki_vm"
|
|
EOF
|
|
|
|
log_success "Configuration saved to $CONFIG_FILE"
|
|
}
|
|
|
|
# Function to load configuration
|
|
load_config() {
|
|
if [ -f "$CONFIG_FILE" ]; then
|
|
log "Loading existing configuration from $CONFIG_FILE..."
|
|
source "$CONFIG_FILE"
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function for non-interactive configuration loading
|
|
load_non_interactive_config() {
|
|
log "=== Non-Interactive Configuration Loading ==="
|
|
|
|
# Load saved configuration
|
|
if ! load_config; then
|
|
log_error "No saved configuration found. Cannot run in non-interactive mode."
|
|
log_error "Please run the script without -y flag first to create initial configuration."
|
|
exit 1
|
|
fi
|
|
|
|
log_success "Loaded saved configuration successfully"
|
|
|
|
# Check for required environment variables for passwords
|
|
if [ -z "${UNRAID_PASSWORD:-}" ]; then
|
|
log_error "UNRAID_PASSWORD environment variable not set."
|
|
log_error "For non-interactive mode, set: export UNRAID_PASSWORD='your_password'"
|
|
exit 1
|
|
fi
|
|
|
|
# Handle GitHub authentication based on saved method
|
|
if [ -n "$GITHUB_USERNAME" ] && [ "$GITHUB_API_ENABLED" = "true" ]; then
|
|
if [ "$GITHUB_AUTH_METHOD" = "oauth" ]; then
|
|
# Check if OAuth token is still valid
|
|
if python3 "$SCRIPT_DIR/../github-auth.py" validate 2>/dev/null; then
|
|
GITHUB_TOKEN=$(python3 "$SCRIPT_DIR/../github-auth.py" token)
|
|
log "Using existing OAuth token"
|
|
else
|
|
log_error "OAuth token expired and cannot refresh in non-interactive mode"
|
|
log_error "Please run without -y flag to re-authenticate with GitHub"
|
|
exit 1
|
|
fi
|
|
else
|
|
# Personal access token method
|
|
if [ -z "${GITHUB_TOKEN:-}" ]; then
|
|
log_error "GITHUB_TOKEN environment variable not set."
|
|
log_error "For non-interactive mode, set: export GITHUB_TOKEN='your_token'"
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Handle webhook secret
|
|
if [ "$WEBHOOK_ENABLED" = "true" ]; then
|
|
if [ -z "${WEBHOOK_SECRET:-}" ]; then
|
|
log_error "WEBHOOK_SECRET environment variable not set."
|
|
log_error "For non-interactive mode, set: export WEBHOOK_SECRET='your_secret'"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
log_success "All required credentials loaded from environment variables"
|
|
log "Configuration summary:"
|
|
echo " Unraid Host: $UNRAID_HOST"
|
|
echo " VM Name: $VM_NAME"
|
|
echo " VM IP: $VM_IP"
|
|
echo " Repository: $REPO_URL"
|
|
echo " GitHub Auth: $GITHUB_AUTH_METHOD"
|
|
echo " Webhook Enabled: $WEBHOOK_ENABLED"
|
|
}
|
|
|
|
# Function to prompt for configuration
|
|
prompt_unraid_config() {
|
|
# In non-interactive mode, use saved config only
|
|
if [ "$NON_INTERACTIVE" = "true" ]; then
|
|
load_non_interactive_config
|
|
return 0
|
|
fi
|
|
|
|
log "=== Unraid VM Configuration ==="
|
|
echo
|
|
|
|
# Try to load existing config first
|
|
if load_config; then
|
|
log_success "Loaded existing configuration"
|
|
echo "Current settings:"
|
|
echo " Unraid Host: $UNRAID_HOST"
|
|
echo " VM Name: $VM_NAME"
|
|
echo " VM IP: $VM_IP"
|
|
echo " Repository: $REPO_URL"
|
|
echo
|
|
read -p "Use existing configuration? (y/n): " use_existing
|
|
if [ "$use_existing" = "y" ] || [ "$use_existing" = "Y" ]; then
|
|
# Still need to get sensitive info that we don't save
|
|
read -s -p "Enter Unraid [PASSWORD-REMOVED]
|
|
echo
|
|
|
|
# Handle GitHub authentication based on saved method
|
|
if [ -n "$GITHUB_USERNAME" ] && [ "$GITHUB_API_ENABLED" = "true" ]; then
|
|
if [ "$GITHUB_AUTH_METHOD" = "oauth" ]; then
|
|
# Check if OAuth token is still valid
|
|
if python3 "$SCRIPT_DIR/../github-auth.py" validate 2>/dev/null; then
|
|
GITHUB_TOKEN=$(python3 "$SCRIPT_DIR/../github-auth.py" token)
|
|
log "Using existing OAuth token"
|
|
else
|
|
log "OAuth token expired, re-authenticating..."
|
|
if python3 "$SCRIPT_DIR/../github-auth.py" login; then
|
|
GITHUB_TOKEN=$(python3 "$SCRIPT_DIR/../github-auth.py" token)
|
|
log_success "OAuth token refreshed"
|
|
else
|
|
log_error "OAuth re-authentication failed"
|
|
exit 1
|
|
fi
|
|
fi
|
|
else
|
|
# Personal access token method
|
|
read -s -p "Enter GitHub personal access token: " GITHUB_TOKEN
|
|
echo
|
|
fi
|
|
fi
|
|
|
|
if [ "$WEBHOOK_ENABLED" = "true" ]; then
|
|
read -s -p "Enter GitHub webhook secret: " WEBHOOK_SECRET
|
|
echo
|
|
fi
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
# Prompt for new configuration
|
|
read -p "Enter your Unraid server IP address: " UNRAID_HOST
|
|
save_config
|
|
|
|
read -p "Enter Unraid username (default: root): " UNRAID_USER
|
|
UNRAID_USER=${UNRAID_USER:-root}
|
|
save_config
|
|
|
|
read -s -p "Enter Unraid [PASSWORD-REMOVED]
|
|
echo
|
|
# Note: Password not saved for security
|
|
|
|
read -p "Enter VM name (default: $DEFAULT_VM_NAME): " VM_NAME
|
|
VM_NAME=${VM_NAME:-$DEFAULT_VM_NAME}
|
|
save_config
|
|
|
|
read -p "Enter VM memory in MB (default: $DEFAULT_VM_MEMORY): " VM_MEMORY
|
|
VM_MEMORY=${VM_MEMORY:-$DEFAULT_VM_MEMORY}
|
|
save_config
|
|
|
|
read -p "Enter VM vCPUs (default: $DEFAULT_VM_VCPUS): " VM_VCPUS
|
|
VM_VCPUS=${VM_VCPUS:-$DEFAULT_VM_VCPUS}
|
|
save_config
|
|
|
|
read -p "Enter VM disk size in GB (default: $DEFAULT_VM_DISK_SIZE): " VM_DISK_SIZE
|
|
VM_DISK_SIZE=${VM_DISK_SIZE:-$DEFAULT_VM_DISK_SIZE}
|
|
save_config
|
|
|
|
read -p "Enter GitHub repository URL: " REPO_URL
|
|
save_config
|
|
|
|
# GitHub API Configuration
|
|
echo
|
|
log "=== GitHub API Configuration ==="
|
|
echo "Choose GitHub authentication method:"
|
|
echo "1. OAuth Device Flow (recommended - secure, supports private repos)"
|
|
echo "2. Personal Access Token (manual token entry)"
|
|
echo "3. Skip (public repositories only)"
|
|
|
|
while true; do
|
|
read -p "Select option (1-3): " auth_choice
|
|
case $auth_choice in
|
|
1)
|
|
log "Using GitHub OAuth Device Flow..."
|
|
if python3 "$SCRIPT_DIR/../github-auth.py" validate 2>/dev/null; then
|
|
log "Existing GitHub authentication found and valid"
|
|
GITHUB_USERNAME=$(python3 "$SCRIPT_DIR/../github-auth.py" whoami 2>/dev/null | grep "You are authenticated as:" | cut -d: -f2 | xargs)
|
|
GITHUB_TOKEN=$(python3 "$SCRIPT_DIR/../github-auth.py" token)
|
|
else
|
|
log "Starting GitHub OAuth authentication..."
|
|
if python3 "$SCRIPT_DIR/../github-auth.py" login; then
|
|
GITHUB_USERNAME=$(python3 "$SCRIPT_DIR/../github-auth.py" whoami 2>/dev/null | grep "You are authenticated as:" | cut -d: -f2 | xargs)
|
|
GITHUB_TOKEN=$(python3 "$SCRIPT_DIR/../github-auth.py" token)
|
|
log_success "GitHub OAuth authentication completed"
|
|
else
|
|
log_error "GitHub authentication failed"
|
|
continue
|
|
fi
|
|
fi
|
|
GITHUB_API_ENABLED=true
|
|
GITHUB_AUTH_METHOD="oauth"
|
|
break
|
|
;;
|
|
2)
|
|
read -p "Enter GitHub username: " GITHUB_USERNAME
|
|
read -s -p "Enter GitHub personal access token: " GITHUB_TOKEN
|
|
echo
|
|
if [ -n "$GITHUB_USERNAME" ] && [ -n "$GITHUB_TOKEN" ]; then
|
|
GITHUB_API_ENABLED=true
|
|
GITHUB_AUTH_METHOD="token"
|
|
log "Personal access token configured"
|
|
else
|
|
log_error "Both username and token are required"
|
|
continue
|
|
fi
|
|
break
|
|
;;
|
|
3)
|
|
GITHUB_USERNAME=""
|
|
GITHUB_TOKEN=""
|
|
GITHUB_API_ENABLED=false
|
|
GITHUB_AUTH_METHOD="none"
|
|
log "Skipping GitHub API - using public access only"
|
|
break
|
|
;;
|
|
*)
|
|
echo "Invalid option. Please select 1, 2, or 3."
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Save GitHub configuration
|
|
save_config
|
|
log "GitHub authentication configuration saved"
|
|
|
|
# Webhook Configuration
|
|
echo
|
|
read -s -p "Enter GitHub webhook secret (optional, press Enter to skip): " WEBHOOK_SECRET
|
|
echo
|
|
|
|
# If no webhook secret provided, disable webhook functionality
|
|
if [ -z "$WEBHOOK_SECRET" ]; then
|
|
log "No webhook secret provided - webhook functionality will be disabled"
|
|
WEBHOOK_ENABLED=false
|
|
else
|
|
WEBHOOK_ENABLED=true
|
|
fi
|
|
|
|
read -p "Enter webhook port (default: $DEFAULT_WEBHOOK_PORT): " WEBHOOK_PORT
|
|
WEBHOOK_PORT=${WEBHOOK_PORT:-$DEFAULT_WEBHOOK_PORT}
|
|
|
|
# Save webhook configuration
|
|
save_config
|
|
log "Webhook configuration saved"
|
|
|
|
# Get VM network configuration preference
|
|
echo
|
|
log "=== Network Configuration ==="
|
|
echo "Choose network configuration method:"
|
|
echo "1. DHCP (automatic IP assignment - recommended)"
|
|
echo "2. Static IP (manual IP configuration)"
|
|
|
|
while true; do
|
|
read -p "Select option (1-2): " network_choice
|
|
case $network_choice in
|
|
1)
|
|
log "Using DHCP network configuration..."
|
|
VM_IP="dhcp"
|
|
VM_GATEWAY="192.168.20.1"
|
|
VM_NETMASK="255.255.255.0"
|
|
VM_NETWORK="192.168.20.0/24"
|
|
NETWORK_MODE="dhcp"
|
|
break
|
|
;;
|
|
2)
|
|
log "Using static IP network configuration..."
|
|
# Get VM IP address with proper range validation
|
|
while true; do
|
|
read -p "Enter VM IP address (192.168.20.10-192.168.20.100): " VM_IP
|
|
if [[ "$VM_IP" =~ ^192\.168\.20\.([1-9][0-9]|100)$ ]]; then
|
|
local ip_last_octet="${BASH_REMATCH[1]}"
|
|
if [ "$ip_last_octet" -ge 10 ] && [ "$ip_last_octet" -le 100 ]; then
|
|
break
|
|
fi
|
|
fi
|
|
echo "Invalid IP address. Please enter an IP in the range 192.168.20.10-192.168.20.100"
|
|
done
|
|
VM_GATEWAY="192.168.20.1"
|
|
VM_NETMASK="255.255.255.0"
|
|
VM_NETWORK="192.168.20.0/24"
|
|
NETWORK_MODE="static"
|
|
break
|
|
;;
|
|
*)
|
|
echo "Invalid option. Please select 1 or 2."
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Save final network configuration
|
|
save_config
|
|
log "Network configuration saved - setup complete!"
|
|
}
|
|
|
|
# Generate SSH keys for VM access
|
|
setup_ssh_keys() {
|
|
log "Setting up SSH keys for VM access..."
|
|
|
|
local ssh_key_path="$HOME/.ssh/thrillwiki_vm"
|
|
local ssh_config_path="$HOME/.ssh/config"
|
|
|
|
if [ ! -f "$ssh_key_path" ]; then
|
|
ssh-keygen -t rsa -b 4096 -f "$ssh_key_path" -N "" -C "thrillwiki-vm-access"
|
|
log_success "SSH key generated: $ssh_key_path"
|
|
else
|
|
log "SSH key already exists: $ssh_key_path"
|
|
fi
|
|
|
|
# Add SSH config entry
|
|
if ! grep -q "Host $VM_NAME" "$ssh_config_path" 2>/dev/null; then
|
|
cat >> "$ssh_config_path" << EOF
|
|
|
|
# ThrillWiki VM
|
|
Host $VM_NAME
|
|
HostName %h
|
|
User ubuntu
|
|
IdentityFile $ssh_key_path
|
|
StrictHostKeyChecking no
|
|
UserKnownHostsFile /dev/null
|
|
EOF
|
|
log_success "SSH config updated"
|
|
fi
|
|
|
|
# Store public key for VM setup
|
|
SSH_PUBLIC_KEY=$(cat "$ssh_key_path.pub")
|
|
export SSH_PUBLIC_KEY
|
|
}
|
|
|
|
# Setup Unraid host access
|
|
setup_unraid_access() {
|
|
log "Setting up Unraid server access..."
|
|
|
|
local unraid_key_path="$HOME/.ssh/unraid_access"
|
|
|
|
if [ ! -f "$unraid_key_path" ]; then
|
|
ssh-keygen -t rsa -b 4096 -f "$unraid_key_path" -N "" -C "unraid-access"
|
|
|
|
log "Please add this public key to your Unraid server:"
|
|
echo "---"
|
|
cat "$unraid_key_path.pub"
|
|
echo "---"
|
|
echo
|
|
log "Add this to /root/.ssh/***REMOVED*** on your Unraid server"
|
|
read -p "Press Enter when you've added the key..."
|
|
fi
|
|
|
|
# Test Unraid connection
|
|
log "Testing Unraid connection..."
|
|
if ssh -i "$unraid_key_path" -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$UNRAID_USER@$UNRAID_HOST" "echo 'Connected to Unraid successfully'"; then
|
|
log_success "Unraid connection test passed"
|
|
else
|
|
log_error "Unraid connection test failed"
|
|
exit 1
|
|
fi
|
|
|
|
# Update SSH config for Unraid
|
|
if ! grep -q "Host unraid" "$HOME/.ssh/config" 2>/dev/null; then
|
|
cat >> "$HOME/.ssh/config" << EOF
|
|
|
|
# Unraid Server
|
|
Host unraid
|
|
HostName $UNRAID_HOST
|
|
User $UNRAID_USER
|
|
IdentityFile $unraid_key_path
|
|
StrictHostKeyChecking no
|
|
EOF
|
|
fi
|
|
}
|
|
|
|
# Create environment files
|
|
create_environment_files() {
|
|
log "Creating environment configuration files..."
|
|
|
|
# Get SSH public key content safely
|
|
local ssh_key_path="$HOME/.ssh/thrillwiki_vm.pub"
|
|
local ssh_public_key=""
|
|
if [ -f "$ssh_key_path" ]; then
|
|
ssh_public_key=$(cat "$ssh_key_path")
|
|
fi
|
|
|
|
# Unraid VM environment
|
|
cat > "$PROJECT_DIR/***REMOVED***.unraid" << EOF
|
|
# Unraid VM Configuration
|
|
UNRAID_HOST=$UNRAID_HOST
|
|
UNRAID_USER=$UNRAID_USER
|
|
UNRAID_PASSWORD=$UNRAID_PASSWORD
|
|
VM_NAME=$VM_NAME
|
|
VM_MEMORY=$VM_MEMORY
|
|
VM_VCPUS=$VM_VCPUS
|
|
VM_DISK_SIZE=$VM_DISK_SIZE
|
|
SSH_PUBLIC_KEY="$ssh_public_key"
|
|
|
|
# Network Configuration
|
|
VM_IP=$VM_IP
|
|
VM_GATEWAY=$VM_GATEWAY
|
|
VM_NETMASK=$VM_NETMASK
|
|
VM_NETWORK=$VM_NETWORK
|
|
|
|
# GitHub Configuration
|
|
REPO_URL=$REPO_URL
|
|
GITHUB_USERNAME=$GITHUB_USERNAME
|
|
GITHUB_TOKEN=$GITHUB_TOKEN
|
|
GITHUB_API_ENABLED=$GITHUB_API_ENABLED
|
|
EOF
|
|
|
|
# Webhook environment (updated with VM info)
|
|
cat > "$PROJECT_DIR/***REMOVED***.webhook" << EOF
|
|
# ThrillWiki Webhook Configuration
|
|
WEBHOOK_PORT=$WEBHOOK_PORT
|
|
WEBHOOK_SECRET=$WEBHOOK_SECRET
|
|
WEBHOOK_ENABLED=$WEBHOOK_ENABLED
|
|
VM_HOST=$VM_IP
|
|
VM_PORT=22
|
|
VM_USER=ubuntu
|
|
VM_KEY_PATH=$HOME/.ssh/thrillwiki_vm
|
|
VM_PROJECT_PATH=/home/ubuntu/thrillwiki
|
|
REPO_URL=$REPO_URL
|
|
DEPLOY_BRANCH=main
|
|
|
|
# GitHub API Configuration
|
|
GITHUB_USERNAME=$GITHUB_USERNAME
|
|
GITHUB_TOKEN=$GITHUB_TOKEN
|
|
GITHUB_API_ENABLED=$GITHUB_API_ENABLED
|
|
EOF
|
|
|
|
log_success "Environment files created"
|
|
}
|
|
|
|
# Install required tools
|
|
install_dependencies() {
|
|
log "Installing required dependencies..."
|
|
|
|
# Check for required tools
|
|
local missing_tools=()
|
|
local mac_tools=()
|
|
|
|
command -v python3 >/dev/null 2>&1 || missing_tools+=("python3")
|
|
command -v ssh >/dev/null 2>&1 || missing_tools+=("openssh-client")
|
|
command -v scp >/dev/null 2>&1 || missing_tools+=("openssh-client")
|
|
|
|
# Check for ISO creation tools and handle platform differences
|
|
if ! command -v genisoimage >/dev/null 2>&1 && ! command -v mkisofs >/dev/null 2>&1 && ! command -v hdiutil >/dev/null 2>&1; then
|
|
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
|
missing_tools+=("genisoimage")
|
|
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
|
# On macOS, hdiutil should be available, but add cdrtools as backup
|
|
if command -v brew >/dev/null 2>&1; then
|
|
mac_tools+=("cdrtools")
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Install Linux packages
|
|
if [ ${#missing_tools[@]} -gt 0 ]; then
|
|
log "Installing missing tools for Linux: ${missing_tools[*]}"
|
|
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
sudo apt-get update
|
|
sudo apt-get install -y "${missing_tools[@]}"
|
|
elif command -v yum >/dev/null 2>&1; then
|
|
sudo yum install -y "${missing_tools[@]}"
|
|
elif command -v dnf >/dev/null 2>&1; then
|
|
sudo dnf install -y "${missing_tools[@]}"
|
|
else
|
|
log_error "Linux package manager not found. Please install: ${missing_tools[*]}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Install macOS packages
|
|
if [ ${#mac_tools[@]} -gt 0 ]; then
|
|
log "Installing additional tools for macOS: ${mac_tools[*]}"
|
|
if command -v brew >/dev/null 2>&1; then
|
|
brew install "${mac_tools[@]}"
|
|
else
|
|
log "Homebrew not found. Skipping optional tool installation."
|
|
log "Note: hdiutil should be available on macOS for ISO creation"
|
|
fi
|
|
fi
|
|
|
|
# Install Python dependencies
|
|
if [ -f "$PROJECT_DIR/pyproject.toml" ]; then
|
|
log "Installing Python dependencies with UV..."
|
|
if ! command -v uv >/dev/null 2>&1; then
|
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
source ~/.cargo/env
|
|
fi
|
|
uv sync
|
|
fi
|
|
|
|
log_success "Dependencies installed"
|
|
}
|
|
|
|
# Create VM using the VM manager
|
|
create_vm() {
|
|
log "Creating VM on Unraid server..."
|
|
|
|
# Export all environment variables from the file
|
|
set -a # automatically export all variables
|
|
source "$PROJECT_DIR/***REMOVED***.unraid"
|
|
set +a # turn off automatic export
|
|
|
|
# Run complete VM setup (builds ISO, creates VM, starts VM)
|
|
cd "$PROJECT_DIR"
|
|
python3 scripts/unraid/main.py setup
|
|
|
|
if [ $? -eq 0 ]; then
|
|
log_success "VM setup completed successfully"
|
|
else
|
|
log_error "VM setup failed"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Wait for VM to be ready and get IP
|
|
wait_for_vm() {
|
|
log "Waiting for VM to be ready..."
|
|
sleep 120
|
|
# Export all environment variables from the file
|
|
set -a # automatically export all variables
|
|
source "$PROJECT_DIR/***REMOVED***.unraid"
|
|
set +a # turn off automatic export
|
|
|
|
local max_attempts=60
|
|
local attempt=1
|
|
|
|
while [ $attempt -le $max_attempts ]; do
|
|
VM_IP=$(python3 scripts/unraid/main.py ip 2>/dev/null | grep "VM IP:" | cut -d' ' -f3)
|
|
|
|
if [ -n "$VM_IP" ]; then
|
|
log_success "VM is ready with IP: $VM_IP"
|
|
|
|
# Update SSH config with actual IP
|
|
sed -i.bak "s/HostName %h/HostName $VM_IP/" "$HOME/.ssh/config"
|
|
|
|
# Update webhook environment with IP
|
|
sed -i.bak "s/VM_HOST=$VM_NAME/VM_HOST=$VM_IP/" "$PROJECT_DIR/***REMOVED***.webhook"
|
|
|
|
return 0
|
|
fi
|
|
|
|
log "Waiting for VM to get IP... (attempt $attempt/$max_attempts)"
|
|
sleep 30
|
|
((attempt++))
|
|
done
|
|
|
|
log_error "VM failed to get IP address"
|
|
exit 1
|
|
}
|
|
|
|
# Configure VM for ThrillWiki
|
|
configure_vm() {
|
|
log "Configuring VM for ThrillWiki deployment..."
|
|
|
|
local vm_setup_script="/tmp/vm_thrillwiki_setup.sh"
|
|
|
|
# Create VM setup script
|
|
cat > "$vm_setup_script" << 'EOF'
|
|
#!/bin/bash
|
|
set -e
|
|
|
|
echo "Setting up VM for ThrillWiki..."
|
|
|
|
# Update system
|
|
sudo apt update && sudo apt upgrade -y
|
|
|
|
# Install required packages
|
|
sudo apt install -y git curl build-essential python3-pip lsof postgresql postgresql-contrib nginx
|
|
|
|
# Install UV
|
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
source ~/.cargo/env
|
|
|
|
# Configure PostgreSQL
|
|
sudo -u postgres psql << PSQL
|
|
CREATE DATABASE thrillwiki;
|
|
CREATE USER thrillwiki_user WITH ENCRYPTED PASSWORD 'thrillwiki_pass';
|
|
GRANT ALL PRIVILEGES ON DATABASE thrillwiki TO thrillwiki_user;
|
|
\q
|
|
PSQL
|
|
|
|
# Clone repository
|
|
git clone REPO_URL_PLACEHOLDER thrillwiki
|
|
cd thrillwiki
|
|
|
|
# Install dependencies
|
|
~/.cargo/bin/uv sync
|
|
|
|
# Create directories
|
|
mkdir -p logs backups
|
|
|
|
# Make scripts executable
|
|
chmod +x scripts/*.sh
|
|
|
|
# Run initial setup
|
|
~/.cargo/bin/uv run manage.py migrate
|
|
~/.cargo/bin/uv run manage.py collectstatic --noinput
|
|
|
|
# Install systemd services
|
|
sudo cp scripts/systemd/thrillwiki.service /etc/systemd/system/
|
|
sudo sed -i 's|/home/ubuntu|/home/ubuntu|g' /etc/systemd/system/thrillwiki.service
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable thrillwiki.service
|
|
|
|
echo "VM setup completed!"
|
|
EOF
|
|
|
|
# Replace placeholder with actual repo URL
|
|
sed -i "s|REPO_URL_PLACEHOLDER|$REPO_URL|g" "$vm_setup_script"
|
|
|
|
# Copy and execute setup script on VM
|
|
scp "$vm_setup_script" "$VM_NAME:/tmp/"
|
|
ssh "$VM_NAME" "bash /tmp/vm_thrillwiki_setup.sh"
|
|
|
|
# Cleanup
|
|
rm "$vm_setup_script"
|
|
|
|
log_success "VM configured for ThrillWiki"
|
|
}
|
|
|
|
# Start services
|
|
start_services() {
|
|
log "Starting ThrillWiki services..."
|
|
|
|
# Start VM service
|
|
ssh "$VM_NAME" "sudo systemctl start thrillwiki"
|
|
|
|
# Verify service is running
|
|
if ssh "$VM_NAME" "systemctl is-active --quiet thrillwiki"; then
|
|
log_success "ThrillWiki service started successfully"
|
|
else
|
|
log_error "Failed to start ThrillWiki service"
|
|
exit 1
|
|
fi
|
|
|
|
# Get service status
|
|
log "Service status:"
|
|
ssh "$VM_NAME" "systemctl status thrillwiki --no-pager -l"
|
|
}
|
|
|
|
# Setup webhook listener
|
|
setup_webhook_listener() {
|
|
log "Setting up webhook listener..."
|
|
|
|
# Create webhook start script
|
|
cat > "$PROJECT_DIR/start-webhook.sh" << 'EOF'
|
|
#!/bin/bash
|
|
cd "$(dirname "$0")"
|
|
source ***REMOVED***.webhook
|
|
python3 scripts/webhook-listener.py
|
|
EOF
|
|
|
|
chmod +x "$PROJECT_DIR/start-webhook.sh"
|
|
|
|
log_success "Webhook listener configured"
|
|
log "You can start the webhook listener with: ./start-webhook.sh"
|
|
}
|
|
|
|
# Perform end-to-end test
|
|
test_deployment() {
|
|
log "Performing end-to-end deployment test..."
|
|
|
|
# Test VM connectivity
|
|
if ssh "$VM_NAME" "echo 'VM connectivity test passed'"; then
|
|
log_success "VM connectivity test passed"
|
|
else
|
|
log_error "VM connectivity test failed"
|
|
return 1
|
|
fi
|
|
|
|
# Test ThrillWiki service
|
|
if ssh "$VM_NAME" "curl -f http://localhost:8000 >/dev/null 2>&1"; then
|
|
log_success "ThrillWiki service test passed"
|
|
else
|
|
log_warning "ThrillWiki service test failed - checking logs..."
|
|
ssh "$VM_NAME" "journalctl -u thrillwiki --no-pager -l | tail -20"
|
|
fi
|
|
|
|
# Test deployment script
|
|
log "Testing deployment script..."
|
|
ssh "$VM_NAME" "cd thrillwiki && ./scripts/vm-deploy.sh status"
|
|
|
|
log_success "End-to-end test completed"
|
|
}
|
|
|
|
# Generate final instructions
|
|
generate_instructions() {
|
|
log "Generating final setup instructions..."
|
|
|
|
cat > "$PROJECT_DIR/UNRAID_SETUP_COMPLETE.md" << EOF
|
|
# ThrillWiki Unraid Automation - Setup Complete! 🎉
|
|
|
|
Your ThrillWiki CI/CD system has been fully automated and deployed!
|
|
|
|
## VM Information
|
|
- **VM Name**: $VM_NAME
|
|
- **VM IP**: $VM_IP
|
|
- **SSH Access**: \`ssh $VM_NAME\`
|
|
|
|
## Services Status
|
|
- **ThrillWiki Service**: Running on VM
|
|
- **Database**: PostgreSQL configured
|
|
- **Web Server**: Available at http://$VM_IP:8000
|
|
|
|
## Next Steps
|
|
|
|
### 1. Start Webhook Listener
|
|
\`\`\`bash
|
|
./start-webhook.sh
|
|
\`\`\`
|
|
|
|
### 2. Configure GitHub Webhook
|
|
- Go to your repository: $REPO_URL
|
|
- Settings → Webhooks → Add webhook
|
|
- **Payload URL**: http://YOUR_PUBLIC_IP:$WEBHOOK_PORT/webhook
|
|
- **Content type**: application/json
|
|
- **Secret**: (your webhook secret)
|
|
- **Events**: Just the push event
|
|
|
|
### 3. Test the System
|
|
\`\`\`bash
|
|
# Test VM connection
|
|
ssh $VM_NAME
|
|
|
|
# Test service status
|
|
ssh $VM_NAME "systemctl status thrillwiki"
|
|
|
|
# Test manual deployment
|
|
ssh $VM_NAME "cd thrillwiki && ./scripts/vm-deploy.sh"
|
|
|
|
# Make a test commit to trigger automatic deployment
|
|
git add .
|
|
git commit -m "Test automated deployment"
|
|
git push origin main
|
|
\`\`\`
|
|
|
|
## Management Commands
|
|
|
|
### VM Management
|
|
\`\`\`bash
|
|
# Check VM status
|
|
python3 scripts/unraid/vm-manager.py status
|
|
|
|
# Start/stop VM
|
|
python3 scripts/unraid/vm-manager.py start
|
|
python3 scripts/unraid/vm-manager.py stop
|
|
|
|
# Get VM IP
|
|
python3 scripts/unraid/vm-manager.py ip
|
|
\`\`\`
|
|
|
|
### Service Management on VM
|
|
\`\`\`bash
|
|
# Check service status
|
|
ssh $VM_NAME "./scripts/vm-deploy.sh status"
|
|
|
|
# Restart service
|
|
ssh $VM_NAME "./scripts/vm-deploy.sh restart"
|
|
|
|
# View logs
|
|
ssh $VM_NAME "journalctl -u thrillwiki -f"
|
|
\`\`\`
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
1. **VM not accessible**: Check VM is running and has IP
|
|
2. **Service not starting**: Check logs with \`journalctl -u thrillwiki\`
|
|
3. **Webhook not working**: Verify port $WEBHOOK_PORT is open
|
|
|
|
### Support Files
|
|
- Configuration: \`***REMOVED***.unraid\`, \`***REMOVED***.webhook\`
|
|
- Logs: \`logs/\` directory
|
|
- Documentation: \`docs/VM_DEPLOYMENT_SETUP.md\`
|
|
|
|
**Your automated CI/CD system is now ready!** 🚀
|
|
|
|
Every push to the main branch will automatically deploy to your VM.
|
|
EOF
|
|
|
|
log_success "Setup instructions saved to UNRAID_SETUP_COMPLETE.md"
|
|
}
|
|
|
|
# Main automation function
|
|
main() {
|
|
log "🚀 Starting ThrillWiki Complete Unraid Automation"
|
|
echo "[AWS-SECRET-REMOVED]=========="
|
|
echo
|
|
|
|
# Parse command line arguments
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--reset)
|
|
RESET_ALL=true
|
|
shift
|
|
;;
|
|
--reset-vm)
|
|
RESET_VM_ONLY=true
|
|
shift
|
|
;;
|
|
--reset-config)
|
|
RESET_CONFIG_ONLY=true
|
|
shift
|
|
;;
|
|
--help|-h)
|
|
show_help
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1"
|
|
show_help
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Create logs directory
|
|
mkdir -p "$LOG_DIR"
|
|
|
|
# Handle reset modes
|
|
if [[ "$RESET_ALL" == "true" ]]; then
|
|
log "🔄 Complete reset mode - deleting VM and configuration"
|
|
echo
|
|
|
|
# Load configuration first to get connection details for VM deletion
|
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
source "$CONFIG_FILE"
|
|
log_success "Loaded existing configuration for VM deletion"
|
|
else
|
|
log_warning "No configuration file found, will skip VM deletion"
|
|
fi
|
|
|
|
# Delete existing VM if config exists
|
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
log "🗑️ Deleting existing VM..."
|
|
# Export environment variables for VM manager
|
|
set -a
|
|
source "$PROJECT_DIR/***REMOVED***.unraid" 2>/dev/null || true
|
|
set +a
|
|
|
|
if python3 "$SCRIPT_DIR/vm-manager.py" delete; then
|
|
log_success "VM deleted successfully"
|
|
else
|
|
log "⚠️ VM deletion failed or VM didn't exist"
|
|
fi
|
|
fi
|
|
|
|
# Remove configuration files
|
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
rm "$CONFIG_FILE"
|
|
log_success "Configuration file removed"
|
|
fi
|
|
|
|
# Remove environment files
|
|
rm -f "$PROJECT_DIR/***REMOVED***.unraid" "$PROJECT_DIR/***REMOVED***.webhook"
|
|
log_success "Environment files removed"
|
|
|
|
log_success "Complete reset finished - continuing with fresh setup"
|
|
echo
|
|
|
|
elif [[ "$RESET_VM_ONLY" == "true" ]]; then
|
|
log "🔄 VM-only reset mode - deleting VM, preserving configuration"
|
|
echo
|
|
|
|
# Load configuration to get connection details
|
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
source "$CONFIG_FILE"
|
|
log_success "Loaded existing configuration"
|
|
else
|
|
log_error "No configuration file found. Cannot reset VM without connection details."
|
|
echo " Run the script without reset flags first to create initial configuration."
|
|
exit 1
|
|
fi
|
|
|
|
# Delete existing VM
|
|
log "🗑️ Deleting existing VM..."
|
|
# Export environment variables for VM manager
|
|
set -a
|
|
source "$PROJECT_DIR/***REMOVED***.unraid" 2>/dev/null || true
|
|
set +a
|
|
|
|
if python3 "$SCRIPT_DIR/vm-manager.py" delete; then
|
|
log_success "VM deleted successfully"
|
|
else
|
|
log "⚠️ VM deletion failed or VM didn't exist"
|
|
fi
|
|
|
|
# Remove only environment files, keep main config
|
|
rm -f "$PROJECT_DIR/***REMOVED***.unraid" "$PROJECT_DIR/***REMOVED***.webhook"
|
|
log_success "Environment files removed, configuration preserved"
|
|
|
|
log_success "VM reset complete - will recreate VM with saved configuration"
|
|
echo
|
|
|
|
elif [[ "$RESET_CONFIG_ONLY" == "true" ]]; then
|
|
log "🔄 Config-only reset mode - deleting configuration, preserving VM"
|
|
echo
|
|
|
|
# Remove configuration files
|
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
rm "$CONFIG_FILE"
|
|
log_success "Configuration file removed"
|
|
fi
|
|
|
|
# Remove environment files
|
|
rm -f "$PROJECT_DIR/***REMOVED***.unraid" "$PROJECT_DIR/***REMOVED***.webhook"
|
|
log_success "Environment files removed"
|
|
|
|
log_success "Configuration reset complete - will prompt for fresh configuration"
|
|
echo
|
|
fi
|
|
|
|
# Collect configuration
|
|
prompt_unraid_config
|
|
|
|
# Setup steps
|
|
setup_ssh_keys
|
|
setup_unraid_access
|
|
create_environment_files
|
|
install_dependencies
|
|
create_vm
|
|
wait_for_vm
|
|
configure_vm
|
|
start_services
|
|
setup_webhook_listener
|
|
test_deployment
|
|
generate_instructions
|
|
|
|
echo
|
|
log_success "🎉 Complete automation setup finished!"
|
|
echo
|
|
log "Your ThrillWiki VM is running at: http://$VM_IP:8000"
|
|
log "Start the webhook listener: ./start-webhook.sh"
|
|
log "See UNRAID_SETUP_COMPLETE.md for detailed instructions"
|
|
echo
|
|
log "The system will now automatically deploy when you push to GitHub!"
|
|
}
|
|
|
|
# Run main function and log output
|
|
main "$@" 2>&1 | tee "$LOG_DIR/unraid-automation.log" |