Remove deprecated scripts and assets related to ThrillWiki deployment and validation
- Deleted the systemd service diagnosis script `test-systemd-service-diagnosis.sh` - Removed the validation fix test script `test-validation-fix.sh` - Eliminated the simple validation test script `validate-step5b-simple.sh` - Removed the GitHub webhook listener script `webhook-listener.py` - Deleted various placeholder images from the static assets - Removed the ThrillWiki database file `thrillwiki.db`
|
Before Width: | Height: | Size: 12 MiB |
|
Before Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 825 B |
|
Before Width: | Height: | Size: 825 B |
|
Before Width: | Height: | Size: 825 B |
|
Before Width: | Height: | Size: 825 B |
|
Before Width: | Height: | Size: 825 B |
|
Before Width: | Height: | Size: 825 B |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 1.7 MiB |
|
Before Width: | Height: | Size: 942 KiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 942 KiB |
|
Before Width: | Height: | Size: 12 MiB |
|
Before Width: | Height: | Size: 1.7 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 770 KiB |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 35 B |
|
Before Width: | Height: | Size: 12 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 942 KiB |
|
Before Width: | Height: | Size: 770 KiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 942 KiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 12 MiB |
|
Before Width: | Height: | Size: 1.7 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 1.7 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
@@ -1,94 +0,0 @@
|
||||
# ThrillWiki Development Scripts
|
||||
|
||||
## Development Server Script
|
||||
|
||||
The `dev_server.sh` script sets up all necessary environment variables and starts the Django development server with proper configuration.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# From the project root directory
|
||||
./scripts/dev_server.sh
|
||||
|
||||
# Or from anywhere
|
||||
/path/to/thrillwiki_django_no_react/scripts/dev_server.sh
|
||||
```
|
||||
|
||||
### What the script does
|
||||
|
||||
1. **Environment Setup**: Sets all required environment variables for local development
|
||||
2. **Directory Creation**: Creates necessary directories (logs, profiles, media, etc.)
|
||||
3. **Database Migrations**: Runs pending migrations automatically
|
||||
4. **Superuser Creation**: Creates a development superuser (admin/admin) if none exists
|
||||
5. **Static Files**: Collects static files for the application
|
||||
6. **Tailwind CSS**: Builds Tailwind CSS if npm is available
|
||||
7. **System Checks**: Runs Django system checks
|
||||
8. **Server Start**: Starts the Django development server on `http://localhost:8000`
|
||||
|
||||
### Environment Variables Set
|
||||
|
||||
The script automatically sets these environment variables:
|
||||
|
||||
- `DJANGO_SETTINGS_MODULE=config.django.local`
|
||||
- `DEBUG=True`
|
||||
- `SECRET_KEY=<generated-dev-key>`
|
||||
- `ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0`
|
||||
- `DATABASE_URL=postgis://thrillwiki_user:thrillwiki_pass@localhost:5432/thrillwiki_db`
|
||||
- `CACHE_URL=locmemcache://`
|
||||
- `CORS_ALLOW_ALL_ORIGINS=True`
|
||||
- GeoDjango library paths for macOS
|
||||
- And many more...
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. **PostgreSQL with PostGIS**: Make sure PostgreSQL with PostGIS extension is running
|
||||
2. **Database**: Create the database `thrillwiki_db` with user `thrillwiki_user`
|
||||
3. **uv**: The script uses `uv` to run Django commands
|
||||
4. **Virtual Environment**: The script will activate `.venv` if it exists
|
||||
|
||||
### Database Setup
|
||||
|
||||
If you need to set up the database:
|
||||
|
||||
```bash
|
||||
# Install PostgreSQL and PostGIS (macOS with Homebrew)
|
||||
brew install postgresql postgis
|
||||
|
||||
# Start PostgreSQL
|
||||
brew services start postgresql
|
||||
|
||||
# Create database and user
|
||||
psql postgres -c "CREATE USER thrillwiki_user WITH PASSWORD 'thrillwiki_pass';"
|
||||
psql postgres -c "CREATE DATABASE thrillwiki_db OWNER thrillwiki_user;"
|
||||
psql -d thrillwiki_db -c "CREATE EXTENSION postgis;"
|
||||
psql -d thrillwiki_db -c "GRANT ALL PRIVILEGES ON DATABASE thrillwiki_db TO thrillwiki_user;"
|
||||
```
|
||||
|
||||
### Access Points
|
||||
|
||||
Once the server is running, you can access:
|
||||
|
||||
- **Main Application**: http://localhost:8000
|
||||
- **Admin Interface**: http://localhost:8000/admin/ (admin/admin)
|
||||
- **Django Silk Profiler**: http://localhost:8000/silk/
|
||||
- **API Documentation**: http://localhost:8000/api/docs/
|
||||
- **API Redoc**: http://localhost:8000/api/redoc/
|
||||
|
||||
### Stopping the Server
|
||||
|
||||
Press `Ctrl+C` to stop the development server.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
1. **Database Connection Issues**: Ensure PostgreSQL is running and the database exists
|
||||
2. **GeoDjango Library Issues**: Adjust `GDAL_LIBRARY_PATH` and `GEOS_LIBRARY_PATH` if needed
|
||||
3. **Permission Issues**: Make sure the script is executable with `chmod +x scripts/dev_server.sh`
|
||||
4. **Virtual Environment**: Ensure your virtual environment is set up with all dependencies
|
||||
|
||||
### Customization
|
||||
|
||||
You can modify the script to:
|
||||
- Change default database credentials
|
||||
- Adjust library paths for your system
|
||||
- Add additional environment variables
|
||||
- Modify the development server port or host
|
||||
@@ -1 +0,0 @@
|
||||
[GITHUB-TOKEN-REMOVED]
|
||||
@@ -1,203 +0,0 @@
|
||||
# ThrillWiki Automation Service Environment Configuration
|
||||
# Copy this file to thrillwiki-automation***REMOVED*** and customize for your environment
|
||||
#
|
||||
# Security Note: This file should have restricted permissions (600) as it may contain
|
||||
# sensitive information like GitHub Personal Access Tokens
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# PROJECT CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Base project directory (usually auto-detected)
|
||||
# PROJECT_DIR=/home/ubuntu/thrillwiki
|
||||
|
||||
# Service name for systemd integration
|
||||
# SERVICE_NAME=thrillwiki
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# GITHUB REPOSITORY CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# GitHub repository remote name
|
||||
# GITHUB_REPO=origin
|
||||
|
||||
# Branch to pull from
|
||||
# GITHUB_BRANCH=main
|
||||
|
||||
# GitHub Personal Access Token (PAT) - Required for private repositories
|
||||
# Generate at: https://github.com/settings/tokens
|
||||
# Required permissions: repo (Full control of private repositories)
|
||||
# GITHUB_TOKEN=ghp_your_personal_access_token_here
|
||||
|
||||
# GitHub token file location (alternative to GITHUB_TOKEN)
|
||||
# GITHUB_TOKEN_FILE=/home/ubuntu/thrillwiki/.github-pat
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# AUTOMATION TIMING CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Repository pull interval in seconds (default: 300 = 5 minutes)
|
||||
# PULL_INTERVAL=300
|
||||
|
||||
# Health check interval in seconds (default: 60 = 1 minute)
|
||||
# HEALTH_CHECK_INTERVAL=60
|
||||
|
||||
# Server startup timeout in seconds (default: 120 = 2 minutes)
|
||||
# STARTUP_TIMEOUT=120
|
||||
|
||||
# Restart delay after failure in seconds (default: 10)
|
||||
# RESTART_DELAY=10
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# LOGGING CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Log directory (default: project_dir/logs)
|
||||
# LOG_DIR=/home/ubuntu/thrillwiki/logs
|
||||
|
||||
# Log file path
|
||||
# LOG_[AWS-SECRET-REMOVED]proof-automation.log
|
||||
|
||||
# Maximum log file size in bytes (default: 10485760 = 10MB)
|
||||
# MAX_LOG_SIZE=10485760
|
||||
|
||||
# Lock file location to prevent multiple instances
|
||||
# LOCK_FILE=/tmp/thrillwiki-bulletproof.lock
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# DEVELOPMENT SERVER CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Server host address (default: 0.0.0.0 for all interfaces)
|
||||
# SERVER_HOST=0.0.0.0
|
||||
|
||||
# Server port (default: 8000)
|
||||
# SERVER_PORT=8000
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# DJANGO CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Django settings module
|
||||
# DJANGO_SETTINGS_MODULE=thrillwiki.settings
|
||||
|
||||
# Python path
|
||||
# PYTHONPATH=/home/ubuntu/thrillwiki
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# ADVANCED CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# GitHub authentication script location
|
||||
# GITHUB_AUTH_[AWS-SECRET-REMOVED]ithub-auth.py
|
||||
|
||||
# Enable verbose logging (true/false)
|
||||
# VERBOSE_LOGGING=false
|
||||
|
||||
# Enable debug mode for troubleshooting (true/false)
|
||||
# DEBUG_MODE=false
|
||||
|
||||
# Custom git remote URL (overrides GITHUB_REPO if set)
|
||||
# CUSTOM_GIT_REMOTE=https://github.com/username/repository.git
|
||||
|
||||
# Email notifications for critical failures (requires email configuration)
|
||||
# NOTIFICATION_EMAIL=admin@example.com
|
||||
|
||||
# Maximum consecutive failures before alerting (default: 5)
|
||||
# MAX_CONSECUTIVE_FAILURES=5
|
||||
|
||||
# Enable automatic dependency updates (true/false, default: true)
|
||||
# AUTO_UPDATE_DEPENDENCIES=true
|
||||
|
||||
# Enable automatic migrations on code changes (true/false, default: true)
|
||||
# AUTO_MIGRATE=true
|
||||
|
||||
# Enable automatic static file collection (true/false, default: true)
|
||||
# AUTO_COLLECTSTATIC=true
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# SECURITY CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# GitHub authentication method (token|ssh|https)
|
||||
# Default: token (uses GITHUB_TOKEN or GITHUB_TOKEN_FILE)
|
||||
# GITHUB_AUTH_METHOD=token
|
||||
|
||||
# SSH key path for git operations (when using ssh auth method)
|
||||
# SSH_KEY_PATH=/home/ubuntu/.ssh/***REMOVED***
|
||||
|
||||
# Git user configuration for commits
|
||||
# GIT_USER_NAME="ThrillWiki Automation"
|
||||
# GIT_USER_EMAIL="automation@thrillwiki.local"
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# MONITORING AND HEALTH CHECKS
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Health check URL to verify server is running
|
||||
# HEALTH_CHECK_URL=http://localhost:8000/health/
|
||||
|
||||
# Health check timeout in seconds
|
||||
# HEALTH_CHECK_TIMEOUT=30
|
||||
|
||||
# Enable system resource monitoring (true/false)
|
||||
# MONITOR_RESOURCES=true
|
||||
|
||||
# Memory usage threshold for warnings (in MB)
|
||||
# MEMORY_WARNING_THRESHOLD=1024
|
||||
|
||||
# CPU usage threshold for warnings (percentage)
|
||||
# CPU_WARNING_THRESHOLD=80
|
||||
|
||||
# Disk usage threshold for warnings (percentage)
|
||||
# DISK_WARNING_THRESHOLD=90
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# INTEGRATION SETTINGS
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Webhook integration (if using thrillwiki-webhook service)
|
||||
# WEBHOOK_INTEGRATION=true
|
||||
|
||||
# Slack webhook URL for notifications (optional)
|
||||
# SLACK_WEBHOOK_URL=https://hooks.slack.com/services/your/webhook/url
|
||||
|
||||
# Discord webhook URL for notifications (optional)
|
||||
# DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/your/webhook/url
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# USAGE EXAMPLES
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Example 1: Basic setup with GitHub PAT
|
||||
# GITHUB_TOKEN=ghp_your_token_here
|
||||
# PULL_INTERVAL=300
|
||||
# AUTO_MIGRATE=true
|
||||
|
||||
# Example 2: Enhanced monitoring setup
|
||||
# HEALTH_CHECK_INTERVAL=30
|
||||
# MONITOR_RESOURCES=true
|
||||
# NOTIFICATION_EMAIL=admin@thrillwiki.com
|
||||
# SLACK_WEBHOOK_URL=https://hooks.slack.com/services/your/webhook
|
||||
|
||||
# Example 3: Development environment with frequent pulls
|
||||
# PULL_INTERVAL=60
|
||||
# DEBUG_MODE=true
|
||||
# VERBOSE_LOGGING=true
|
||||
# AUTO_UPDATE_DEPENDENCIES=true
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# INSTALLATION NOTES
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# 1. Copy this file: cp thrillwiki-automation***REMOVED***.example thrillwiki-automation***REMOVED***
|
||||
# 2. Set secure permissions: chmod 600 thrillwiki-automation***REMOVED***
|
||||
# 3. Customize the settings above for your environment
|
||||
# 4. Enable the service: sudo systemctl enable thrillwiki-automation
|
||||
# 5. Start the service: sudo systemctl start thrillwiki-automation
|
||||
# 6. Check status: sudo systemctl status thrillwiki-automation
|
||||
# 7. View logs: sudo journalctl -u thrillwiki-automation -f
|
||||
|
||||
# For security, ensure only the ubuntu user can read this file:
|
||||
# sudo chown ubuntu:ubuntu thrillwiki-automation***REMOVED***
|
||||
# sudo chmod 600 thrillwiki-automation***REMOVED***
|
||||
@@ -1,129 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ThrillWiki Local CI Start Script
|
||||
# This script starts the Django development server following project requirements
|
||||
|
||||
set -e # Exit on any error
|
||||
|
||||
# Configuration
|
||||
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
LOG_DIR="$PROJECT_DIR/logs"
|
||||
PID_FILE="$LOG_DIR/django.pid"
|
||||
LOG_FILE="$LOG_DIR/django.log"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Logging function
|
||||
log() {
|
||||
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
|
||||
}
|
||||
|
||||
# Create logs directory if it doesn't exist
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
# Change to project directory
|
||||
cd "$PROJECT_DIR"
|
||||
|
||||
log "Starting ThrillWiki CI deployment..."
|
||||
|
||||
# Check if UV is installed
|
||||
if ! command -v uv &> /dev/null; then
|
||||
log_error "UV is not installed. Please install UV first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Stop any existing Django processes on port 8000
|
||||
log "Stopping any existing Django processes on port 8000..."
|
||||
if lsof -ti :8000 >/dev/null 2>&1; then
|
||||
lsof -ti :8000 | xargs kill -9 2>/dev/null || true
|
||||
log_success "Stopped existing processes"
|
||||
else
|
||||
log "No existing processes found on port 8000"
|
||||
fi
|
||||
|
||||
# Clean up Python cache files
|
||||
log "Cleaning up Python cache files..."
|
||||
find . -type d -name "__pycache__" -exec rm -r {} + 2>/dev/null || true
|
||||
log_success "Cache files cleaned"
|
||||
|
||||
# Install/update dependencies
|
||||
log "Installing/updating dependencies with UV..."
|
||||
uv sync --no-dev || {
|
||||
log_error "Failed to sync dependencies"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Run database migrations
|
||||
log "Running database migrations..."
|
||||
uv run manage.py migrate || {
|
||||
log_error "Database migrations failed"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Collect static files
|
||||
log "Collecting static files..."
|
||||
uv run manage.py collectstatic --noinput || {
|
||||
log_warning "Static file collection failed, continuing anyway"
|
||||
}
|
||||
|
||||
# Start the development server
|
||||
log "Starting Django development server with Tailwind..."
|
||||
log "Server will be available at: http://localhost:8000"
|
||||
log "Press Ctrl+C to stop the server"
|
||||
|
||||
# Start server and capture PID
|
||||
uv run manage.py tailwind runserver 0.0.0.0:8000 &
|
||||
SERVER_PID=$!
|
||||
|
||||
# Save PID to file
|
||||
echo $SERVER_PID > "$PID_FILE"
|
||||
|
||||
log_success "Django server started with PID: $SERVER_PID"
|
||||
log "Server logs are being written to: $LOG_FILE"
|
||||
|
||||
# Wait for server to start
|
||||
sleep 3
|
||||
|
||||
# Check if server is running
|
||||
if kill -0 $SERVER_PID 2>/dev/null; then
|
||||
log_success "Server is running successfully!"
|
||||
|
||||
# Monitor the process
|
||||
wait $SERVER_PID
|
||||
else
|
||||
log_error "Server failed to start"
|
||||
rm -f "$PID_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Cleanup on exit
|
||||
cleanup() {
|
||||
log "Shutting down server..."
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
PID=$(cat "$PID_FILE")
|
||||
if kill -0 $PID 2>/dev/null; then
|
||||
kill $PID
|
||||
log_success "Server stopped"
|
||||
fi
|
||||
rm -f "$PID_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
trap cleanup EXIT INT TERM
|
||||
@@ -1,108 +0,0 @@
|
||||
from django.utils import timezone
|
||||
from parks.models import Park, ParkLocation
|
||||
from rides.models import Ride, RideModel, RollerCoasterStats
|
||||
from rides.models import Manufacturer
|
||||
|
||||
# Create Cedar Point
|
||||
park, _ = Park.objects.get_or_create(
|
||||
name="Cedar Point",
|
||||
slug="cedar-point",
|
||||
defaults={
|
||||
"description": (
|
||||
"Cedar Point is a 364-acre amusement park located on a Lake Erie "
|
||||
"peninsula in Sandusky, Ohio."
|
||||
),
|
||||
"website": "https://www.cedarpoint.com",
|
||||
"size_acres": 364,
|
||||
"opening_date": timezone.datetime(
|
||||
1870, 1, 1
|
||||
).date(), # Cedar Point opened in 1870
|
||||
},
|
||||
)
|
||||
|
||||
# Create location for Cedar Point
|
||||
location, _ = ParkLocation.objects.get_or_create(
|
||||
park=park,
|
||||
defaults={
|
||||
"street_address": "1 Cedar Point Dr",
|
||||
"city": "Sandusky",
|
||||
"state": "OH",
|
||||
"postal_code": "44870",
|
||||
"country": "USA",
|
||||
},
|
||||
)
|
||||
# Set coordinates using the helper method
|
||||
location.set_coordinates(-82.6839, 41.4822) # longitude, latitude
|
||||
location.save()
|
||||
|
||||
# Create Intamin as manufacturer
|
||||
bm, _ = Manufacturer.objects.get_or_create(
|
||||
name="Intamin",
|
||||
slug="intamin",
|
||||
defaults={
|
||||
"description": (
|
||||
"Intamin Amusement Rides is a design company known for creating "
|
||||
"some of the most thrilling and innovative roller coasters in the world."
|
||||
),
|
||||
"website": "https://www.intaminworldwide.com",
|
||||
},
|
||||
)
|
||||
|
||||
# Create Giga Coaster model
|
||||
giga_model, _ = RideModel.objects.get_or_create(
|
||||
name="Giga Coaster",
|
||||
manufacturer=bm,
|
||||
defaults={
|
||||
"description": (
|
||||
"A roller coaster type characterized by a height between 300–399 feet "
|
||||
"and a complete circuit."
|
||||
),
|
||||
"category": "RC", # Roller Coaster
|
||||
},
|
||||
)
|
||||
|
||||
# Create Millennium Force
|
||||
millennium, _ = Ride.objects.get_or_create(
|
||||
name="Millennium Force",
|
||||
slug="millennium-force",
|
||||
defaults={
|
||||
"description": (
|
||||
"Millennium Force is a steel roller coaster located at Cedar Point "
|
||||
"amusement park in Sandusky, Ohio. It was built by Intamin of "
|
||||
"Switzerland and opened on May 13, 2000 as the world's first giga "
|
||||
"coaster, a class of roller coasters having a height between 300 "
|
||||
"and 399 feet and a complete circuit."
|
||||
),
|
||||
"park": park,
|
||||
"category": "RC",
|
||||
"manufacturer": bm,
|
||||
"ride_model": giga_model,
|
||||
"status": "OPERATING",
|
||||
"opening_date": timezone.datetime(2000, 5, 13).date(),
|
||||
"min_height_in": 48, # 48 inches minimum height
|
||||
"capacity_per_hour": 1300,
|
||||
"ride_duration_seconds": 120, # 2 minutes
|
||||
},
|
||||
)
|
||||
|
||||
# Create stats for Millennium Force
|
||||
RollerCoasterStats.objects.get_or_create(
|
||||
ride=millennium,
|
||||
defaults={
|
||||
"height_ft": 310,
|
||||
"length_ft": 6595,
|
||||
"speed_mph": 93,
|
||||
"inversions": 0,
|
||||
"ride_time_seconds": 120,
|
||||
"track_material": "STEEL",
|
||||
"roller_coaster_type": "SITDOWN",
|
||||
"max_drop_height_ft": 300,
|
||||
"launch_type": "CHAIN",
|
||||
"train_style": "Open-air stadium seating",
|
||||
"trains_count": 3,
|
||||
"cars_per_train": 9,
|
||||
"seats_per_car": 4,
|
||||
},
|
||||
)
|
||||
|
||||
print("Initial data created successfully!")
|
||||
@@ -1,494 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ThrillWiki Deployment Script
|
||||
# Deploys the application to various environments
|
||||
|
||||
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
|
||||
|
||||
# Script directory and project root
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../" && pwd)"
|
||||
|
||||
# Configuration
|
||||
DEPLOY_ENV="production"
|
||||
DEPLOY_DIR="$PROJECT_ROOT/deploy"
|
||||
BACKUP_DIR="$PROJECT_ROOT/backups"
|
||||
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
|
||||
|
||||
# Function to print colored output
|
||||
print_status() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Function to check if a command exists
|
||||
command_exists() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Function to check deployment requirements
|
||||
check_deployment_requirements() {
|
||||
print_status "Checking deployment requirements..."
|
||||
|
||||
local missing_deps=()
|
||||
|
||||
# Check if deployment artifacts exist
|
||||
if [ ! -d "$DEPLOY_DIR" ]; then
|
||||
missing_deps+=("deployment_artifacts")
|
||||
fi
|
||||
|
||||
if [ ! -f "$DEPLOY_DIR/manifest.json" ]; then
|
||||
missing_deps+=("deployment_manifest")
|
||||
fi
|
||||
|
||||
# Check for deployment tools
|
||||
if [ "$DEPLOY_METHOD" = "docker" ]; then
|
||||
if ! command_exists docker; then
|
||||
missing_deps+=("docker")
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$DEPLOY_METHOD" = "rsync" ]; then
|
||||
if ! command_exists rsync; then
|
||||
missing_deps+=("rsync")
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ${#missing_deps[@]} -ne 0 ]; then
|
||||
print_error "Missing deployment requirements: ${missing_deps[*]}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "Deployment requirements met!"
|
||||
}
|
||||
|
||||
# Function to create backup
|
||||
create_backup() {
|
||||
print_status "Creating backup before deployment..."
|
||||
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
local backup_path="$BACKUP_DIR/backup_$TIMESTAMP"
|
||||
|
||||
# Create backup directory
|
||||
mkdir -p "$backup_path"
|
||||
|
||||
# Backup current deployment if it exists
|
||||
if [ -d "$DEPLOY_TARGET" ]; then
|
||||
print_status "Backing up current deployment..."
|
||||
cp -r "$DEPLOY_TARGET" "$backup_path/current"
|
||||
fi
|
||||
|
||||
# Backup database if requested
|
||||
if [ "$BACKUP_DATABASE" = true ]; then
|
||||
print_status "Backing up database..."
|
||||
# This would depend on your database setup
|
||||
# For SQLite:
|
||||
if [ -f "$PROJECT_ROOT/backend/db.sqlite3" ]; then
|
||||
cp "$PROJECT_ROOT/backend/db.sqlite3" "$backup_path/database.sqlite3"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Backup environment files
|
||||
if [ -f "$PROJECT_ROOT/.env" ]; then
|
||||
cp "$PROJECT_ROOT/.env" "$backup_path/.env.backup"
|
||||
fi
|
||||
|
||||
print_success "Backup created: $backup_path"
|
||||
}
|
||||
|
||||
# Function to prepare deployment artifacts
|
||||
prepare_artifacts() {
|
||||
print_status "Preparing deployment artifacts..."
|
||||
|
||||
# Check if build artifacts exist
|
||||
if [ ! -d "$DEPLOY_DIR" ]; then
|
||||
print_error "No deployment artifacts found. Please run build-all.sh first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate manifest
|
||||
if [ -f "$DEPLOY_DIR/manifest.json" ]; then
|
||||
print_status "Validating deployment manifest..."
|
||||
# You could add more validation here
|
||||
cat "$DEPLOY_DIR/manifest.json" | grep -q "build_timestamp" || {
|
||||
print_error "Invalid deployment manifest"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
print_success "Deployment artifacts ready!"
|
||||
}
|
||||
|
||||
# Function to deploy to local development
|
||||
deploy_local() {
|
||||
print_status "Deploying to local development environment..."
|
||||
|
||||
local target_dir="$PROJECT_ROOT/deployment"
|
||||
|
||||
# Create target directory
|
||||
mkdir -p "$target_dir"
|
||||
|
||||
# Copy artifacts
|
||||
print_status "Copying frontend artifacts..."
|
||||
cp -r "$DEPLOY_DIR/frontend" "$target_dir/"
|
||||
|
||||
print_status "Copying backend artifacts..."
|
||||
mkdir -p "$target_dir/backend"
|
||||
cp -r "$DEPLOY_DIR/backend/staticfiles" "$target_dir/backend/"
|
||||
|
||||
# Copy deployment configuration
|
||||
cp "$DEPLOY_DIR/manifest.json" "$target_dir/"
|
||||
|
||||
print_success "Local deployment completed!"
|
||||
print_status "Deployment available at: $target_dir"
|
||||
}
|
||||
|
||||
# Function to deploy via rsync
|
||||
deploy_rsync() {
|
||||
print_status "Deploying via rsync..."
|
||||
|
||||
if [ -z "$DEPLOY_HOST" ]; then
|
||||
print_error "DEPLOY_HOST not set for rsync deployment"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local target=""
|
||||
|
||||
if [ -n "$DEPLOY_USER" ]; then
|
||||
target="$DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH"
|
||||
else
|
||||
target="$DEPLOY_HOST:$DEPLOY_PATH"
|
||||
fi
|
||||
|
||||
print_status "Syncing files to $target..."
|
||||
|
||||
# Rsync options:
|
||||
# -a: archive mode (recursive, preserves attributes)
|
||||
# -v: verbose
|
||||
# -z: compress during transfer
|
||||
# --delete: delete files not in source
|
||||
# --exclude: exclude certain files
|
||||
rsync -avz --delete \
|
||||
--exclude='.git' \
|
||||
--exclude='node_modules' \
|
||||
--exclude='__pycache__' \
|
||||
--exclude='*.log' \
|
||||
"$DEPLOY_DIR/" "$target"
|
||||
|
||||
print_success "Rsync deployment completed!"
|
||||
}
|
||||
|
||||
# Function to deploy via Docker
|
||||
deploy_docker() {
|
||||
print_status "Deploying via Docker..."
|
||||
|
||||
local image_name="thrillwiki-$DEPLOY_ENV"
|
||||
local container_name="thrillwiki-$DEPLOY_ENV"
|
||||
|
||||
# Build Docker image
|
||||
print_status "Building Docker image: $image_name"
|
||||
docker build -t "$image_name" \
|
||||
--build-arg DEPLOY_ENV="$DEPLOY_ENV" \
|
||||
-f "$PROJECT_ROOT/Dockerfile" \
|
||||
"$PROJECT_ROOT"
|
||||
|
||||
# Stop existing container
|
||||
if docker ps -q -f name="$container_name" | grep -q .; then
|
||||
print_status "Stopping existing container..."
|
||||
docker stop "$container_name"
|
||||
fi
|
||||
|
||||
# Remove existing container
|
||||
if docker ps -a -q -f name="$container_name" | grep -q .; then
|
||||
print_status "Removing existing container..."
|
||||
docker rm "$container_name"
|
||||
fi
|
||||
|
||||
# Run new container
|
||||
print_status "Starting new container..."
|
||||
docker run -d \
|
||||
--name "$container_name" \
|
||||
-p 8080:80 \
|
||||
-e DEPLOY_ENV="$DEPLOY_ENV" \
|
||||
"$image_name"
|
||||
|
||||
print_success "Docker deployment completed!"
|
||||
print_status "Container: $container_name"
|
||||
print_status "URL: http://localhost:8080"
|
||||
}
|
||||
|
||||
# Function to run post-deployment checks
|
||||
run_post_deploy_checks() {
|
||||
print_status "Running post-deployment checks..."
|
||||
|
||||
local health_url=""
|
||||
|
||||
case $DEPLOY_METHOD in
|
||||
"local")
|
||||
health_url="http://localhost:8080/health"
|
||||
;;
|
||||
"docker")
|
||||
health_url="http://localhost:8080/health"
|
||||
;;
|
||||
"rsync")
|
||||
if [ -n "$DEPLOY_HOST" ]; then
|
||||
health_url="http://$DEPLOY_HOST/health"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "$health_url" ]; then
|
||||
print_status "Checking health endpoint: $health_url"
|
||||
if curl -s -f "$health_url" > /dev/null 2>&1; then
|
||||
print_success "Health check passed!"
|
||||
else
|
||||
print_warning "Health check failed. Please verify deployment."
|
||||
fi
|
||||
fi
|
||||
|
||||
print_success "Post-deployment checks completed!"
|
||||
}
|
||||
|
||||
# Function to generate deployment report
|
||||
generate_deployment_report() {
|
||||
print_status "Generating deployment report..."
|
||||
|
||||
local report_file="$PROJECT_ROOT/deployment-report-$DEPLOY_ENV-$TIMESTAMP.txt"
|
||||
|
||||
cat > "$report_file" << EOF
|
||||
ThrillWiki Deployment Report
|
||||
============================
|
||||
|
||||
Deployment Information:
|
||||
- Deployment Date: $(date)
|
||||
- Environment: $DEPLOY_ENV
|
||||
- Method: $DEPLOY_METHOD
|
||||
- Project Root: $PROJECT_ROOT
|
||||
|
||||
Deployment Details:
|
||||
- Source Directory: $DEPLOY_DIR
|
||||
- Target: $DEPLOY_TARGET
|
||||
- Backup Created: $([ "$CREATE_BACKUP" = true ] && echo "Yes" || echo "No")
|
||||
|
||||
Build Information:
|
||||
$(if [ -f "$DEPLOY_DIR/manifest.json" ]; then
|
||||
cat "$DEPLOY_DIR/manifest.json"
|
||||
else
|
||||
echo "No manifest found"
|
||||
fi)
|
||||
|
||||
System Information:
|
||||
- Hostname: $(hostname)
|
||||
- User: $(whoami)
|
||||
- OS: $(uname -s) $(uname -r)
|
||||
|
||||
Deployment Status: SUCCESS
|
||||
|
||||
Post-Deployment:
|
||||
- Health Check: $([ "$RUN_CHECKS" = true ] && echo "Run" || echo "Skipped")
|
||||
- Backup Location: $([ "$CREATE_BACKUP" = true ] && echo "$BACKUP_DIR/backup_$TIMESTAMP" || echo "None")
|
||||
|
||||
EOF
|
||||
|
||||
print_success "Deployment report generated: $report_file"
|
||||
}
|
||||
|
||||
# Function to show usage
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
Usage: $0 [ENVIRONMENT] [OPTIONS]
|
||||
|
||||
Deploy ThrillWiki to the specified environment.
|
||||
|
||||
Environments:
|
||||
dev Development environment
|
||||
staging Staging environment
|
||||
production Production environment
|
||||
|
||||
Options:
|
||||
-h, --help Show this help message
|
||||
-m, --method METHOD Deployment method (local, rsync, docker)
|
||||
--no-backup Skip backup creation
|
||||
--no-checks Skip post-deployment checks
|
||||
--no-report Skip deployment report generation
|
||||
|
||||
Examples:
|
||||
$0 production # Deploy to production using default method
|
||||
$0 staging --method docker # Deploy to staging using Docker
|
||||
$0 dev --no-backup # Deploy to dev without backup
|
||||
|
||||
Environment Variables:
|
||||
DEPLOY_METHOD Deployment method (default: local)
|
||||
DEPLOY_HOST Target host for rsync deployment
|
||||
DEPLOY_USER SSH user for rsync deployment
|
||||
DEPLOY_PATH Target path for rsync deployment
|
||||
CREATE_BACKUP Create backup before deployment (default: true)
|
||||
BACKUP_DATABASE Backup database (default: false)
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
DEPLOY_METHOD="local"
|
||||
CREATE_BACKUP=true
|
||||
RUN_CHECKS=true
|
||||
SKIP_REPORT=false
|
||||
|
||||
# Get environment from first argument
|
||||
if [ $# -gt 0 ]; then
|
||||
case $1 in
|
||||
dev|staging|production)
|
||||
DEPLOY_ENV="$1"
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
print_error "Invalid environment: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Parse remaining arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
-m|--method)
|
||||
DEPLOY_METHOD="$2"
|
||||
shift 2
|
||||
;;
|
||||
--no-backup)
|
||||
CREATE_BACKUP=false
|
||||
shift
|
||||
;;
|
||||
--no-checks)
|
||||
RUN_CHECKS=false
|
||||
shift
|
||||
;;
|
||||
--no-report)
|
||||
SKIP_REPORT=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown option: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Override from environment variables
|
||||
if [ ! -z "$DEPLOY_METHOD_ENV" ]; then
|
||||
DEPLOY_METHOD=$DEPLOY_METHOD_ENV
|
||||
fi
|
||||
|
||||
if [ "$CREATE_BACKUP_ENV" = "false" ]; then
|
||||
CREATE_BACKUP=false
|
||||
fi
|
||||
|
||||
# Set deployment target based on method
|
||||
case $DEPLOY_METHOD in
|
||||
"local")
|
||||
DEPLOY_TARGET="$PROJECT_ROOT/deployment"
|
||||
;;
|
||||
"rsync")
|
||||
DEPLOY_TARGET="${DEPLOY_USER:-}$(if [ -n "$DEPLOY_USER" ]; then echo "@"; fi)${DEPLOY_HOST:-localhost}:${DEPLOY_PATH:-/var/www/thrillwiki}"
|
||||
;;
|
||||
"docker")
|
||||
DEPLOY_TARGET="docker_container"
|
||||
;;
|
||||
*)
|
||||
print_error "Unsupported deployment method: $DEPLOY_METHOD"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Print banner
|
||||
echo -e "${GREEN}"
|
||||
echo "=========================================="
|
||||
echo " ThrillWiki Deployment"
|
||||
echo "=========================================="
|
||||
echo -e "${NC}"
|
||||
|
||||
print_status "Environment: $DEPLOY_ENV"
|
||||
print_status "Method: $DEPLOY_METHOD"
|
||||
print_status "Target: $DEPLOY_TARGET"
|
||||
print_status "Create backup: $CREATE_BACKUP"
|
||||
|
||||
# Check deployment requirements
|
||||
check_deployment_requirements
|
||||
|
||||
# Prepare deployment artifacts
|
||||
prepare_artifacts
|
||||
|
||||
# Create backup if requested
|
||||
if [ "$CREATE_BACKUP" = true ]; then
|
||||
create_backup
|
||||
else
|
||||
print_warning "Skipping backup creation as requested"
|
||||
fi
|
||||
|
||||
# Deploy based on method
|
||||
case $DEPLOY_METHOD in
|
||||
"local")
|
||||
deploy_local
|
||||
;;
|
||||
"rsync")
|
||||
deploy_rsync
|
||||
;;
|
||||
"docker")
|
||||
deploy_docker
|
||||
;;
|
||||
*)
|
||||
print_error "Unsupported deployment method: $DEPLOY_METHOD"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Run post-deployment checks
|
||||
if [ "$RUN_CHECKS" = true ]; then
|
||||
run_post_deploy_checks
|
||||
else
|
||||
print_warning "Skipping post-deployment checks as requested"
|
||||
fi
|
||||
|
||||
# Generate deployment report
|
||||
if [ "$SKIP_REPORT" = false ]; then
|
||||
generate_deployment_report
|
||||
else
|
||||
print_warning "Skipping deployment report generation as requested"
|
||||
fi
|
||||
|
||||
print_success "Deployment completed successfully!"
|
||||
echo ""
|
||||
print_status "Environment: $DEPLOY_ENV"
|
||||
print_status "Method: $DEPLOY_METHOD"
|
||||
print_status "Target: $DEPLOY_TARGET"
|
||||
echo ""
|
||||
print_status "Deployment report: $PROJECT_ROOT/deployment-report-$DEPLOY_ENV-$TIMESTAMP.txt"
|
||||
@@ -1,368 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ThrillWiki Development Environment Setup
|
||||
# Sets up the complete development environment for both backend and frontend
|
||||
|
||||
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
|
||||
|
||||
# Script directory and project root
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../" && pwd)"
|
||||
|
||||
# Configuration
|
||||
BACKEND_DIR="$PROJECT_ROOT/backend"
|
||||
FRONTEND_DIR="$PROJECT_ROOT/frontend"
|
||||
|
||||
# Function to print colored output
|
||||
print_status() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Function to check if a command exists
|
||||
command_exists() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Function to check system requirements
|
||||
check_requirements() {
|
||||
print_status "Checking system requirements..."
|
||||
|
||||
local missing_deps=()
|
||||
|
||||
# Check Python
|
||||
if ! command_exists python3; then
|
||||
missing_deps+=("python3")
|
||||
else
|
||||
local python_version=$(python3 --version | cut -d' ' -f2 | cut -d'.' -f1,2)
|
||||
if (( $(echo "$python_version < 3.11" | bc -l) )); then
|
||||
print_warning "Python version $python_version detected. Python 3.11+ recommended."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check uv
|
||||
if ! command_exists uv; then
|
||||
missing_deps+=("uv")
|
||||
fi
|
||||
|
||||
# Check Node.js
|
||||
if ! command_exists node; then
|
||||
missing_deps+=("node")
|
||||
else
|
||||
local node_version=$(node --version | cut -d'v' -f2 | cut -d'.' -f1)
|
||||
if (( node_version < 18 )); then
|
||||
print_warning "Node.js version $node_version detected. Node.js 18+ recommended."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check pnpm
|
||||
if ! command_exists pnpm; then
|
||||
missing_deps+=("pnpm")
|
||||
fi
|
||||
|
||||
# Check PostgreSQL (optional)
|
||||
if ! command_exists psql; then
|
||||
print_warning "PostgreSQL not found. SQLite will be used for development."
|
||||
fi
|
||||
|
||||
# Check Redis (optional)
|
||||
if ! command_exists redis-server; then
|
||||
print_warning "Redis not found. Some features may not work."
|
||||
fi
|
||||
|
||||
if [ ${#missing_deps[@]} -ne 0 ]; then
|
||||
print_error "Missing required dependencies: ${missing_deps[*]}"
|
||||
print_status "Please install the missing dependencies and run this script again."
|
||||
print_status "Installation instructions:"
|
||||
print_status " - Python 3.11+: https://www.python.org/downloads/"
|
||||
print_status " - uv: pip install uv"
|
||||
print_status " - Node.js 18+: https://nodejs.org/"
|
||||
print_status " - pnpm: npm install -g pnpm"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "All system requirements met!"
|
||||
}
|
||||
|
||||
# Function to setup backend
|
||||
setup_backend() {
|
||||
print_status "Setting up Django backend..."
|
||||
|
||||
cd "$BACKEND_DIR"
|
||||
|
||||
# Install Python dependencies with uv
|
||||
print_status "Installing Python dependencies..."
|
||||
if [ ! -d ".venv" ]; then
|
||||
uv sync
|
||||
else
|
||||
print_warning "Virtual environment already exists. Updating dependencies..."
|
||||
uv sync
|
||||
fi
|
||||
|
||||
# Create .env file if it doesn't exist
|
||||
if [ ! -f ".env" ]; then
|
||||
print_status "Creating backend .env file..."
|
||||
cp .env.example .env
|
||||
print_warning "Please edit backend/.env with your settings"
|
||||
else
|
||||
print_warning "Backend .env file already exists"
|
||||
fi
|
||||
|
||||
# Run database migrations
|
||||
print_status "Running database migrations..."
|
||||
uv run manage.py migrate
|
||||
|
||||
# Create superuser (optional)
|
||||
print_status "Creating Django superuser..."
|
||||
echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.filter(username='admin').exists() or User.objects.create_superuser('admin', 'admin@example.com', 'admin')" | uv run manage.py shell
|
||||
|
||||
print_success "Backend setup completed!"
|
||||
cd "$PROJECT_ROOT"
|
||||
}
|
||||
|
||||
# Function to setup frontend
|
||||
setup_frontend() {
|
||||
print_status "Setting up Vue.js frontend..."
|
||||
|
||||
cd "$FRONTEND_DIR"
|
||||
|
||||
# Install Node.js dependencies
|
||||
print_status "Installing Node.js dependencies..."
|
||||
if [ ! -d "node_modules" ]; then
|
||||
pnpm install
|
||||
else
|
||||
print_warning "node_modules already exists. Updating dependencies..."
|
||||
pnpm install
|
||||
fi
|
||||
|
||||
# Create environment files if they don't exist
|
||||
if [ ! -f ".env.local" ]; then
|
||||
print_status "Creating frontend .env.local file..."
|
||||
cp .env.development .env.local
|
||||
print_warning "Please edit frontend/.env.local with your settings"
|
||||
else
|
||||
print_warning "Frontend .env.local file already exists"
|
||||
fi
|
||||
|
||||
print_success "Frontend setup completed!"
|
||||
cd "$PROJECT_ROOT"
|
||||
}
|
||||
|
||||
# Function to setup root environment
|
||||
setup_root_env() {
|
||||
print_status "Setting up root environment..."
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
# Create root .env file if it doesn't exist
|
||||
if [ ! -f ".env" ]; then
|
||||
print_status "Creating root .env file..."
|
||||
cp .env.example .env
|
||||
print_warning "Please edit .env with your settings"
|
||||
else
|
||||
print_warning "Root .env file already exists"
|
||||
fi
|
||||
|
||||
print_success "Root environment setup completed!"
|
||||
}
|
||||
|
||||
# Function to verify setup
|
||||
verify_setup() {
|
||||
print_status "Verifying setup..."
|
||||
|
||||
local issues=()
|
||||
|
||||
# Check backend
|
||||
cd "$BACKEND_DIR"
|
||||
if [ ! -d ".venv" ]; then
|
||||
issues+=("Backend virtual environment not found")
|
||||
fi
|
||||
|
||||
if [ ! -f ".env" ]; then
|
||||
issues+=("Backend .env file not found")
|
||||
fi
|
||||
|
||||
# Check if Django can start
|
||||
if ! uv run manage.py check --settings=config.django.local >/dev/null 2>&1; then
|
||||
issues+=("Django configuration check failed")
|
||||
fi
|
||||
|
||||
cd "$FRONTEND_DIR"
|
||||
|
||||
# Check frontend
|
||||
if [ ! -d "node_modules" ]; then
|
||||
issues+=("Frontend node_modules not found")
|
||||
fi
|
||||
|
||||
if [ ! -f ".env.local" ]; then
|
||||
issues+=("Frontend .env.local file not found")
|
||||
fi
|
||||
|
||||
# Check if Vue can build
|
||||
if ! pnpm run type-check >/dev/null 2>&1; then
|
||||
issues+=("Vue.js type check failed")
|
||||
fi
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
if [ ${#issues[@]} -ne 0 ]; then
|
||||
print_warning "Setup verification found issues:"
|
||||
for issue in "${issues[@]}"; do
|
||||
echo -e " - ${YELLOW}$issue${NC}"
|
||||
done
|
||||
return 1
|
||||
else
|
||||
print_success "Setup verification passed!"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to show usage
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
Usage: $0 [OPTIONS]
|
||||
|
||||
Set up the complete ThrillWiki development environment.
|
||||
|
||||
Options:
|
||||
-h, --help Show this help message
|
||||
-b, --backend-only Setup only the backend
|
||||
-f, --frontend-only Setup only the frontend
|
||||
-y, --yes Skip confirmation prompts
|
||||
--no-verify Skip setup verification
|
||||
|
||||
Examples:
|
||||
$0 # Setup both backend and frontend
|
||||
$0 --backend-only # Setup only backend
|
||||
$0 --frontend-only # Setup only frontend
|
||||
|
||||
Environment Variables:
|
||||
SKIP_CONFIRMATION Set to 'true' to skip confirmation prompts
|
||||
SKIP_VERIFICATION Set to 'true' to skip verification
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
BACKEND_ONLY=false
|
||||
FRONTEND_ONLY=false
|
||||
SKIP_CONFIRMATION=false
|
||||
SKIP_VERIFICATION=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
-b|--backend-only)
|
||||
BACKEND_ONLY=true
|
||||
shift
|
||||
;;
|
||||
-f|--frontend-only)
|
||||
FRONTEND_ONLY=true
|
||||
shift
|
||||
;;
|
||||
-y|--yes)
|
||||
SKIP_CONFIRMATION=true
|
||||
shift
|
||||
;;
|
||||
--no-verify)
|
||||
SKIP_VERIFICATION=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown option: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Override from environment variables
|
||||
if [ "$SKIP_CONFIRMATION" = "true" ] || [ "$SKIP_CONFIRMATION_ENV" = "true" ]; then
|
||||
SKIP_CONFIRMATION=true
|
||||
fi
|
||||
|
||||
if [ "$SKIP_VERIFICATION" = "true" ] || [ "$SKIP_VERIFICATION_ENV" = "true" ]; then
|
||||
SKIP_VERIFICATION=true
|
||||
fi
|
||||
|
||||
# Print banner
|
||||
echo -e "${GREEN}"
|
||||
echo "=========================================="
|
||||
echo " ThrillWiki Development Setup"
|
||||
echo "=========================================="
|
||||
echo -e "${NC}"
|
||||
|
||||
print_status "Project root: $PROJECT_ROOT"
|
||||
|
||||
# Confirmation prompt
|
||||
if [ "$SKIP_CONFIRMATION" = false ]; then
|
||||
echo ""
|
||||
read -p "This will set up the development environment. Continue? (y/N): " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
print_status "Setup cancelled."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check requirements
|
||||
check_requirements
|
||||
|
||||
# Setup components based on options
|
||||
if [ "$BACKEND_ONLY" = true ]; then
|
||||
print_status "Setting up backend only..."
|
||||
setup_backend
|
||||
setup_root_env
|
||||
elif [ "$FRONTEND_ONLY" = true ]; then
|
||||
print_status "Setting up frontend only..."
|
||||
setup_frontend
|
||||
setup_root_env
|
||||
else
|
||||
print_status "Setting up both backend and frontend..."
|
||||
setup_backend
|
||||
setup_frontend
|
||||
setup_root_env
|
||||
fi
|
||||
|
||||
# Verify setup
|
||||
if [ "$SKIP_VERIFICATION" = false ]; then
|
||||
echo ""
|
||||
if verify_setup; then
|
||||
print_success "Development environment setup completed successfully!"
|
||||
echo ""
|
||||
print_status "Next steps:"
|
||||
echo " 1. Edit .env files with your configuration"
|
||||
echo " 2. Start development servers: ./shared/scripts/dev/start-all.sh"
|
||||
echo " 3. Visit http://localhost:5174 for the frontend"
|
||||
echo " 4. Visit http://localhost:8000 for the backend API"
|
||||
echo ""
|
||||
print_status "Happy coding! 🚀"
|
||||
else
|
||||
print_warning "Setup completed with issues. Please review the warnings above."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_success "Development environment setup completed!"
|
||||
print_status "Skipped verification as requested."
|
||||
fi
|
||||
@@ -1,279 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ThrillWiki Development Server Starter
|
||||
# Starts both Django backend and Vue.js frontend servers concurrently
|
||||
|
||||
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
|
||||
|
||||
# Script directory and project root
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../" && pwd)"
|
||||
|
||||
# Configuration
|
||||
BACKEND_PORT=8000
|
||||
FRONTEND_PORT=5174
|
||||
BACKEND_DIR="$PROJECT_ROOT/backend"
|
||||
FRONTEND_DIR="$PROJECT_ROOT/frontend"
|
||||
|
||||
# Function to print colored output
|
||||
print_status() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Function to check if a port is available
|
||||
check_port() {
|
||||
local port=$1
|
||||
if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null ; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to kill process on port
|
||||
kill_port() {
|
||||
local port=$1
|
||||
local pid=$(lsof -ti:$port)
|
||||
if [ ! -z "$pid" ]; then
|
||||
print_warning "Killing process $pid on port $port"
|
||||
kill -9 $pid
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to wait for service to be ready
|
||||
wait_for_service() {
|
||||
local url=$1
|
||||
local service_name=$2
|
||||
local max_attempts=30
|
||||
local attempt=1
|
||||
|
||||
print_status "Waiting for $service_name to be ready at $url"
|
||||
|
||||
while [ $attempt -le $max_attempts ]; do
|
||||
if curl -s -f "$url" > /dev/null 2>&1; then
|
||||
print_success "$service_name is ready!"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -n "."
|
||||
sleep 2
|
||||
((attempt++))
|
||||
done
|
||||
|
||||
print_error "$service_name failed to start after $max_attempts attempts"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Function to start backend server
|
||||
start_backend() {
|
||||
print_status "Starting Django backend server..."
|
||||
|
||||
# Kill any existing process on backend port
|
||||
kill_port $BACKEND_PORT
|
||||
|
||||
# Clean up Python cache files
|
||||
find "$BACKEND_DIR" -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
||||
|
||||
cd "$BACKEND_DIR"
|
||||
|
||||
# Check if virtual environment exists
|
||||
if [ ! -d ".venv" ]; then
|
||||
print_error "Backend virtual environment not found. Please run setup-dev.sh first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start Django server in background
|
||||
print_status "Starting Django development server on port $BACKEND_PORT"
|
||||
uv run manage.py runserver 0.0.0.0:$BACKEND_PORT &
|
||||
BACKEND_PID=$!
|
||||
|
||||
# Wait for backend to be ready
|
||||
wait_for_service "http://localhost:$BACKEND_PORT/api/" "Django backend"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
}
|
||||
|
||||
# Function to start frontend server
|
||||
start_frontend() {
|
||||
print_status "Starting Vue.js frontend server..."
|
||||
|
||||
cd "$FRONTEND_DIR"
|
||||
|
||||
# Check if node_modules exists
|
||||
if [ ! -d "node_modules" ]; then
|
||||
print_error "Frontend dependencies not installed. Please run setup-dev.sh first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start Vue.js dev server in background
|
||||
print_status "Starting Vue.js development server on port $FRONTEND_PORT"
|
||||
pnpm run dev &
|
||||
FRONTEND_PID=$!
|
||||
|
||||
# Wait for frontend to be ready
|
||||
wait_for_service "http://localhost:$FRONTEND_PORT" "Vue.js frontend"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
}
|
||||
|
||||
# Function to cleanup on script exit
|
||||
cleanup() {
|
||||
print_warning "Shutting down development servers..."
|
||||
|
||||
if [ ! -z "$BACKEND_PID" ]; then
|
||||
kill $BACKEND_PID 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if [ ! -z "$FRONTEND_PID" ]; then
|
||||
kill $FRONTEND_PID 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Kill any remaining processes on our ports
|
||||
kill_port $BACKEND_PORT
|
||||
kill_port $FRONTEND_PORT
|
||||
|
||||
print_success "Development servers stopped."
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Function to show usage
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
Usage: $0 [OPTIONS]
|
||||
|
||||
Start both Django backend and Vue.js frontend development servers.
|
||||
|
||||
Options:
|
||||
-h, --help Show this help message
|
||||
-b, --backend-only Start only the backend server
|
||||
-f, --frontend-only Start only the frontend server
|
||||
-p, --production Start in production mode (if applicable)
|
||||
--no-wait Don't wait for services to be ready
|
||||
|
||||
Examples:
|
||||
$0 # Start both servers
|
||||
$0 --backend-only # Start only backend
|
||||
$0 --frontend-only # Start only frontend
|
||||
|
||||
Environment Variables:
|
||||
BACKEND_PORT Backend server port (default: 8000)
|
||||
FRONTEND_PORT Frontend server port (default: 5174)
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
BACKEND_ONLY=false
|
||||
FRONTEND_ONLY=false
|
||||
PRODUCTION=false
|
||||
WAIT_FOR_SERVICES=true
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
-b|--backend-only)
|
||||
BACKEND_ONLY=true
|
||||
shift
|
||||
;;
|
||||
-f|--frontend-only)
|
||||
FRONTEND_ONLY=true
|
||||
shift
|
||||
;;
|
||||
-p|--production)
|
||||
PRODUCTION=true
|
||||
shift
|
||||
;;
|
||||
--no-wait)
|
||||
WAIT_FOR_SERVICES=false
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown option: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Override ports from environment if set
|
||||
if [ ! -z "$BACKEND_PORT_ENV" ]; then
|
||||
BACKEND_PORT=$BACKEND_PORT_ENV
|
||||
fi
|
||||
|
||||
if [ ! -z "$FRONTEND_PORT_ENV" ]; then
|
||||
FRONTEND_PORT=$FRONTEND_PORT_ENV
|
||||
fi
|
||||
|
||||
# Set up signal handlers for graceful shutdown
|
||||
trap cleanup SIGINT SIGTERM
|
||||
|
||||
# Print banner
|
||||
echo -e "${GREEN}"
|
||||
echo "=========================================="
|
||||
echo " ThrillWiki Development Environment"
|
||||
echo "=========================================="
|
||||
echo -e "${NC}"
|
||||
|
||||
print_status "Project root: $PROJECT_ROOT"
|
||||
print_status "Backend port: $BACKEND_PORT"
|
||||
print_status "Frontend port: $FRONTEND_PORT"
|
||||
|
||||
# Check if required tools are available
|
||||
command -v uv >/dev/null 2>&1 || { print_error "uv is required but not installed. Please install uv first."; exit 1; }
|
||||
command -v pnpm >/dev/null 2>&1 || { print_error "pnpm is required but not installed. Please install pnpm first."; exit 1; }
|
||||
command -v curl >/dev/null 2>&1 || { print_error "curl is required but not installed."; exit 1; }
|
||||
|
||||
# Start services based on options
|
||||
if [ "$BACKEND_ONLY" = true ]; then
|
||||
print_status "Starting backend only..."
|
||||
start_backend
|
||||
print_success "Backend server started successfully!"
|
||||
print_status "Backend URL: http://localhost:$BACKEND_PORT"
|
||||
print_status "API URL: http://localhost:$BACKEND_PORT/api/"
|
||||
wait
|
||||
elif [ "$FRONTEND_ONLY" = true ]; then
|
||||
print_status "Starting frontend only..."
|
||||
start_frontend
|
||||
print_success "Frontend server started successfully!"
|
||||
print_status "Frontend URL: http://localhost:$FRONTEND_PORT"
|
||||
wait
|
||||
else
|
||||
print_status "Starting both backend and frontend servers..."
|
||||
start_backend &
|
||||
BACKEND_PID=$!
|
||||
start_frontend &
|
||||
FRONTEND_PID=$!
|
||||
|
||||
print_success "Development servers started successfully!"
|
||||
echo ""
|
||||
print_status "Backend URL: http://localhost:$BACKEND_PORT"
|
||||
print_status "API URL: http://localhost:$BACKEND_PORT/api/"
|
||||
print_status "Frontend URL: http://localhost:$FRONTEND_PORT"
|
||||
echo ""
|
||||
print_status "Press Ctrl+C to stop all servers"
|
||||
|
||||
# Wait for both processes
|
||||
wait
|
||||
fi
|
||||
@@ -1,147 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ThrillWiki Development Server Script
|
||||
# This script sets up the proper environment variables and runs the Django development server
|
||||
|
||||
set -e # Exit on any error
|
||||
|
||||
echo "🚀 Starting ThrillWiki Development Server..."
|
||||
|
||||
# Change to the project directory (parent of scripts folder)
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
# Set Django environment to local development
|
||||
export DJANGO_SETTINGS_MODULE="config.django.local"
|
||||
|
||||
# Core Django settings
|
||||
export DEBUG="True"
|
||||
export SECRET_KEY="django-insecure-dev-key-not-for-production-$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)"
|
||||
|
||||
# Allowed hosts for development
|
||||
export ALLOWED_HOSTS="localhost,127.0.0.1,0.0.0.0"
|
||||
|
||||
# CSRF trusted origins for development
|
||||
export CSRF_TRUSTED_ORIGINS="http://localhost:8000,http://127.0.0.1:8000,https://127.0.0.1:8000"
|
||||
|
||||
# Database configuration (PostgreSQL with PostGIS)
|
||||
export DATABASE_URL="postgis://thrillwiki_user:thrillwiki@localhost:5432/thrillwiki_test_db"
|
||||
|
||||
# Cache configuration (use locmem for development if Redis not available)
|
||||
export CACHE_URL="locmemcache://"
|
||||
export REDIS_URL="redis://127.0.0.1:6379/1"
|
||||
|
||||
# CORS settings for API development
|
||||
export CORS_ALLOW_ALL_ORIGINS="True"
|
||||
export CORS_ALLOWED_ORIGINS=""
|
||||
|
||||
# Email configuration for development (console backend)
|
||||
export EMAIL_URL="consolemail://"
|
||||
|
||||
# GeoDjango library paths for macOS (adjust if needed)
|
||||
export GDAL_LIBRARY_PATH="/opt/homebrew/lib/libgdal.dylib"
|
||||
export GEOS_LIBRARY_PATH="/opt/homebrew/lib/libgeos_c.dylib"
|
||||
|
||||
# API rate limiting (generous for development)
|
||||
export API_RATE_LIMIT_PER_MINUTE="1000"
|
||||
export API_RATE_LIMIT_PER_HOUR="10000"
|
||||
|
||||
# Cache settings
|
||||
export CACHE_MIDDLEWARE_SECONDS="1" # Very short cache for development
|
||||
export CACHE_MIDDLEWARE_KEY_PREFIX="thrillwiki_dev"
|
||||
|
||||
# Social auth settings (you can set these if you have them)
|
||||
# export GOOGLE_OAUTH2_CLIENT_ID=""
|
||||
# export GOOGLE_OAUTH2_CLIENT_SECRET=""
|
||||
# export DISCORD_CLIENT_ID=""
|
||||
# export DISCORD_CLIENT_SECRET=""
|
||||
|
||||
# Create necessary directories
|
||||
echo "📁 Creating necessary directories..."
|
||||
mkdir -p logs
|
||||
mkdir -p profiles
|
||||
mkdir -p media
|
||||
mkdir -p staticfiles
|
||||
mkdir -p static/css
|
||||
|
||||
# Check if virtual environment is activated
|
||||
if [[ -z "$VIRTUAL_ENV" ]] && [[ -d ".venv" ]]; then
|
||||
echo "🔧 Activating virtual environment..."
|
||||
source .venv/bin/activate
|
||||
fi
|
||||
|
||||
# Run database migrations if needed
|
||||
echo "🗄️ Checking database migrations..."
|
||||
if uv run manage.py migrate --check 2>/dev/null; then
|
||||
echo "✅ Database migrations are up to date"
|
||||
else
|
||||
echo "🔄 Running database migrations..."
|
||||
uv run manage.py migrate --noinput
|
||||
fi
|
||||
echo "Resetting database..."
|
||||
if uv run manage.py seed_sample_data 2>/dev/null; then
|
||||
echo "Seeding complete!"
|
||||
else
|
||||
echo "Seeding test data to database..."
|
||||
uv run manage.py seed_sample_data
|
||||
fi
|
||||
|
||||
# Create superuser if it doesn't exist
|
||||
echo "👤 Checking for superuser..."
|
||||
if ! uv run manage.py shell -c "from django.contrib.auth import get_user_model; User = get_user_model(); exit(0 if User.objects.filter(is_superuser=True).exists() else 1)" 2>/dev/null; then
|
||||
echo "👤 Creating development superuser (admin/admin)..."
|
||||
uv run manage.py shell -c "
|
||||
from django.contrib.auth import get_user_model
|
||||
User = get_user_model()
|
||||
if not User.objects.filter(username='admin').exists():
|
||||
User.objects.create_superuser('admin', 'admin@example.com', 'admin')
|
||||
print('Created superuser: admin/admin')
|
||||
else:
|
||||
print('Superuser already exists')
|
||||
"
|
||||
fi
|
||||
|
||||
# Collect static files for development
|
||||
echo "📦 Collecting static files..."
|
||||
uv run manage.py collectstatic --noinput --clear
|
||||
|
||||
# Build Tailwind CSS
|
||||
if command -v npm &> /dev/null; then
|
||||
echo "🎨 Building Tailwind CSS..."
|
||||
uv run manage.py tailwind build
|
||||
else
|
||||
echo "⚠️ npm not found, skipping Tailwind CSS build"
|
||||
fi
|
||||
|
||||
# Run system checks
|
||||
echo "🔍 Running system checks..."
|
||||
if uv run manage.py check; then
|
||||
echo "✅ System checks passed"
|
||||
else
|
||||
echo "❌ System checks failed, but continuing..."
|
||||
fi
|
||||
|
||||
# Display environment info
|
||||
echo ""
|
||||
echo "🌍 Development Environment:"
|
||||
echo " - Settings Module: $DJANGO_SETTINGS_MODULE"
|
||||
echo " - Debug Mode: $DEBUG"
|
||||
echo " - Database: PostgreSQL with PostGIS"
|
||||
echo " - Cache: Local memory cache"
|
||||
echo " - Admin URL: http://localhost:8000/admin/"
|
||||
echo " - Admin User: admin / admin"
|
||||
echo " - Silk Profiler: http://localhost:8000/silk/"
|
||||
echo " - Debug Toolbar: Available on debug pages"
|
||||
echo " - API Documentation: http://localhost:8000/api/docs/"
|
||||
echo ""
|
||||
|
||||
# Start the development server
|
||||
echo "🌟 Starting Django development server on http://localhost:8000"
|
||||
echo "Press Ctrl+C to stop the server"
|
||||
echo ""
|
||||
|
||||
# Use runserver_plus if django-extensions is available, otherwise use standard runserver
|
||||
if uv run python -c "import django_extensions" 2>/dev/null; then
|
||||
exec uv run manage.py runserver_plus 0.0.0.0:8000
|
||||
else
|
||||
exec uv run manage.py runserver 0.0.0.0:8000
|
||||
fi
|
||||
@@ -1,234 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
GitHub OAuth Device Flow Authentication for ThrillWiki CI/CD
|
||||
This script implements GitHub's device flow to securely obtain access tokens.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import time
|
||||
import requests
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
# GitHub OAuth App Configuration
|
||||
CLIENT_ID = "Iv23liOX5Hp75AxhUvIe"
|
||||
TOKEN_FILE = ".github-token"
|
||||
|
||||
|
||||
def parse_response(response):
|
||||
"""Parse HTTP response and handle errors."""
|
||||
if response.status_code in [200, 201]:
|
||||
return response.json()
|
||||
elif response.status_code == 401:
|
||||
print("You are not authorized. Run the `login` command.")
|
||||
sys.exit(1)
|
||||
else:
|
||||
print(f"HTTP {response.status_code}: {response.text}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def request_device_code():
|
||||
"""Request a device code from GitHub."""
|
||||
url = "https://github.com/login/device/code"
|
||||
data = {"client_id": CLIENT_ID}
|
||||
headers = {"Accept": "application/json"}
|
||||
|
||||
response = requests.post(url, data=data, headers=headers)
|
||||
return parse_response(response)
|
||||
|
||||
|
||||
def request_token(device_code):
|
||||
"""Request an access token using the device code."""
|
||||
url = "https://github.com/login/oauth/access_token"
|
||||
data = {
|
||||
"client_id": CLIENT_ID,
|
||||
"device_code": device_code,
|
||||
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
|
||||
}
|
||||
headers = {"Accept": "application/json"}
|
||||
|
||||
response = requests.post(url, data=data, headers=headers)
|
||||
return parse_response(response)
|
||||
|
||||
|
||||
def poll_for_token(device_code, interval):
|
||||
"""Poll GitHub for the access token after user authorization."""
|
||||
print("Waiting for authorization...")
|
||||
|
||||
while True:
|
||||
response = request_token(device_code)
|
||||
error = response.get("error")
|
||||
access_token = response.get("access_token")
|
||||
|
||||
if error:
|
||||
if error == "authorization_pending":
|
||||
# User hasn't entered the code yet
|
||||
print(".", end="", flush=True)
|
||||
time.sleep(interval)
|
||||
continue
|
||||
elif error == "slow_down":
|
||||
# Polling too fast
|
||||
time.sleep(interval + 5)
|
||||
continue
|
||||
elif error == "expired_token":
|
||||
print("\nThe device code has expired. Please run `login` again.")
|
||||
sys.exit(1)
|
||||
elif error == "access_denied":
|
||||
print("\nLogin cancelled by user.")
|
||||
sys.exit(1)
|
||||
else:
|
||||
print(f"\nError: {response}")
|
||||
sys.exit(1)
|
||||
|
||||
# Success! Save the token
|
||||
token_path = Path(TOKEN_FILE)
|
||||
token_path.write_text(access_token)
|
||||
token_path.chmod(0o600) # Read/write for owner only
|
||||
|
||||
print(f"\nToken saved to {TOKEN_FILE}")
|
||||
break
|
||||
|
||||
|
||||
def login():
|
||||
"""Initiate the GitHub OAuth device flow login process."""
|
||||
print("Starting GitHub authentication...")
|
||||
|
||||
device_response = request_device_code()
|
||||
verification_uri = device_response["verification_uri"]
|
||||
user_code = device_response["user_code"]
|
||||
device_code = device_response["device_code"]
|
||||
interval = device_response["interval"]
|
||||
|
||||
print(f"\nPlease visit: {verification_uri}")
|
||||
print(f"and enter code: {user_code}")
|
||||
print("\nWaiting for you to complete authorization in your browser...")
|
||||
|
||||
poll_for_token(device_code, interval)
|
||||
print("Successfully authenticated!")
|
||||
return True
|
||||
|
||||
|
||||
def whoami():
|
||||
"""Display information about the authenticated user."""
|
||||
token_path = Path(TOKEN_FILE)
|
||||
|
||||
if not token_path.exists():
|
||||
print("You are not authorized. Run the `login` command.")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
token = token_path.read_text().strip()
|
||||
except Exception as e:
|
||||
print(f"Error reading token: {e}")
|
||||
print("You may need to run the `login` command again.")
|
||||
sys.exit(1)
|
||||
|
||||
url = "https://api.github.com/user"
|
||||
headers = {
|
||||
"Accept": "application/vnd.github+json",
|
||||
"Authorization": f"Bearer {token}",
|
||||
}
|
||||
|
||||
response = requests.get(url, headers=headers)
|
||||
user_data = parse_response(response)
|
||||
|
||||
print(f"You are authenticated as: {user_data['login']}")
|
||||
print(f"Name: {user_data.get('name', 'Not set')}")
|
||||
print(f"Email: {user_data.get('email', 'Not public')}")
|
||||
|
||||
return user_data
|
||||
|
||||
|
||||
def get_token():
|
||||
"""Get the current access token if available."""
|
||||
token_path = Path(TOKEN_FILE)
|
||||
|
||||
if not token_path.exists():
|
||||
return None
|
||||
|
||||
try:
|
||||
return token_path.read_text().strip()
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def validate_token():
|
||||
"""Validate that the current token is still valid."""
|
||||
token = get_token()
|
||||
if not token:
|
||||
return False
|
||||
|
||||
url = "https://api.github.com/user"
|
||||
headers = {
|
||||
"Accept": "application/vnd.github+json",
|
||||
"Authorization": f"Bearer {token}",
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.get(url, headers=headers)
|
||||
return response.status_code == 200
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def ensure_authenticated():
|
||||
"""Ensure user is authenticated, prompting login if necessary."""
|
||||
if validate_token():
|
||||
return get_token()
|
||||
|
||||
print("GitHub authentication required.")
|
||||
login()
|
||||
return get_token()
|
||||
|
||||
|
||||
def logout():
|
||||
"""Remove the stored access token."""
|
||||
token_path = Path(TOKEN_FILE)
|
||||
|
||||
if token_path.exists():
|
||||
token_path.unlink()
|
||||
print("Successfully logged out.")
|
||||
else:
|
||||
print("You are not currently logged in.")
|
||||
|
||||
|
||||
def main():
|
||||
"""Main CLI interface."""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="GitHub OAuth authentication for ThrillWiki CI/CD"
|
||||
)
|
||||
parser.add_argument(
|
||||
"command",
|
||||
choices=["login", "logout", "whoami", "token", "validate"],
|
||||
help="Command to execute",
|
||||
)
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == "login":
|
||||
login()
|
||||
elif args.command == "logout":
|
||||
logout()
|
||||
elif args.command == "whoami":
|
||||
whoami()
|
||||
elif args.command == "token":
|
||||
token = get_token()
|
||||
if token:
|
||||
print(token)
|
||||
else:
|
||||
print("No token available. Run `login` first.")
|
||||
sys.exit(1)
|
||||
elif args.command == "validate":
|
||||
if validate_token():
|
||||
print("Token is valid.")
|
||||
else:
|
||||
print("Token is invalid or missing.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,268 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ThrillWiki VM CI Setup Script
|
||||
# This script helps set up the VM deployment system
|
||||
|
||||
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}[SETUP]${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 prompts
|
||||
prompt_config() {
|
||||
log "Setting up ThrillWiki VM CI/CD system..."
|
||||
echo
|
||||
|
||||
read -p "Enter your VM IP address: " VM_IP
|
||||
read -p "Enter your VM username (default: ubuntu): " VM_USER
|
||||
VM_USER=${VM_USER:-ubuntu}
|
||||
|
||||
read -p "Enter your GitHub repository URL: " REPO_URL
|
||||
read -p "Enter your GitHub webhook secret: " WEBHOOK_SECRET
|
||||
|
||||
read -p "Enter local webhook port (default: 9000): " WEBHOOK_PORT
|
||||
WEBHOOK_PORT=${WEBHOOK_PORT:-9000}
|
||||
|
||||
read -p "Enter VM project path (default: /home/$VM_USER/thrillwiki): " VM_PROJECT_PATH
|
||||
VM_PROJECT_PATH=${VM_PROJECT_PATH:-/home/$VM_USER/thrillwiki}
|
||||
}
|
||||
|
||||
# Create SSH key
|
||||
setup_ssh() {
|
||||
log "Setting up SSH keys..."
|
||||
|
||||
local ssh_key_path="$HOME/.ssh/thrillwiki_vm"
|
||||
|
||||
if [ ! -f "$ssh_key_path" ]; then
|
||||
ssh-keygen -t rsa -b 4096 -f "$ssh_key_path" -N ""
|
||||
log_success "SSH key generated: $ssh_key_path"
|
||||
|
||||
log "Please copy the following public key to your VM:"
|
||||
echo "---"
|
||||
cat "$ssh_key_path.pub"
|
||||
echo "---"
|
||||
echo
|
||||
log "Run this on your VM:"
|
||||
echo "mkdir -p ~/.ssh && echo '$(cat "$ssh_key_path.pub")' >> ~/.ssh/***REMOVED*** && chmod 600 ~/.ssh/***REMOVED***"
|
||||
echo
|
||||
read -p "Press Enter when you've added the key to your VM..."
|
||||
else
|
||||
log "SSH key already exists: $ssh_key_path"
|
||||
fi
|
||||
|
||||
# Test SSH connection
|
||||
log "Testing SSH connection..."
|
||||
if ssh -i "$ssh_key_path" -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$VM_USER@$VM_IP" "echo 'SSH connection successful'"; then
|
||||
log_success "SSH connection test passed"
|
||||
else
|
||||
log_error "SSH connection test failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Create environment file
|
||||
create_env_file() {
|
||||
log "Creating webhook environment file..."
|
||||
|
||||
cat > ***REMOVED***.webhook << EOF
|
||||
# ThrillWiki Webhook Configuration
|
||||
WEBHOOK_PORT=$WEBHOOK_PORT
|
||||
WEBHOOK_SECRET=$WEBHOOK_SECRET
|
||||
VM_HOST=$VM_IP
|
||||
VM_PORT=22
|
||||
VM_USER=$VM_USER
|
||||
VM_KEY_PATH=$HOME/.ssh/thrillwiki_vm
|
||||
VM_PROJECT_PATH=$VM_PROJECT_PATH
|
||||
REPO_URL=$REPO_URL
|
||||
DEPLOY_BRANCH=main
|
||||
EOF
|
||||
|
||||
log_success "Environment file created: ***REMOVED***.webhook"
|
||||
}
|
||||
|
||||
# Setup VM
|
||||
setup_vm() {
|
||||
log "Setting up VM environment..."
|
||||
|
||||
local ssh_key_path="$HOME/.ssh/thrillwiki_vm"
|
||||
|
||||
# Create setup script for VM
|
||||
cat > /tmp/vm_setup.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "Setting up VM for ThrillWiki deployment..."
|
||||
|
||||
# Update system
|
||||
sudo apt update
|
||||
|
||||
# Install required packages
|
||||
sudo apt install -y git curl build-essential python3-pip lsof
|
||||
|
||||
# Install UV if not present
|
||||
if ! command -v uv &> /dev/null; then
|
||||
echo "Installing UV..."
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
source ~/.cargo/env
|
||||
fi
|
||||
|
||||
# Clone repository if not present
|
||||
if [ ! -d "thrillwiki" ]; then
|
||||
echo "Cloning repository..."
|
||||
git clone REPO_URL_PLACEHOLDER thrillwiki
|
||||
fi
|
||||
|
||||
cd thrillwiki
|
||||
|
||||
# Install dependencies
|
||||
uv sync
|
||||
|
||||
# Create directories
|
||||
mkdir -p logs backups
|
||||
|
||||
# Make scripts executable
|
||||
chmod +x scripts/*.sh
|
||||
|
||||
echo "VM setup completed successfully!"
|
||||
EOF
|
||||
|
||||
# Replace placeholder with actual repo URL
|
||||
sed -i.bak "s|REPO_URL_PLACEHOLDER|$REPO_URL|g" /tmp/vm_setup.sh
|
||||
|
||||
# Copy and execute setup script on VM
|
||||
scp -i "$ssh_key_path" /tmp/vm_setup.sh "$VM_USER@$VM_IP:/tmp/"
|
||||
ssh -i "$ssh_key_path" "$VM_USER@$VM_IP" "bash /tmp/vm_setup.sh"
|
||||
|
||||
log_success "VM setup completed"
|
||||
|
||||
# Cleanup
|
||||
rm /tmp/vm_setup.sh /tmp/vm_setup.sh.bak
|
||||
}
|
||||
|
||||
# Install systemd services
|
||||
setup_services() {
|
||||
log "Setting up systemd services on VM..."
|
||||
|
||||
local ssh_key_path="$HOME/.ssh/thrillwiki_vm"
|
||||
|
||||
# Copy service files and install them
|
||||
ssh -i "$ssh_key_path" "$VM_USER@$VM_IP" << EOF
|
||||
cd thrillwiki
|
||||
|
||||
# Update service files with correct paths
|
||||
sed -i 's|/home/ubuntu|/home/$VM_USER|g' scripts/systemd/*.service
|
||||
sed -i 's|ubuntu|$VM_USER|g' scripts/systemd/*.service
|
||||
|
||||
# Install services
|
||||
sudo cp scripts/systemd/thrillwiki.service /etc/systemd/system/
|
||||
sudo cp scripts/systemd/thrillwiki-webhook.service /etc/systemd/system/
|
||||
|
||||
# Reload and enable services
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable thrillwiki.service
|
||||
|
||||
echo "Services installed successfully!"
|
||||
EOF
|
||||
|
||||
log_success "Systemd services installed"
|
||||
}
|
||||
|
||||
# Test deployment
|
||||
test_deployment() {
|
||||
log "Testing VM deployment..."
|
||||
|
||||
local ssh_key_path="$HOME/.ssh/thrillwiki_vm"
|
||||
|
||||
ssh -i "$ssh_key_path" "$VM_USER@$VM_IP" << EOF
|
||||
cd thrillwiki
|
||||
./scripts/vm-deploy.sh
|
||||
EOF
|
||||
|
||||
log_success "Deployment test completed"
|
||||
}
|
||||
|
||||
# Start webhook listener
|
||||
start_webhook() {
|
||||
log "Starting webhook listener..."
|
||||
|
||||
if [ -f "***REMOVED***.webhook" ]; then
|
||||
log "Webhook configuration found. You can start the webhook listener with:"
|
||||
echo " source ***REMOVED***.webhook && python3 scripts/webhook-listener.py"
|
||||
echo
|
||||
log "Or run it in the background:"
|
||||
echo " nohup python3 scripts/webhook-listener.py > logs/webhook.log 2>&1 &"
|
||||
else
|
||||
log_error "Webhook configuration not found!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# GitHub webhook instructions
|
||||
github_instructions() {
|
||||
log "GitHub Webhook Setup Instructions:"
|
||||
echo
|
||||
echo "1. Go to your GitHub repository: $REPO_URL"
|
||||
echo "2. Navigate to Settings → Webhooks"
|
||||
echo "3. Click 'Add webhook'"
|
||||
echo "4. Configure:"
|
||||
echo " - Payload URL: http://YOUR_PUBLIC_IP:$WEBHOOK_PORT/webhook"
|
||||
echo " - Content type: application/json"
|
||||
echo " - Secret: $WEBHOOK_SECRET"
|
||||
echo " - Events: Just the push event"
|
||||
echo "5. Click 'Add webhook'"
|
||||
echo
|
||||
log_warning "Make sure port $WEBHOOK_PORT is open on your firewall!"
|
||||
}
|
||||
|
||||
# Main setup flow
|
||||
main() {
|
||||
log "ThrillWiki VM CI/CD Setup"
|
||||
echo "=========================="
|
||||
echo
|
||||
|
||||
# Create logs directory
|
||||
mkdir -p logs
|
||||
|
||||
# Get configuration
|
||||
prompt_config
|
||||
|
||||
# Setup steps
|
||||
setup_ssh
|
||||
create_env_file
|
||||
setup_vm
|
||||
setup_services
|
||||
test_deployment
|
||||
|
||||
# Final instructions
|
||||
echo
|
||||
log_success "Setup completed successfully!"
|
||||
echo
|
||||
start_webhook
|
||||
echo
|
||||
github_instructions
|
||||
|
||||
log "Setup log saved to: logs/setup.log"
|
||||
}
|
||||
|
||||
# Run main function and log output
|
||||
main "$@" 2>&1 | tee logs/setup.log
|
||||
@@ -1,575 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ThrillWiki Server Start Script
|
||||
# Stops any running servers, clears caches, runs migrations, and starts both servers
|
||||
# Works whether servers are currently running or not
|
||||
# Usage: ./start-servers.sh
|
||||
|
||||
set -e # Exit on any error
|
||||
|
||||
# Global variables for process management
|
||||
BACKEND_PID=""
|
||||
FRONTEND_PID=""
|
||||
CLEANUP_PERFORMED=false
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Script directory and project root
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
BACKEND_DIR="$PROJECT_ROOT/backend"
|
||||
FRONTEND_DIR="$PROJECT_ROOT/frontend"
|
||||
|
||||
# Function to print colored output
|
||||
print_status() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Function for graceful shutdown
|
||||
graceful_shutdown() {
|
||||
if [ "$CLEANUP_PERFORMED" = true ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
CLEANUP_PERFORMED=true
|
||||
|
||||
print_warning "Received shutdown signal - performing graceful shutdown..."
|
||||
|
||||
# Disable further signal handling to prevent recursive calls
|
||||
trap - INT TERM
|
||||
|
||||
# Kill backend server if running
|
||||
if [ -n "$BACKEND_PID" ] && kill -0 "$BACKEND_PID" 2>/dev/null; then
|
||||
print_status "Stopping backend server (PID: $BACKEND_PID)..."
|
||||
kill -TERM "$BACKEND_PID" 2>/dev/null || true
|
||||
|
||||
# Wait up to 10 seconds for graceful shutdown
|
||||
local count=0
|
||||
while [ $count -lt 10 ] && kill -0 "$BACKEND_PID" 2>/dev/null; do
|
||||
sleep 1
|
||||
count=$((count + 1))
|
||||
done
|
||||
|
||||
# Force kill if still running
|
||||
if kill -0 "$BACKEND_PID" 2>/dev/null; then
|
||||
print_warning "Force killing backend server..."
|
||||
kill -KILL "$BACKEND_PID" 2>/dev/null || true
|
||||
fi
|
||||
print_success "Backend server stopped"
|
||||
else
|
||||
print_status "Backend server not running or already stopped"
|
||||
fi
|
||||
|
||||
# Kill frontend server if running
|
||||
if [ -n "$FRONTEND_PID" ] && kill -0 "$FRONTEND_PID" 2>/dev/null; then
|
||||
print_status "Stopping frontend server (PID: $FRONTEND_PID)..."
|
||||
kill -TERM "$FRONTEND_PID" 2>/dev/null || true
|
||||
|
||||
# Wait up to 10 seconds for graceful shutdown
|
||||
local count=0
|
||||
while [ $count -lt 10 ] && kill -0 "$FRONTEND_PID" 2>/dev/null; do
|
||||
sleep 1
|
||||
count=$((count + 1))
|
||||
done
|
||||
|
||||
# Force kill if still running
|
||||
if kill -0 "$FRONTEND_PID" 2>/dev/null; then
|
||||
print_warning "Force killing frontend server..."
|
||||
kill -KILL "$FRONTEND_PID" 2>/dev/null || true
|
||||
fi
|
||||
print_success "Frontend server stopped"
|
||||
else
|
||||
print_status "Frontend server not running or already stopped"
|
||||
fi
|
||||
|
||||
# Clear PID files if they exist
|
||||
if [ -f "$PROJECT_ROOT/shared/logs/backend.pid" ]; then
|
||||
rm -f "$PROJECT_ROOT/shared/logs/backend.pid"
|
||||
fi
|
||||
if [ -f "$PROJECT_ROOT/shared/logs/frontend.pid" ]; then
|
||||
rm -f "$PROJECT_ROOT/shared/logs/frontend.pid"
|
||||
fi
|
||||
|
||||
print_success "Graceful shutdown completed"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Function to kill processes by pattern
|
||||
kill_processes() {
|
||||
local pattern="$1"
|
||||
local description="$2"
|
||||
|
||||
print_status "Checking for $description processes..."
|
||||
|
||||
# Find and kill processes
|
||||
local pids=$(pgrep -f "$pattern" 2>/dev/null || true)
|
||||
|
||||
if [ -n "$pids" ]; then
|
||||
print_status "Found $description processes, stopping them..."
|
||||
echo "$pids" | xargs kill -TERM 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
# Force kill if still running
|
||||
local remaining_pids=$(pgrep -f "$pattern" 2>/dev/null || true)
|
||||
if [ -n "$remaining_pids" ]; then
|
||||
print_warning "Force killing remaining $description processes..."
|
||||
echo "$remaining_pids" | xargs kill -KILL 2>/dev/null || true
|
||||
fi
|
||||
|
||||
print_success "$description processes stopped"
|
||||
else
|
||||
print_status "No $description processes found (this is fine)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to clear Django cache
|
||||
clear_django_cache() {
|
||||
print_status "Clearing Django cache..."
|
||||
|
||||
cd "$BACKEND_DIR"
|
||||
|
||||
# Clear Django cache
|
||||
if command -v uv >/dev/null 2>&1; then
|
||||
if ! uv run manage.py clear_cache 2>clear_cache_error.log; then
|
||||
print_error "Django clear_cache command failed:"
|
||||
cat clear_cache_error.log
|
||||
rm -f clear_cache_error.log
|
||||
exit 1
|
||||
else
|
||||
rm -f clear_cache_error.log
|
||||
fi
|
||||
else
|
||||
print_error "uv not found! Please install uv first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Remove Python cache files
|
||||
find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
||||
find . -name "*.pyc" -delete 2>/dev/null || true
|
||||
find . -name "*.pyo" -delete 2>/dev/null || true
|
||||
|
||||
print_success "Django cache cleared"
|
||||
}
|
||||
|
||||
# Function to clear frontend cache
|
||||
clear_frontend_cache() {
|
||||
print_status "Clearing frontend cache..."
|
||||
|
||||
cd "$FRONTEND_DIR"
|
||||
|
||||
# Remove node_modules/.cache if it exists
|
||||
if [ -d "node_modules/.cache" ]; then
|
||||
rm -rf node_modules/.cache
|
||||
print_status "Removed node_modules/.cache"
|
||||
fi
|
||||
|
||||
# Remove .nuxt cache if it exists (for Nuxt projects)
|
||||
if [ -d ".nuxt" ]; then
|
||||
rm -rf .nuxt
|
||||
print_status "Removed .nuxt cache"
|
||||
fi
|
||||
|
||||
# Remove dist/build directories
|
||||
if [ -d "dist" ]; then
|
||||
rm -rf dist
|
||||
print_status "Removed dist directory"
|
||||
fi
|
||||
|
||||
if [ -d "build" ]; then
|
||||
rm -rf build
|
||||
print_status "Removed build directory"
|
||||
fi
|
||||
|
||||
# Clear pnpm cache
|
||||
if command -v pnpm >/dev/null 2>&1; then
|
||||
pnpm store prune 2>/dev/null || print_warning "Could not prune pnpm store"
|
||||
else
|
||||
print_error "pnpm not found! Please install pnpm first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "Frontend cache cleared"
|
||||
}
|
||||
|
||||
# Function to run Django migrations
|
||||
run_migrations() {
|
||||
print_status "Running Django migrations..."
|
||||
|
||||
cd "$BACKEND_DIR"
|
||||
|
||||
# Check for pending migrations
|
||||
if uv run python manage.py showmigrations --plan | grep -q "\[ \]"; then
|
||||
print_status "Pending migrations found, applying..."
|
||||
uv run python manage.py migrate
|
||||
print_success "Migrations applied successfully"
|
||||
else
|
||||
print_status "No pending migrations found"
|
||||
fi
|
||||
|
||||
# Run any custom management commands if needed
|
||||
# uv run python manage.py collectstatic --noinput --clear 2>/dev/null || print_warning "collectstatic failed or not needed"
|
||||
}
|
||||
|
||||
# Function to start backend server
|
||||
start_backend() {
|
||||
print_status "Starting Django backend server with runserver_plus (verbose output)..."
|
||||
|
||||
cd "$BACKEND_DIR"
|
||||
|
||||
# Start Django development server with runserver_plus for enhanced features and verbose output
|
||||
print_status "Running: uv run python manage.py runserver_plus 8000 --verbosity=2"
|
||||
uv run python manage.py runserver_plus 8000 --verbosity=2 &
|
||||
BACKEND_PID=$!
|
||||
|
||||
# Make sure the background process can receive signals
|
||||
disown -h "$BACKEND_PID" 2>/dev/null || true
|
||||
|
||||
# Wait a moment and check if it started successfully
|
||||
sleep 3
|
||||
if kill -0 $BACKEND_PID 2>/dev/null; then
|
||||
print_success "Backend server started (PID: $BACKEND_PID)"
|
||||
echo $BACKEND_PID > ../shared/logs/backend.pid
|
||||
else
|
||||
print_error "Failed to start backend server"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to start frontend server
|
||||
start_frontend() {
|
||||
print_status "Starting frontend server with verbose output..."
|
||||
|
||||
cd "$FRONTEND_DIR"
|
||||
|
||||
# Install dependencies if node_modules doesn't exist or package.json is newer
|
||||
if [ ! -d "node_modules" ] || [ "package.json" -nt "node_modules" ]; then
|
||||
print_status "Installing/updating frontend dependencies..."
|
||||
pnpm install
|
||||
fi
|
||||
|
||||
# Start frontend development server using Vite with explicit port, auto-open, and verbose output
|
||||
# --port 5173: Use standard Vite port
|
||||
# --open: Automatically open browser when ready
|
||||
# --host localhost: Ensure it binds to localhost
|
||||
# --debug: Enable debug logging
|
||||
print_status "Starting Vite development server with verbose output and auto-browser opening..."
|
||||
print_status "Running: pnpm vite --port 5173 --open --host localhost --debug"
|
||||
pnpm vite --port 5173 --open --host localhost --debug &
|
||||
FRONTEND_PID=$!
|
||||
|
||||
# Make sure the background process can receive signals
|
||||
disown -h "$FRONTEND_PID" 2>/dev/null || true
|
||||
|
||||
# Wait a moment and check if it started successfully
|
||||
sleep 3
|
||||
if kill -0 $FRONTEND_PID 2>/dev/null; then
|
||||
print_success "Frontend server started (PID: $FRONTEND_PID) - browser should open automatically"
|
||||
echo $FRONTEND_PID > ../shared/logs/frontend.pid
|
||||
else
|
||||
print_error "Failed to start frontend server"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to detect operating system
|
||||
detect_os() {
|
||||
case "$(uname -s)" in
|
||||
Darwin*) echo "macos";;
|
||||
Linux*) echo "linux";;
|
||||
*) echo "unknown";;
|
||||
esac
|
||||
}
|
||||
|
||||
# Function to open browser on the appropriate OS
|
||||
open_browser() {
|
||||
local url="$1"
|
||||
local os=$(detect_os)
|
||||
|
||||
print_status "Opening browser to $url..."
|
||||
|
||||
case "$os" in
|
||||
"macos")
|
||||
if command -v open >/dev/null 2>&1; then
|
||||
open "$url" 2>/dev/null || print_warning "Failed to open browser automatically"
|
||||
else
|
||||
print_warning "Cannot open browser: 'open' command not available"
|
||||
fi
|
||||
;;
|
||||
"linux")
|
||||
if command -v xdg-open >/dev/null 2>&1; then
|
||||
xdg-open "$url" 2>/dev/null || print_warning "Failed to open browser automatically"
|
||||
else
|
||||
print_warning "Cannot open browser: 'xdg-open' command not available"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
print_warning "Cannot open browser automatically: Unsupported operating system"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Function to verify frontend is responding (simplified since port is known)
|
||||
verify_frontend_ready() {
|
||||
local frontend_url="http://localhost:5173"
|
||||
local max_checks=15
|
||||
local check=0
|
||||
|
||||
print_status "Verifying frontend server is responding at $frontend_url..."
|
||||
|
||||
while [ $check -lt $max_checks ]; do
|
||||
local response_code=$(curl -s -o /dev/null -w "%{http_code}" "$frontend_url" 2>/dev/null)
|
||||
if [ "$response_code" = "200" ] || [ "$response_code" = "301" ] || [ "$response_code" = "302" ] || [ "$response_code" = "404" ]; then
|
||||
print_success "Frontend server is responding (HTTP $response_code)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ $((check % 3)) -eq 0 ]; then
|
||||
print_status "Waiting for frontend to respond... (attempt $((check + 1))/$max_checks)"
|
||||
fi
|
||||
sleep 2
|
||||
check=$((check + 1))
|
||||
done
|
||||
|
||||
print_warning "Frontend may still be starting up"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Function to verify servers are responding
|
||||
verify_servers_ready() {
|
||||
print_status "Verifying both servers are responding..."
|
||||
|
||||
# Check backend
|
||||
local backend_ready=false
|
||||
local frontend_ready=false
|
||||
local max_checks=10
|
||||
local check=0
|
||||
|
||||
while [ $check -lt $max_checks ]; do
|
||||
# Check backend
|
||||
if [ "$backend_ready" = false ]; then
|
||||
local backend_response=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:8000" 2>/dev/null)
|
||||
if [ "$backend_response" = "200" ] || [ "$backend_response" = "301" ] || [ "$backend_response" = "302" ] || [ "$backend_response" = "404" ]; then
|
||||
print_success "Backend server is responding (HTTP $backend_response)"
|
||||
backend_ready=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check frontend
|
||||
if [ "$frontend_ready" = false ]; then
|
||||
local frontend_response=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:5173" 2>/dev/null)
|
||||
if [ "$frontend_response" = "200" ] || [ "$frontend_response" = "301" ] || [ "$frontend_response" = "302" ] || [ "$frontend_response" = "404" ]; then
|
||||
print_success "Frontend server is responding (HTTP $frontend_response)"
|
||||
frontend_ready=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Both ready?
|
||||
if [ "$backend_ready" = true ] && [ "$frontend_ready" = true ]; then
|
||||
print_success "Both servers are responding!"
|
||||
return 0
|
||||
fi
|
||||
|
||||
sleep 2
|
||||
check=$((check + 1))
|
||||
done
|
||||
|
||||
# Show status of what's working
|
||||
if [ "$backend_ready" = true ]; then
|
||||
print_success "Backend is ready at http://localhost:8000"
|
||||
else
|
||||
print_warning "Backend may still be starting up"
|
||||
fi
|
||||
|
||||
if [ "$frontend_ready" = true ]; then
|
||||
print_success "Frontend is ready at http://localhost:5173"
|
||||
else
|
||||
print_warning "Frontend may still be starting up"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to create logs directory if it doesn't exist
|
||||
ensure_logs_dir() {
|
||||
local logs_dir="$PROJECT_ROOT/shared/logs"
|
||||
if [ ! -d "$logs_dir" ]; then
|
||||
mkdir -p "$logs_dir"
|
||||
print_status "Created logs directory: $logs_dir"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to validate project structure
|
||||
validate_project() {
|
||||
if [ ! -d "$BACKEND_DIR" ]; then
|
||||
print_error "Backend directory not found: $BACKEND_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$FRONTEND_DIR" ]; then
|
||||
print_error "Frontend directory not found: $FRONTEND_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$BACKEND_DIR/manage.py" ]; then
|
||||
print_error "Django manage.py not found in: $BACKEND_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$FRONTEND_DIR/package.json" ]; then
|
||||
print_error "Frontend package.json not found in: $FRONTEND_DIR"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to kill processes using specific ports
|
||||
kill_port_processes() {
|
||||
local port="$1"
|
||||
local description="$2"
|
||||
|
||||
print_status "Checking for processes using port $port ($description)..."
|
||||
|
||||
# Find processes using the specific port
|
||||
local pids=$(lsof -ti :$port 2>/dev/null || true)
|
||||
|
||||
if [ -n "$pids" ]; then
|
||||
print_warning "Found processes using port $port, killing them..."
|
||||
echo "$pids" | xargs kill -TERM 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
# Force kill if still running
|
||||
local remaining_pids=$(lsof -ti :$port 2>/dev/null || true)
|
||||
if [ -n "$remaining_pids" ]; then
|
||||
print_warning "Force killing remaining processes on port $port..."
|
||||
echo "$remaining_pids" | xargs kill -KILL 2>/dev/null || true
|
||||
fi
|
||||
|
||||
print_success "Port $port cleared"
|
||||
else
|
||||
print_status "Port $port is available"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check and clear required ports
|
||||
check_and_clear_ports() {
|
||||
print_status "Checking and clearing required ports..."
|
||||
|
||||
# Kill processes using our specific ports
|
||||
kill_port_processes 8000 "Django backend"
|
||||
kill_port_processes 5173 "Frontend Vite"
|
||||
}
|
||||
|
||||
# Main execution function
|
||||
main() {
|
||||
print_status "ThrillWiki Server Start Script Starting..."
|
||||
print_status "This script works whether servers are currently running or not."
|
||||
print_status "Project root: $PROJECT_ROOT"
|
||||
|
||||
# Set up signal traps EARLY - before any long-running operations
|
||||
print_status "Setting up signal handlers for graceful shutdown..."
|
||||
trap 'graceful_shutdown' INT TERM
|
||||
|
||||
# Validate project structure
|
||||
validate_project
|
||||
|
||||
# Ensure logs directory exists
|
||||
ensure_logs_dir
|
||||
|
||||
# Check and clear ports
|
||||
check_and_clear_ports
|
||||
|
||||
# Kill existing server processes (if any)
|
||||
print_status "=== Stopping Any Running Servers ==="
|
||||
print_status "Note: It's perfectly fine if no servers are currently running"
|
||||
kill_processes "manage.py runserver" "Django backend"
|
||||
kill_processes "pnpm.*dev\|npm.*dev\|yarn.*dev\|node.*dev" "Frontend development"
|
||||
kill_processes "uvicorn\|gunicorn" "Python web servers"
|
||||
|
||||
# Clear caches
|
||||
print_status "=== Clearing Caches ==="
|
||||
clear_django_cache
|
||||
clear_frontend_cache
|
||||
|
||||
# Run migrations
|
||||
print_status "=== Running Migrations ==="
|
||||
run_migrations
|
||||
|
||||
# Start servers
|
||||
print_status "=== Starting Servers ==="
|
||||
|
||||
# Start backend first
|
||||
if start_backend; then
|
||||
print_success "Backend server is running"
|
||||
else
|
||||
print_error "Failed to start backend server"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start frontend
|
||||
if start_frontend; then
|
||||
print_success "Frontend server is running"
|
||||
else
|
||||
print_error "Failed to start frontend server"
|
||||
print_status "Backend server is still running"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify servers are responding
|
||||
print_status "=== Verifying Servers ==="
|
||||
verify_servers_ready
|
||||
|
||||
# Final status
|
||||
print_status "=== Server Status ==="
|
||||
print_success "✅ Backend server: http://localhost:8000 (Django with runserver_plus)"
|
||||
print_success "✅ Frontend server: http://localhost:5173 (Vite with verbose output)"
|
||||
print_status "🌐 Browser should have opened automatically via Vite --open"
|
||||
print_status "🔧 To stop servers, use: kill \$(cat $PROJECT_ROOT/shared/logs/backend.pid) \$(cat $PROJECT_ROOT/shared/logs/frontend.pid)"
|
||||
print_status "📋 Both servers are running with verbose output directly in your terminal"
|
||||
|
||||
print_success "🚀 All servers started successfully with full verbose output!"
|
||||
|
||||
# Keep the script running and wait for signals
|
||||
wait_for_servers
|
||||
}
|
||||
|
||||
# Wait for servers function to keep script running and handle signals
|
||||
wait_for_servers() {
|
||||
print_status "🚀 Servers are running! Press Ctrl+C for graceful shutdown."
|
||||
print_status "📋 Backend: http://localhost:8000 | Frontend: http://localhost:5173"
|
||||
|
||||
# Keep the script alive and wait for signals
|
||||
while [ "$CLEANUP_PERFORMED" != true ]; do
|
||||
# Check if both servers are still running
|
||||
if [ -n "$BACKEND_PID" ] && ! kill -0 "$BACKEND_PID" 2>/dev/null; then
|
||||
print_error "Backend server has stopped unexpectedly"
|
||||
graceful_shutdown
|
||||
break
|
||||
fi
|
||||
|
||||
if [ -n "$FRONTEND_PID" ] && ! kill -0 "$FRONTEND_PID" 2>/dev/null; then
|
||||
print_error "Frontend server has stopped unexpectedly"
|
||||
graceful_shutdown
|
||||
break
|
||||
fi
|
||||
|
||||
# Use shorter sleep and check for signals more frequently
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
# Run main function (no traps set up initially)
|
||||
main "$@"
|
||||
@@ -1,296 +0,0 @@
|
||||
# ThrillWiki Automation Service Environment Configuration
|
||||
# Copy this file to thrillwiki-automation***REMOVED*** and customize for your environment
|
||||
#
|
||||
# Security Note: This file should have restricted permissions (600) as it may contain
|
||||
# sensitive information like GitHub Personal Access Tokens
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# PROJECT CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Base project directory (usually auto-detected)
|
||||
# PROJECT_DIR=/home/ubuntu/thrillwiki
|
||||
|
||||
# Service name for systemd integration
|
||||
# SERVICE_NAME=thrillwiki
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# GITHUB REPOSITORY CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# GitHub repository remote name
|
||||
# GITHUB_REPO=origin
|
||||
|
||||
# Branch to pull from
|
||||
# GITHUB_BRANCH=main
|
||||
|
||||
# GitHub Personal Access Token (PAT) - Required for private repositories
|
||||
# Generate at: https://github.com/settings/tokens
|
||||
# Required permissions: repo (Full control of private repositories)
|
||||
# GITHUB_TOKEN=ghp_your_personal_access_token_here
|
||||
|
||||
# GitHub token file location (alternative to GITHUB_TOKEN)
|
||||
# GITHUB_TOKEN_FILE=/home/ubuntu/thrillwiki/.github-pat
|
||||
GITHUB_PAT_FILE=/home/ubuntu/thrillwiki/.github-pat
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# AUTOMATION TIMING CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Repository pull interval in seconds (default: 300 = 5 minutes)
|
||||
# PULL_INTERVAL=300
|
||||
|
||||
# Health check interval in seconds (default: 60 = 1 minute)
|
||||
# HEALTH_CHECK_INTERVAL=60
|
||||
|
||||
# Server startup timeout in seconds (default: 120 = 2 minutes)
|
||||
# STARTUP_TIMEOUT=120
|
||||
|
||||
# Restart delay after failure in seconds (default: 10)
|
||||
# RESTART_DELAY=10
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# LOGGING CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Log directory (default: project_dir/logs)
|
||||
# LOG_DIR=/home/ubuntu/thrillwiki/logs
|
||||
|
||||
# Log file path
|
||||
# LOG_[AWS-SECRET-REMOVED]proof-automation.log
|
||||
|
||||
# Maximum log file size in bytes (default: 10485760 = 10MB)
|
||||
# MAX_LOG_SIZE=10485760
|
||||
|
||||
# Lock file location to prevent multiple instances
|
||||
# LOCK_FILE=/tmp/thrillwiki-bulletproof.lock
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# DEVELOPMENT SERVER CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Server host address (default: 0.0.0.0 for all interfaces)
|
||||
# SERVER_HOST=0.0.0.0
|
||||
|
||||
# Server port (default: 8000)
|
||||
# SERVER_PORT=8000
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# DEPLOYMENT CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Deployment preset (dev, prod, demo, testing)
|
||||
# DEPLOYMENT_PRESET=dev
|
||||
|
||||
# Repository URL for deployment
|
||||
# GITHUB_REPO_URL=https://github.com/username/repository.git
|
||||
|
||||
# Repository branch for deployment
|
||||
# GITHUB_REPO_BRANCH=main
|
||||
|
||||
# Enable Django project setup during deployment
|
||||
# DJANGO_PROJECT_SETUP=true
|
||||
|
||||
# Skip GitHub authentication setup
|
||||
# SKIP_GITHUB_SETUP=false
|
||||
|
||||
# Skip repository configuration
|
||||
# SKIP_REPO_CONFIG=false
|
||||
|
||||
# Skip systemd service setup
|
||||
# SKIP_SERVICE_SETUP=false
|
||||
|
||||
# Force deployment even if target exists
|
||||
# FORCE_DEPLOY=false
|
||||
|
||||
# Remote deployment user
|
||||
# REMOTE_USER=ubuntu
|
||||
|
||||
# Remote deployment host
|
||||
# REMOTE_HOST=
|
||||
|
||||
# Remote deployment port
|
||||
# REMOTE_PORT=22
|
||||
|
||||
# Remote deployment path
|
||||
# REMOTE_PATH=/home/ubuntu/thrillwiki
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# DJANGO CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Django settings module
|
||||
# DJANGO_SETTINGS_MODULE=thrillwiki.settings
|
||||
|
||||
# Python path
|
||||
# PYTHONPATH=/home/ubuntu/thrillwiki
|
||||
|
||||
# UV executable path (for systems where UV is not in standard PATH)
|
||||
# UV_EXECUTABLE=/home/ubuntu/.local/bin/uv
|
||||
|
||||
# Django development server command (used by bulletproof automation)
|
||||
# DJANGO_RUNSERVER_CMD=uv run manage.py tailwind runserver
|
||||
|
||||
# Enable development server auto-cleanup (kills processes on port 8000)
|
||||
# AUTO_CLEANUP_PROCESSES=true
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# ADVANCED CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# GitHub authentication script location
|
||||
# GITHUB_AUTH_[AWS-SECRET-REMOVED]ithub-auth.py
|
||||
|
||||
# Enable verbose logging (true/false)
|
||||
# VERBOSE_LOGGING=false
|
||||
|
||||
# Enable debug mode for troubleshooting (true/false)
|
||||
# DEBUG_MODE=false
|
||||
|
||||
# Custom git remote URL (overrides GITHUB_REPO if set)
|
||||
# CUSTOM_GIT_REMOTE=https://github.com/username/repository.git
|
||||
|
||||
# Email notifications for critical failures (requires email configuration)
|
||||
# NOTIFICATION_EMAIL=admin@example.com
|
||||
|
||||
# Maximum consecutive failures before alerting (default: 5)
|
||||
# MAX_CONSECUTIVE_FAILURES=5
|
||||
|
||||
# Enable automatic dependency updates (true/false, default: true)
|
||||
# AUTO_UPDATE_DEPENDENCIES=true
|
||||
|
||||
# Enable automatic migrations on code changes (true/false, default: true)
|
||||
# AUTO_MIGRATE=true
|
||||
|
||||
# Enable automatic static file collection (true/false, default: true)
|
||||
# AUTO_COLLECTSTATIC=true
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# SECURITY CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# GitHub authentication method (token|ssh|https)
|
||||
# Default: token (uses GITHUB_TOKEN or GITHUB_TOKEN_FILE)
|
||||
# GITHUB_AUTH_METHOD=token
|
||||
|
||||
# SSH key path for git operations (when using ssh auth method)
|
||||
# SSH_KEY_PATH=/home/ubuntu/.ssh/***REMOVED***
|
||||
|
||||
# Git user configuration for commits
|
||||
# GIT_USER_NAME="ThrillWiki Automation"
|
||||
# GIT_USER_EMAIL="automation@thrillwiki.local"
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# MONITORING AND HEALTH CHECKS
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Health check URL to verify server is running
|
||||
# HEALTH_CHECK_URL=http://localhost:8000/health/
|
||||
|
||||
# Health check timeout in seconds
|
||||
# HEALTH_CHECK_TIMEOUT=30
|
||||
|
||||
# Enable system resource monitoring (true/false)
|
||||
# MONITOR_RESOURCES=true
|
||||
|
||||
# Memory usage threshold for warnings (in MB)
|
||||
# MEMORY_WARNING_THRESHOLD=1024
|
||||
|
||||
# CPU usage threshold for warnings (percentage)
|
||||
# CPU_WARNING_THRESHOLD=80
|
||||
|
||||
# Disk usage threshold for warnings (percentage)
|
||||
# DISK_WARNING_THRESHOLD=90
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# INTEGRATION SETTINGS
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Webhook integration (if using thrillwiki-webhook service)
|
||||
# WEBHOOK_INTEGRATION=true
|
||||
|
||||
# Slack webhook URL for notifications (optional)
|
||||
# SLACK_WEBHOOK_URL=https://hooks.slack.com/services/your/webhook/url
|
||||
|
||||
# Discord webhook URL for notifications (optional)
|
||||
# DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/your/webhook/url
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# ENVIRONMENT AND SYSTEM CONFIGURATION
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# System PATH additions (for UV and other tools)
|
||||
# ADDITIONAL_PATH=/home/ubuntu/.local/bin:/home/ubuntu/.cargo/bin
|
||||
|
||||
# Python environment configuration
|
||||
# PYTHON_EXECUTABLE=python3
|
||||
|
||||
# Enable verbose logging for debugging
|
||||
# VERBOSE_LOGGING=false
|
||||
|
||||
# Debug mode for development
|
||||
# DEBUG_MODE=false
|
||||
|
||||
# Service restart configuration
|
||||
# MAX_RESTART_ATTEMPTS=3
|
||||
# RESTART_COOLDOWN=300
|
||||
|
||||
# Health check configuration
|
||||
# HEALTH_CHECK_URL=http://localhost:8000/health/
|
||||
# HEALTH_CHECK_TIMEOUT=30
|
||||
|
||||
# System resource monitoring
|
||||
# MONITOR_RESOURCES=true
|
||||
# MEMORY_WARNING_THRESHOLD=1024
|
||||
# CPU_WARNING_THRESHOLD=80
|
||||
# DISK_WARNING_THRESHOLD=90
|
||||
|
||||
# Lock file configuration
|
||||
# LOCK_FILE=/tmp/thrillwiki-bulletproof.lock
|
||||
|
||||
# GitHub authentication method (token|ssh|https)
|
||||
# GITHUB_AUTH_METHOD=token
|
||||
|
||||
# SSH key path for git operations (when using ssh auth method)
|
||||
# SSH_KEY_PATH=/home/ubuntu/.ssh/***REMOVED***
|
||||
|
||||
# Git user configuration for commits
|
||||
# GIT_USER_NAME="ThrillWiki Automation"
|
||||
# GIT_USER_EMAIL="automation@thrillwiki.local"
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# USAGE EXAMPLES
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# Example 1: Basic setup with GitHub PAT
|
||||
# GITHUB_TOKEN=ghp_your_token_here
|
||||
# PULL_INTERVAL=300
|
||||
# AUTO_MIGRATE=true
|
||||
|
||||
# Example 2: Enhanced monitoring setup
|
||||
# HEALTH_CHECK_INTERVAL=30
|
||||
# MONITOR_RESOURCES=true
|
||||
# NOTIFICATION_EMAIL=admin@thrillwiki.com
|
||||
# SLACK_WEBHOOK_URL=https://hooks.slack.com/services/your/webhook
|
||||
|
||||
# Example 3: Development environment with frequent pulls
|
||||
# PULL_INTERVAL=60
|
||||
# DEBUG_MODE=true
|
||||
# VERBOSE_LOGGING=true
|
||||
# AUTO_UPDATE_DEPENDENCIES=true
|
||||
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
# INSTALLATION NOTES
|
||||
# [AWS-SECRET-REMOVED]====================================
|
||||
|
||||
# 1. Copy this file: cp thrillwiki-automation***REMOVED***.example thrillwiki-automation***REMOVED***
|
||||
# 2. Set secure permissions: chmod 600 thrillwiki-automation***REMOVED***
|
||||
# 3. Customize the settings above for your environment
|
||||
# 4. Enable the service: sudo systemctl enable thrillwiki-automation
|
||||
# 5. Start the service: sudo systemctl start thrillwiki-automation
|
||||
# 6. Check status: sudo systemctl status thrillwiki-automation
|
||||
# 7. View logs: sudo journalctl -u thrillwiki-automation -f
|
||||
|
||||
# For security, ensure only the ubuntu user can read this file:
|
||||
# sudo chown ubuntu:ubuntu thrillwiki-automation***REMOVED***
|
||||
# sudo chmod 600 thrillwiki-automation***REMOVED***
|
||||
@@ -1,106 +0,0 @@
|
||||
[Unit]
|
||||
Description=ThrillWiki Bulletproof Development Automation
|
||||
Documentation=man:thrillwiki-automation(8)
|
||||
After=network.target
|
||||
Wants=network.target
|
||||
Before=thrillwiki.service
|
||||
PartOf=thrillwiki.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=ubuntu
|
||||
Group=ubuntu
|
||||
[AWS-SECRET-REMOVED]
|
||||
[AWS-SECRET-REMOVED]s/vm/bulletproof-automation.sh
|
||||
ExecStop=/bin/kill -TERM $MAINPID
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
KillMode=mixed
|
||||
KillSignal=SIGTERM
|
||||
TimeoutStopSec=60
|
||||
TimeoutStartSec=120
|
||||
StartLimitIntervalSec=300
|
||||
StartLimitBurst=3
|
||||
|
||||
# Environment variables - Load from file for security
|
||||
EnvironmentFile=-[AWS-SECRET-REMOVED]thrillwiki-automation***REMOVED***
|
||||
Environment=PROJECT_DIR=/home/ubuntu/thrillwiki
|
||||
Environment=SERVICE_NAME=thrillwiki-automation
|
||||
Environment=GITHUB_REPO=origin
|
||||
Environment=GITHUB_BRANCH=main
|
||||
Environment=PULL_INTERVAL=300
|
||||
Environment=HEALTH_CHECK_INTERVAL=60
|
||||
Environment=STARTUP_TIMEOUT=120
|
||||
Environment=RESTART_DELAY=10
|
||||
Environment=LOG_DIR=/home/ubuntu/thrillwiki/logs
|
||||
Environment=MAX_LOG_SIZE=10485760
|
||||
Environment=SERVER_HOST=0.0.0.0
|
||||
Environment=SERVER_PORT=8000
|
||||
Environment=PATH=/home/ubuntu/.local/bin:/home/ubuntu/.cargo/bin:/usr/local/bin:/usr/bin:/bin
|
||||
[AWS-SECRET-REMOVED]llwiki
|
||||
|
||||
# Security settings - Enhanced hardening for automation script
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectControlGroups=true
|
||||
RestrictSUIDSGID=true
|
||||
RestrictRealtime=true
|
||||
RestrictNamespaces=true
|
||||
LockPersonality=true
|
||||
MemoryDenyWriteExecute=false
|
||||
RemoveIPC=true
|
||||
|
||||
# File system permissions - Allow access to necessary directories
|
||||
ReadWritePaths=/home/ubuntu/thrillwiki
|
||||
[AWS-SECRET-REMOVED]ogs
|
||||
[AWS-SECRET-REMOVED]edia
|
||||
[AWS-SECRET-REMOVED]taticfiles
|
||||
[AWS-SECRET-REMOVED]ploads
|
||||
ReadWritePaths=/home/ubuntu/.cache
|
||||
ReadWritePaths=/tmp
|
||||
ReadOnlyPaths=/home/ubuntu/.github-pat
|
||||
ReadOnlyPaths=/home/ubuntu/.ssh
|
||||
ReadOnlyPaths=/home/ubuntu/.local
|
||||
|
||||
# Resource limits - Appropriate for automation script
|
||||
LimitNOFILE=65536
|
||||
LimitNPROC=1024
|
||||
MemoryMax=512M
|
||||
CPUQuota=50%
|
||||
TasksMax=256
|
||||
|
||||
# Timeouts
|
||||
WatchdogSec=300
|
||||
|
||||
# Logging configuration
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=thrillwiki-automation
|
||||
SyslogFacility=daemon
|
||||
SyslogLevel=info
|
||||
SyslogLevelPrefix=true
|
||||
|
||||
# Enhanced logging for debugging
|
||||
# Ensure logs are captured and rotated properly
|
||||
LogsDirectory=thrillwiki-automation
|
||||
LogsDirectoryMode=0755
|
||||
StateDirectory=thrillwiki-automation
|
||||
StateDirectoryMode=0755
|
||||
RuntimeDirectory=thrillwiki-automation
|
||||
RuntimeDirectoryMode=0755
|
||||
|
||||
# Capabilities - Minimal required capabilities
|
||||
CapabilityBoundingSet=
|
||||
AmbientCapabilities=
|
||||
PrivateDevices=true
|
||||
ProtectClock=true
|
||||
ProtectHostname=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Also=thrillwiki.service
|
||||
@@ -1,103 +0,0 @@
|
||||
[Unit]
|
||||
Description=ThrillWiki Complete Deployment Automation Service
|
||||
Documentation=man:thrillwiki-deployment(8)
|
||||
After=network.target network-online.target
|
||||
Wants=network-online.target
|
||||
Before=thrillwiki-smart-deploy.timer
|
||||
PartOf=thrillwiki-smart-deploy.timer
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=thrillwiki
|
||||
Group=thrillwiki
|
||||
[AWS-SECRET-REMOVED]wiki
|
||||
[AWS-SECRET-REMOVED]ripts/vm/deploy-automation.sh
|
||||
ExecStop=/bin/kill -TERM $MAINPID
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Restart=always
|
||||
RestartSec=30
|
||||
KillMode=mixed
|
||||
KillSignal=SIGTERM
|
||||
TimeoutStopSec=120
|
||||
TimeoutStartSec=180
|
||||
StartLimitIntervalSec=600
|
||||
StartLimitBurst=3
|
||||
|
||||
# Environment variables - Load from file for security and preset integration
|
||||
EnvironmentFile=-[AWS-SECRET-REMOVED]emd/thrillwiki-deployment***REMOVED***
|
||||
Environment=PROJECT_DIR=/home/thrillwiki/thrillwiki
|
||||
Environment=SERVICE_NAME=thrillwiki-deployment
|
||||
Environment=GITHUB_REPO=origin
|
||||
Environment=GITHUB_BRANCH=main
|
||||
Environment=DEPLOYMENT_MODE=automated
|
||||
Environment=LOG_DIR=/home/thrillwiki/thrillwiki/logs
|
||||
Environment=MAX_LOG_SIZE=10485760
|
||||
Environment=SERVER_HOST=0.0.0.0
|
||||
Environment=SERVER_PORT=8000
|
||||
Environment=PATH=/home/thrillwiki/.local/bin:/home/thrillwiki/.cargo/bin:/usr/local/bin:/usr/bin:/bin
|
||||
[AWS-SECRET-REMOVED]thrillwiki
|
||||
|
||||
# Security settings - Enhanced hardening for deployment automation
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectControlGroups=true
|
||||
RestrictSUIDSGID=true
|
||||
RestrictRealtime=true
|
||||
RestrictNamespaces=true
|
||||
LockPersonality=true
|
||||
MemoryDenyWriteExecute=false
|
||||
RemoveIPC=true
|
||||
|
||||
# File system permissions - Allow access to necessary directories
|
||||
[AWS-SECRET-REMOVED]ki
|
||||
[AWS-SECRET-REMOVED]ki/logs
|
||||
[AWS-SECRET-REMOVED]ki/media
|
||||
[AWS-SECRET-REMOVED]ki/staticfiles
|
||||
[AWS-SECRET-REMOVED]ki/uploads
|
||||
ReadWritePaths=/home/thrillwiki/.cache
|
||||
ReadWritePaths=/tmp
|
||||
ReadOnlyPaths=/home/thrillwiki/.github-pat
|
||||
ReadOnlyPaths=/home/thrillwiki/.ssh
|
||||
ReadOnlyPaths=/home/thrillwiki/.local
|
||||
|
||||
# Resource limits - Appropriate for deployment automation
|
||||
LimitNOFILE=65536
|
||||
LimitNPROC=2048
|
||||
MemoryMax=1G
|
||||
CPUQuota=75%
|
||||
TasksMax=512
|
||||
|
||||
# Timeouts and watchdog
|
||||
WatchdogSec=600
|
||||
RuntimeMaxSec=0
|
||||
|
||||
# Logging configuration
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=thrillwiki-deployment
|
||||
SyslogFacility=daemon
|
||||
SyslogLevel=info
|
||||
SyslogLevelPrefix=true
|
||||
|
||||
# Enhanced logging for debugging
|
||||
LogsDirectory=thrillwiki-deployment
|
||||
LogsDirectoryMode=0755
|
||||
StateDirectory=thrillwiki-deployment
|
||||
StateDirectoryMode=0755
|
||||
RuntimeDirectory=thrillwiki-deployment
|
||||
RuntimeDirectoryMode=0755
|
||||
|
||||
# Capabilities - Minimal required capabilities
|
||||
CapabilityBoundingSet=
|
||||
AmbientCapabilities=
|
||||
PrivateDevices=true
|
||||
ProtectClock=true
|
||||
ProtectHostname=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Also=thrillwiki-smart-deploy.timer
|
||||
@@ -1,76 +0,0 @@
|
||||
[Unit]
|
||||
Description=ThrillWiki Smart Deployment Service
|
||||
Documentation=man:thrillwiki-smart-deploy(8)
|
||||
After=network.target thrillwiki-deployment.service
|
||||
Wants=network.target
|
||||
PartOf=thrillwiki-smart-deploy.timer
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=thrillwiki
|
||||
Group=thrillwiki
|
||||
[AWS-SECRET-REMOVED]wiki
|
||||
[AWS-SECRET-REMOVED]ripts/smart-deploy.sh
|
||||
TimeoutStartSec=300
|
||||
TimeoutStopSec=60
|
||||
|
||||
# Environment variables - Load from deployment configuration
|
||||
EnvironmentFile=-[AWS-SECRET-REMOVED]emd/thrillwiki-deployment***REMOVED***
|
||||
Environment=PROJECT_DIR=/home/thrillwiki/thrillwiki
|
||||
Environment=SERVICE_NAME=thrillwiki-smart-deploy
|
||||
Environment=DEPLOYMENT_MODE=timer
|
||||
Environment=LOG_DIR=/home/thrillwiki/thrillwiki/logs
|
||||
Environment=PATH=/home/thrillwiki/.local/bin:/home/thrillwiki/.cargo/bin:/usr/local/bin:/usr/bin:/bin
|
||||
[AWS-SECRET-REMOVED]thrillwiki
|
||||
|
||||
# Security settings - Inherited from main deployment service
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectControlGroups=true
|
||||
RestrictSUIDSGID=true
|
||||
RestrictRealtime=true
|
||||
RestrictNamespaces=true
|
||||
LockPersonality=true
|
||||
MemoryDenyWriteExecute=false
|
||||
RemoveIPC=true
|
||||
|
||||
# File system permissions
|
||||
[AWS-SECRET-REMOVED]ki
|
||||
[AWS-SECRET-REMOVED]ki/logs
|
||||
[AWS-SECRET-REMOVED]ki/media
|
||||
[AWS-SECRET-REMOVED]ki/staticfiles
|
||||
[AWS-SECRET-REMOVED]ki/uploads
|
||||
ReadWritePaths=/home/thrillwiki/.cache
|
||||
ReadWritePaths=/tmp
|
||||
ReadOnlyPaths=/home/thrillwiki/.github-pat
|
||||
ReadOnlyPaths=/home/thrillwiki/.ssh
|
||||
ReadOnlyPaths=/home/thrillwiki/.local
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65536
|
||||
LimitNPROC=1024
|
||||
MemoryMax=512M
|
||||
CPUQuota=50%
|
||||
TasksMax=256
|
||||
|
||||
# Logging configuration
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=thrillwiki-smart-deploy
|
||||
SyslogFacility=daemon
|
||||
SyslogLevel=info
|
||||
SyslogLevelPrefix=true
|
||||
|
||||
# Capabilities
|
||||
CapabilityBoundingSet=
|
||||
AmbientCapabilities=
|
||||
PrivateDevices=true
|
||||
ProtectClock=true
|
||||
ProtectHostname=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,17 +0,0 @@
|
||||
[Unit]
|
||||
Description=ThrillWiki Smart Deployment Timer
|
||||
Documentation=man:thrillwiki-smart-deploy(8)
|
||||
Requires=thrillwiki-smart-deploy.service
|
||||
After=thrillwiki-deployment.service
|
||||
|
||||
[Timer]
|
||||
# Default timer configuration (can be overridden by environment)
|
||||
OnBootSec=5min
|
||||
OnUnitActiveSec=5min
|
||||
Unit=thrillwiki-smart-deploy.service
|
||||
Persistent=true
|
||||
RandomizedDelaySec=30sec
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
Also=thrillwiki-smart-deploy.service
|
||||
@@ -1,39 +0,0 @@
|
||||
[Unit]
|
||||
Description=ThrillWiki GitHub Webhook Listener
|
||||
After=network.target
|
||||
Wants=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=ubuntu
|
||||
Group=ubuntu
|
||||
[AWS-SECRET-REMOVED]
|
||||
ExecStart=/usr/bin/python3 /home/ubuntu/thrillwiki/scripts/webhook-listener.py
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
# Environment variables
|
||||
Environment=WEBHOOK_PORT=9000
|
||||
Environment=WEBHOOK_SECRET=your_webhook_secret_here
|
||||
Environment=VM_HOST=localhost
|
||||
Environment=VM_PORT=22
|
||||
Environment=VM_USER=ubuntu
|
||||
Environment=VM_KEY_PATH=/home/ubuntu/.ssh/***REMOVED***
|
||||
Environment=VM_PROJECT_PATH=/home/ubuntu/thrillwiki
|
||||
Environment=REPO_URL=https://github.com/YOUR_USERNAME/thrillwiki_django_no_react.git
|
||||
Environment=DEPLOY_BRANCH=main
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
[AWS-SECRET-REMOVED]ogs
|
||||
|
||||
# Logging
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=thrillwiki-webhook
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,45 +0,0 @@
|
||||
[Unit]
|
||||
Description=ThrillWiki Django Application
|
||||
After=network.target postgresql.service
|
||||
Wants=network.target
|
||||
Requires=postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
User=ubuntu
|
||||
Group=ubuntu
|
||||
[AWS-SECRET-REMOVED]
|
||||
[AWS-SECRET-REMOVED]s/ci-start.sh
|
||||
ExecStop=/bin/kill -TERM $MAINPID
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
[AWS-SECRET-REMOVED]ngo.pid
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
# Environment variables
|
||||
Environment=DJANGO_SETTINGS_MODULE=thrillwiki.settings
|
||||
[AWS-SECRET-REMOVED]llwiki
|
||||
Environment=PATH=/home/ubuntu/.cargo/bin:/usr/local/bin:/usr/bin:/bin
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
[AWS-SECRET-REMOVED]ogs
|
||||
[AWS-SECRET-REMOVED]edia
|
||||
[AWS-SECRET-REMOVED]taticfiles
|
||||
[AWS-SECRET-REMOVED]ploads
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65536
|
||||
TimeoutStartSec=300
|
||||
TimeoutStopSec=30
|
||||
|
||||
# Logging
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=thrillwiki
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,175 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ThrillWiki Automation Test Script
|
||||
# This script validates all automation components without actually running them
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
log() {
|
||||
echo -e "${BLUE}[TEST]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[✓]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[!]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[✗]${NC} $1"
|
||||
}
|
||||
|
||||
# Test counters
|
||||
TESTS_PASSED=0
|
||||
TESTS_FAILED=0
|
||||
TESTS_TOTAL=0
|
||||
|
||||
test_case() {
|
||||
local name="$1"
|
||||
local command="$2"
|
||||
|
||||
((TESTS_TOTAL++))
|
||||
log "Testing: $name"
|
||||
|
||||
if eval "$command" >/dev/null 2>&1; then
|
||||
log_success "$name"
|
||||
((TESTS_PASSED++))
|
||||
else
|
||||
log_error "$name"
|
||||
((TESTS_FAILED++))
|
||||
fi
|
||||
}
|
||||
|
||||
test_case_with_output() {
|
||||
local name="$1"
|
||||
local command="$2"
|
||||
local expected_pattern="$3"
|
||||
|
||||
((TESTS_TOTAL++))
|
||||
log "Testing: $name"
|
||||
|
||||
local output
|
||||
if output=$(eval "$command" 2>&1); then
|
||||
if [[ -n "$expected_pattern" && ! "$output" =~ $expected_pattern ]]; then
|
||||
log_error "$name (unexpected output)"
|
||||
((TESTS_FAILED++))
|
||||
else
|
||||
log_success "$name"
|
||||
((TESTS_PASSED++))
|
||||
fi
|
||||
else
|
||||
log_error "$name (command failed)"
|
||||
((TESTS_FAILED++))
|
||||
fi
|
||||
}
|
||||
|
||||
log "🧪 Starting ThrillWiki Automation Tests"
|
||||
echo "======================================"
|
||||
|
||||
# Test 1: File Permissions
|
||||
log "\n📁 Testing File Permissions..."
|
||||
test_case "CI start script is executable" "[ -x scripts/ci-start.sh ]"
|
||||
test_case "VM deploy script is executable" "[ -x scripts/vm-deploy.sh ]"
|
||||
test_case "Webhook listener is executable" "[ -x scripts/webhook-listener.py ]"
|
||||
test_case "VM manager is executable" "[ -x scripts/unraid/vm-manager.py ]"
|
||||
test_case "Complete automation script is executable" "[ -x scripts/unraid/setup-complete-automation.sh ]"
|
||||
|
||||
# Test 2: Script Syntax
|
||||
log "\n🔍 Testing Script Syntax..."
|
||||
test_case "CI start script syntax" "bash -n scripts/ci-start.sh"
|
||||
test_case "VM deploy script syntax" "bash -n scripts/vm-deploy.sh"
|
||||
test_case "Setup VM CI script syntax" "bash -n scripts/setup-vm-ci.sh"
|
||||
test_case "Complete automation script syntax" "bash -n scripts/unraid/setup-complete-automation.sh"
|
||||
test_case "Webhook listener Python syntax" "python3 -m py_compile scripts/webhook-listener.py"
|
||||
test_case "VM manager Python syntax" "python3 -m py_compile scripts/unraid/vm-manager.py"
|
||||
|
||||
# Test 3: Help Functions
|
||||
log "\n❓ Testing Help Functions..."
|
||||
test_case_with_output "VM manager help" "python3 scripts/unraid/vm-manager.py --help" "usage:"
|
||||
test_case_with_output "Webhook listener help" "python3 scripts/webhook-listener.py --help" "usage:"
|
||||
test_case_with_output "VM deploy script usage" "scripts/vm-deploy.sh invalid 2>&1" "Usage:"
|
||||
|
||||
# Test 4: Configuration Validation
|
||||
log "\n⚙️ Testing Configuration Validation..."
|
||||
test_case_with_output "Webhook listener test mode" "python3 scripts/webhook-listener.py --test" "Configuration validation"
|
||||
|
||||
# Test 5: Directory Structure
|
||||
log "\n📂 Testing Directory Structure..."
|
||||
test_case "Scripts directory exists" "[ -d scripts ]"
|
||||
test_case "Unraid scripts directory exists" "[ -d scripts/unraid ]"
|
||||
test_case "Systemd directory exists" "[ -d scripts/systemd ]"
|
||||
test_case "Docs directory exists" "[ -d docs ]"
|
||||
test_case "Logs directory created" "[ -d logs ]"
|
||||
|
||||
# Test 6: Required Files
|
||||
log "\n📄 Testing Required Files..."
|
||||
test_case "ThrillWiki service file exists" "[ -f scripts/systemd/thrillwiki.service ]"
|
||||
test_case "Webhook service file exists" "[ -f scripts/systemd/thrillwiki-webhook.service ]"
|
||||
test_case "VM deployment setup doc exists" "[ -f docs/VM_DEPLOYMENT_SETUP.md ]"
|
||||
test_case "Unraid automation doc exists" "[ -f docs/UNRAID_COMPLETE_AUTOMATION.md ]"
|
||||
test_case "CI README exists" "[ -f CI_README.md ]"
|
||||
|
||||
# Test 7: Python Dependencies
|
||||
log "\n🐍 Testing Python Dependencies..."
|
||||
test_case "Python 3 available" "command -v python3"
|
||||
test_case "Requests module available" "python3 -c 'import requests'"
|
||||
test_case "JSON module available" "python3 -c 'import json'"
|
||||
test_case "OS module available" "python3 -c 'import os'"
|
||||
test_case "Subprocess module available" "python3 -c 'import subprocess'"
|
||||
|
||||
# Test 8: System Dependencies
|
||||
log "\n🔧 Testing System Dependencies..."
|
||||
test_case "SSH command available" "command -v ssh"
|
||||
test_case "SCP command available" "command -v scp"
|
||||
test_case "Bash available" "command -v bash"
|
||||
test_case "Git available" "command -v git"
|
||||
|
||||
# Test 9: UV Package Manager
|
||||
log "\n📦 Testing UV Package Manager..."
|
||||
if command -v uv >/dev/null 2>&1; then
|
||||
log_success "UV package manager is available"
|
||||
((TESTS_PASSED++))
|
||||
test_case "UV version check" "uv --version"
|
||||
else
|
||||
log_warning "UV package manager not found (will be installed during setup)"
|
||||
((TESTS_PASSED++))
|
||||
fi
|
||||
((TESTS_TOTAL++))
|
||||
|
||||
# Test 10: Django Project Structure
|
||||
log "\n🌟 Testing Django Project Structure..."
|
||||
test_case "Django manage.py exists" "[ -f manage.py ]"
|
||||
test_case "Django settings module exists" "[ -f thrillwiki/settings.py ]"
|
||||
test_case "PyProject.toml exists" "[ -f pyproject.toml ]"
|
||||
|
||||
# Final Results
|
||||
echo
|
||||
log "📊 Test Results Summary"
|
||||
echo "======================"
|
||||
echo "Total Tests: $TESTS_TOTAL"
|
||||
echo "Passed: $TESTS_PASSED"
|
||||
echo "Failed: $TESTS_FAILED"
|
||||
|
||||
if [ $TESTS_FAILED -eq 0 ]; then
|
||||
echo
|
||||
log_success "🎉 All tests passed! The automation system is ready."
|
||||
echo
|
||||
log "Next steps:"
|
||||
echo "1. For complete automation: ./scripts/unraid/setup-complete-automation.sh"
|
||||
echo "2. For manual setup: ./scripts/setup-vm-ci.sh"
|
||||
echo "3. Read documentation: docs/UNRAID_COMPLETE_AUTOMATION.md"
|
||||
exit 0
|
||||
else
|
||||
echo
|
||||
log_error "❌ Some tests failed. Please check the issues above."
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"permissions": {
|
||||
"additionalDirectories": [
|
||||
"/Users/talor/thrillwiki_django_no_react"
|
||||
],
|
||||
"allow": [
|
||||
"Bash(uv run:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
# Non-Interactive Mode for ThrillWiki Automation
|
||||
|
||||
The ThrillWiki automation script supports a non-interactive mode (`-y` flag) that allows you to run the entire setup process without any user prompts. This is perfect for:
|
||||
|
||||
- **CI/CD pipelines**
|
||||
- **Automated deployments**
|
||||
- **Scripted environments**
|
||||
- **Remote execution**
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Saved Configuration**: You must have run the script interactively at least once to create the saved configuration file (`.thrillwiki-config`).
|
||||
|
||||
2. **Environment Variables**: Set the required environment variables for sensitive credentials that aren't saved to disk.
|
||||
|
||||
## Required Environment Variables
|
||||
|
||||
### Always Required
|
||||
- `UNRAID_PASSWORD` - Your Unraid server password
|
||||
|
||||
### Required if GitHub API is enabled
|
||||
- `GITHUB_TOKEN` - Your GitHub personal access token (if using token auth method)
|
||||
|
||||
### Required if Webhooks are enabled
|
||||
- `WEBHOOK_SECRET` - Your GitHub webhook secret
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Basic Non-Interactive Setup
|
||||
```bash
|
||||
# Set required credentials
|
||||
export UNRAID_PASSWORD="your_unraid_password"
|
||||
export GITHUB_TOKEN="your_github_token"
|
||||
export WEBHOOK_SECRET="your_webhook_secret"
|
||||
|
||||
# Run in non-interactive mode
|
||||
./setup-complete-automation.sh -y
|
||||
```
|
||||
|
||||
### CI/CD Pipeline Example
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Load credentials from secure environment
|
||||
export UNRAID_PASSWORD="$UNRAID_CREDS_PASSWORD"
|
||||
export GITHUB_TOKEN="$GITHUB_API_TOKEN"
|
||||
export WEBHOOK_SECRET="$WEBHOOK_SECRET_KEY"
|
||||
|
||||
# Deploy with no user interaction
|
||||
cd scripts/unraid
|
||||
./setup-complete-automation.sh -y
|
||||
```
|
||||
|
||||
### Docker/Container Example
|
||||
```bash
|
||||
# Run from container with environment file
|
||||
docker run --env-file ***REMOVED***.secrets \
|
||||
-v $(pwd):/workspace \
|
||||
your-automation-container \
|
||||
/workspace/scripts/unraid/setup-complete-automation.sh -y
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
The script will exit with clear error messages if:
|
||||
|
||||
- No saved configuration is found
|
||||
- Required environment variables are missing
|
||||
- OAuth tokens have expired (non-interactive mode cannot refresh them)
|
||||
|
||||
### Common Issues
|
||||
|
||||
**❌ No saved configuration**
|
||||
```
|
||||
[ERROR] No saved configuration found. Cannot run in non-interactive mode.
|
||||
[ERROR] Please run the script without -y flag first to create initial configuration.
|
||||
```
|
||||
**Solution**: Run `./setup-complete-automation.sh` interactively first.
|
||||
|
||||
**❌ Missing password**
|
||||
```
|
||||
[ERROR] UNRAID_PASSWORD environment variable not set.
|
||||
[ERROR] For non-interactive mode, set: export UNRAID_PASSWORD='your_password'
|
||||
```
|
||||
**Solution**: Set the `UNRAID_PASSWORD` environment variable.
|
||||
|
||||
**❌ Expired OAuth token**
|
||||
```
|
||||
[ERROR] OAuth token expired and cannot refresh in non-interactive mode
|
||||
[ERROR] Please run without -y flag to re-authenticate with GitHub
|
||||
```
|
||||
**Solution**: Run interactively to refresh OAuth token, or switch to personal access token method.
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
1. **Never commit credentials to version control**
|
||||
2. **Use secure environment variable storage** (CI/CD secret stores, etc.)
|
||||
3. **Rotate credentials regularly**
|
||||
4. **Use minimal required permissions** for tokens
|
||||
5. **Clear environment variables** after use if needed:
|
||||
```bash
|
||||
unset UNRAID_PASSWORD GITHUB_TOKEN WEBHOOK_SECRET
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Combining with Reset Modes
|
||||
```bash
|
||||
# Reset VM only and redeploy non-interactively
|
||||
export UNRAID_PASSWORD="password"
|
||||
./setup-complete-automation.sh --reset-vm -y
|
||||
```
|
||||
|
||||
### Using with Different Authentication Methods
|
||||
```bash
|
||||
# For OAuth method (no GITHUB_TOKEN needed if valid)
|
||||
export UNRAID_PASSWORD="password"
|
||||
export WEBHOOK_SECRET="secret"
|
||||
./setup-complete-automation.sh -y
|
||||
|
||||
# For personal access token method
|
||||
export UNRAID_PASSWORD="password"
|
||||
export GITHUB_TOKEN="ghp_xxxx"
|
||||
export WEBHOOK_SECRET="secret"
|
||||
./setup-complete-automation.sh -y
|
||||
```
|
||||
|
||||
### Environment File Pattern
|
||||
```bash
|
||||
# Create ***REMOVED***.automation (don't commit this!)
|
||||
cat > ***REMOVED***.automation << EOF
|
||||
UNRAID_PASSWORD=your_password_here
|
||||
GITHUB_TOKEN=your_token_here
|
||||
WEBHOOK_SECRET=your_secret_here
|
||||
EOF
|
||||
|
||||
# Use it
|
||||
source ***REMOVED***.automation
|
||||
./setup-complete-automation.sh -y
|
||||
|
||||
# Clean up
|
||||
rm ***REMOVED***.automation
|
||||
```
|
||||
|
||||
## Integration Examples
|
||||
|
||||
See `example-non-interactive.sh` for a complete working example that you can customize for your needs.
|
||||
|
||||
The non-interactive mode makes it easy to integrate ThrillWiki deployment into your existing automation workflows while maintaining security and reliability.
|
||||
@@ -1,385 +0,0 @@
|
||||
# ThrillWiki Template-Based VM Deployment
|
||||
|
||||
This guide explains how to use the new **template-based VM deployment** system that dramatically speeds up VM creation by using a pre-configured Ubuntu template instead of autoinstall ISOs.
|
||||
|
||||
## Overview
|
||||
|
||||
### Traditional Approach (Slow)
|
||||
- Create autoinstall ISO from scratch
|
||||
- Boot VM from ISO (20-30 minutes)
|
||||
- Wait for Ubuntu installation
|
||||
- Configure system packages and dependencies
|
||||
|
||||
### Template Approach (Fast ⚡)
|
||||
- Copy pre-configured VM disk from template
|
||||
- Boot VM from template disk (2-5 minutes)
|
||||
- System is already configured with Ubuntu, packages, and dependencies
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Template VM**: You must have a VM named `thrillwiki-template-ubuntu` on your Unraid server
|
||||
2. **Template Configuration**: The template should be pre-configured with:
|
||||
- Ubuntu 24.04 LTS
|
||||
- Python 3, Git, PostgreSQL, Nginx
|
||||
- UV package manager (optional but recommended)
|
||||
- Basic system configuration
|
||||
|
||||
## Template VM Setup
|
||||
|
||||
### Creating the Template VM
|
||||
|
||||
1. **Create the template VM manually** on your Unraid server:
|
||||
- Name: `thrillwiki-template-ubuntu`
|
||||
- Install Ubuntu 24.04 LTS
|
||||
- Configure with 4GB RAM, 2 vCPUs (can be adjusted later)
|
||||
|
||||
2. **Configure the template** by SSH'ing into it and running:
|
||||
```bash
|
||||
# Update system
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# Install required packages
|
||||
sudo apt install -y git curl build-essential python3-pip python3-venv
|
||||
sudo apt install -y postgresql postgresql-contrib nginx
|
||||
|
||||
# Install UV (Python package manager)
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
source ~/.cargo/env
|
||||
|
||||
# Create thrillwiki user with password 'thrillwiki'
|
||||
sudo useradd -m -s /bin/bash thrillwiki || true
|
||||
echo 'thrillwiki:thrillwiki' | sudo chpasswd
|
||||
sudo usermod -aG sudo thrillwiki
|
||||
|
||||
# Setup SSH key for thrillwiki user
|
||||
# First, generate your SSH key on your Mac:
|
||||
# ssh-keygen -t rsa -b 4096 -f ~/.ssh/thrillwiki_vm -N "" -C "thrillwiki-template-vm-access"
|
||||
# Then copy the public key to the template VM:
|
||||
sudo mkdir -p /home/thrillwiki/.ssh
|
||||
echo "YOUR_PUBLIC_KEY_FROM_~/.ssh/thrillwiki_vm.pub" | sudo tee /home/thrillwiki/.ssh/***REMOVED***
|
||||
sudo chown -R thrillwiki:thrillwiki /home/thrillwiki/.ssh
|
||||
sudo chmod 700 /home/thrillwiki/.ssh
|
||||
sudo chmod 600 /home/thrillwiki/.ssh/***REMOVED***
|
||||
|
||||
# Configure PostgreSQL
|
||||
sudo systemctl enable postgresql
|
||||
sudo systemctl start postgresql
|
||||
|
||||
# Configure Nginx
|
||||
sudo systemctl enable nginx
|
||||
|
||||
# Clean up for template
|
||||
sudo apt autoremove -y
|
||||
sudo apt autoclean
|
||||
history -c && history -w
|
||||
|
||||
# Shutdown template
|
||||
sudo shutdown now
|
||||
```
|
||||
|
||||
3. **Verify template** is stopped and ready:
|
||||
```bash
|
||||
./template-utils.sh status # Should show "shut off"
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Step 0: Set Up SSH Key (First Time Only)
|
||||
|
||||
**IMPORTANT**: Before using template deployment, set up your SSH key:
|
||||
|
||||
```bash
|
||||
# Generate and configure SSH key
|
||||
./scripts/unraid/setup-ssh-key.sh
|
||||
|
||||
# Follow the instructions to add the public key to your template VM
|
||||
```
|
||||
|
||||
See `TEMPLATE_VM_SETUP.md` for complete template VM setup instructions.
|
||||
|
||||
### Using the Utility Script
|
||||
|
||||
The easiest way to work with template VMs is using the utility script:
|
||||
|
||||
```bash
|
||||
# Check if template is ready
|
||||
./template-utils.sh check
|
||||
|
||||
# Get template information
|
||||
./template-utils.sh info
|
||||
|
||||
# Deploy a new VM from template
|
||||
./template-utils.sh deploy my-thrillwiki-vm
|
||||
|
||||
# Copy template to new VM (without full deployment)
|
||||
./template-utils.sh copy my-vm-name
|
||||
|
||||
# List all template-based VMs
|
||||
./template-utils.sh list
|
||||
```
|
||||
|
||||
### Using Python Scripts Directly
|
||||
|
||||
For more control, use the Python scripts:
|
||||
|
||||
```bash
|
||||
# Set environment variables
|
||||
export UNRAID_HOST="your.unraid.server.ip"
|
||||
export UNRAID_USER="root"
|
||||
export VM_NAME="my-thrillwiki-vm"
|
||||
export REPO_URL="owner/repository-name"
|
||||
|
||||
# Deploy VM from template
|
||||
python3 main_template.py deploy
|
||||
|
||||
# Just create VM without ThrillWiki setup
|
||||
python3 main_template.py setup
|
||||
|
||||
# Get VM status and IP
|
||||
python3 main_template.py status
|
||||
python3 main_template.py ip
|
||||
|
||||
# Manage template
|
||||
python3 main_template.py template info
|
||||
python3 main_template.py template check
|
||||
```
|
||||
|
||||
## File Structure
|
||||
|
||||
### New Template-Based Files
|
||||
|
||||
```
|
||||
scripts/unraid/
|
||||
├── template_manager.py # Template VM management
|
||||
├── vm_manager_template.py # Template-based VM manager
|
||||
├── main_template.py # Template deployment orchestrator
|
||||
├── template-utils.sh # Quick utility commands
|
||||
├── deploy-thrillwiki-template.sh # Optimized deployment script
|
||||
├── thrillwiki-vm-template-simple.xml # VM XML without autoinstall ISO
|
||||
└── README-template-deployment.md # This documentation
|
||||
```
|
||||
|
||||
### Original Files (Still Available)
|
||||
|
||||
```
|
||||
scripts/unraid/
|
||||
├── main.py # Original autoinstall approach
|
||||
├── vm_manager.py # Original VM manager
|
||||
├── deploy-thrillwiki.sh # Original deployment script
|
||||
└── thrillwiki-vm-template.xml # Original XML with autoinstall
|
||||
```
|
||||
|
||||
## Commands Reference
|
||||
|
||||
### Template Management
|
||||
|
||||
```bash
|
||||
# Check template status
|
||||
./template-utils.sh status
|
||||
python3 template_manager.py check
|
||||
|
||||
# Get template information
|
||||
./template-utils.sh info
|
||||
python3 template_manager.py info
|
||||
|
||||
# List VMs created from template
|
||||
./template-utils.sh list
|
||||
python3 template_manager.py list
|
||||
|
||||
# Update template instructions
|
||||
./template-utils.sh update
|
||||
python3 template_manager.py update
|
||||
```
|
||||
|
||||
### VM Deployment
|
||||
|
||||
```bash
|
||||
# Complete deployment (VM + ThrillWiki)
|
||||
./template-utils.sh deploy VM_NAME
|
||||
python3 main_template.py deploy
|
||||
|
||||
# VM setup only
|
||||
python3 main_template.py setup
|
||||
|
||||
# Individual operations
|
||||
python3 main_template.py create
|
||||
python3 main_template.py start
|
||||
python3 main_template.py stop
|
||||
python3 main_template.py delete
|
||||
```
|
||||
|
||||
### VM Information
|
||||
|
||||
```bash
|
||||
# Get VM status
|
||||
python3 main_template.py status
|
||||
|
||||
# Get VM IP and connection info
|
||||
python3 main_template.py ip
|
||||
|
||||
# Get detailed VM information
|
||||
python3 main_template.py info
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Configure these in your `***REMOVED***.unraid` file or export them:
|
||||
|
||||
```bash
|
||||
# Required
|
||||
UNRAID_HOST="192.168.1.100" # Your Unraid server IP
|
||||
UNRAID_USER="root" # Unraid SSH user
|
||||
VM_NAME="thrillwiki-vm" # Name for new VM
|
||||
|
||||
# Optional VM Configuration
|
||||
VM_MEMORY="4096" # Memory in MB
|
||||
VM_VCPUS="2" # Number of vCPUs
|
||||
VM_DISK_SIZE="50" # Disk size in GB (for reference)
|
||||
VM_IP="dhcp" # IP configuration (dhcp or static IP)
|
||||
|
||||
# ThrillWiki Configuration
|
||||
REPO_URL="owner/repository-name" # GitHub repository
|
||||
GITHUB_TOKEN="ghp_xxxxx" # GitHub token (optional)
|
||||
```
|
||||
|
||||
## Advantages of Template Approach
|
||||
|
||||
### Speed ⚡
|
||||
- **VM Creation**: 2-5 minutes vs 20-30 minutes
|
||||
- **Boot Time**: Instant boot vs full Ubuntu installation
|
||||
- **Total Deployment**: ~10 minutes vs ~45 minutes
|
||||
|
||||
### Reliability 🔒
|
||||
- **Pre-tested**: Template is already configured and tested
|
||||
- **Consistent**: All VMs start from identical base
|
||||
- **No Installation Failures**: No autoinstall ISO issues
|
||||
|
||||
### Efficiency 💾
|
||||
- **Disk Space**: Copy-on-write QCOW2 format
|
||||
- **Network**: No ISO downloads during deployment
|
||||
- **Resources**: Less CPU usage during creation
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Template Not Found
|
||||
```
|
||||
❌ Template VM disk not found at: /mnt/user/domains/thrillwiki-template-ubuntu/vdisk1.qcow2
|
||||
```
|
||||
|
||||
**Solution**: Create the template VM first or verify the path.
|
||||
|
||||
### Template VM Running
|
||||
```
|
||||
⚠️ Template VM is currently running!
|
||||
```
|
||||
|
||||
**Solution**: Stop the template VM before creating new instances:
|
||||
```bash
|
||||
ssh root@unraid-host "virsh shutdown thrillwiki-template-ubuntu"
|
||||
```
|
||||
|
||||
### SSH Connection Issues
|
||||
```
|
||||
❌ Cannot connect to Unraid server
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
1. Verify `UNRAID_HOST` is correct
|
||||
2. Ensure SSH key authentication is set up
|
||||
3. Check network connectivity
|
||||
|
||||
### Template Disk Corruption
|
||||
|
||||
If template VM gets corrupted:
|
||||
1. Start template VM and fix issues
|
||||
2. Or recreate template VM from scratch
|
||||
3. Update template: `./template-utils.sh update`
|
||||
|
||||
## Template Maintenance
|
||||
|
||||
### Updating the Template
|
||||
|
||||
Periodically update your template:
|
||||
|
||||
1. **Start template VM** on Unraid
|
||||
2. **SSH into template** and update:
|
||||
```bash
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
sudo apt autoremove -y && sudo apt autoclean
|
||||
|
||||
# Update UV if installed
|
||||
~/.cargo/bin/uv --version
|
||||
|
||||
# Clear history
|
||||
history -c && history -w
|
||||
```
|
||||
3. **Shutdown template VM**
|
||||
4. **Verify update**: `./template-utils.sh check`
|
||||
|
||||
### Template Best Practices
|
||||
|
||||
- Keep template VM stopped when not maintaining it
|
||||
- Update template monthly or before major deployments
|
||||
- Test template by creating a test VM before important deployments
|
||||
- Document any custom configurations in the template
|
||||
|
||||
## Migration Guide
|
||||
|
||||
### From Autoinstall to Template
|
||||
|
||||
1. **Create your template VM** following the setup guide above
|
||||
2. **Test template deployment**:
|
||||
```bash
|
||||
./template-utils.sh deploy test-vm
|
||||
```
|
||||
3. **Update your automation scripts** to use template approach
|
||||
4. **Keep autoinstall scripts** as backup for special cases
|
||||
|
||||
### Switching Between Approaches
|
||||
|
||||
You can use both approaches as needed:
|
||||
|
||||
```bash
|
||||
# Template-based (fast)
|
||||
python3 main_template.py deploy
|
||||
|
||||
# Autoinstall-based (traditional)
|
||||
python3 main.py setup
|
||||
```
|
||||
|
||||
## Integration with CI/CD
|
||||
|
||||
The template approach integrates perfectly with your existing CI/CD:
|
||||
|
||||
```bash
|
||||
# In your automation scripts
|
||||
export UNRAID_HOST="your-server"
|
||||
export VM_NAME="thrillwiki-$(date +%s)"
|
||||
export REPO_URL="your-org/thrillwiki"
|
||||
|
||||
# Deploy quickly
|
||||
./scripts/unraid/template-utils.sh deploy "$VM_NAME"
|
||||
|
||||
# VM is ready in minutes instead of 30+ minutes
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
**Q: Can I use both template and autoinstall approaches?**
|
||||
A: Yes! Keep both. Use template for speed, autoinstall for special configurations.
|
||||
|
||||
**Q: How much disk space does template copying use?**
|
||||
A: QCOW2 copy-on-write format means copies only store differences, saving space.
|
||||
|
||||
**Q: What if I need different Ubuntu versions?**
|
||||
A: Create multiple template VMs (e.g., `thrillwiki-template-ubuntu-22`, `thrillwiki-template-ubuntu-24`).
|
||||
|
||||
**Q: Can I customize the template VM configuration?**
|
||||
A: Yes! The template VM is just a regular VM. Customize it as needed.
|
||||
|
||||
**Q: Is this approach secure?**
|
||||
A: Yes. Each VM gets a fresh copy and can be configured independently.
|
||||
|
||||
---
|
||||
|
||||
This template-based approach should make your VM deployments much faster and more reliable! 🚀
|
||||
@@ -1,131 +0,0 @@
|
||||
# ThrillWiki Unraid VM Automation
|
||||
|
||||
This directory contains scripts and configuration files for automating the creation and deployment of ThrillWiki VMs on Unraid servers using Ubuntu autoinstall.
|
||||
|
||||
## Files
|
||||
|
||||
- **`vm-manager.py`** - Main VM management script with direct kernel boot support
|
||||
- **`thrillwiki-vm-template.xml`** - VM XML configuration template for libvirt
|
||||
- **`cloud-init-template.yaml`** - Ubuntu autoinstall configuration template
|
||||
- **`validate-autoinstall.py`** - Validation script for autoinstall configuration
|
||||
|
||||
## Key Features
|
||||
|
||||
### Direct Kernel Boot Approach
|
||||
The system now uses direct kernel boot instead of GRUB-based boot for maximum reliability:
|
||||
|
||||
1. **Kernel Extraction**: Automatically extracts Ubuntu kernel and initrd files from the ISO
|
||||
2. **Direct Boot**: VM boots directly using extracted kernel with explicit autoinstall parameters
|
||||
3. **Reliable Autoinstall**: Kernel cmdline explicitly specifies `autoinstall ds=nocloud-net;s=cdrom:/`
|
||||
|
||||
### Schema-Compliant Configuration
|
||||
The autoinstall configuration has been validated against Ubuntu's official schema:
|
||||
|
||||
- ✅ Proper network configuration structure
|
||||
- ✅ Correct storage layout specification
|
||||
- ✅ Valid shutdown configuration
|
||||
- ✅ Schema-compliant field types and values
|
||||
|
||||
## Usage
|
||||
|
||||
### Environment Variables
|
||||
Set these environment variables before running:
|
||||
|
||||
```bash
|
||||
export UNRAID_HOST="your-unraid-server"
|
||||
export UNRAID_USER="root"
|
||||
export UNRAID_PASSWORD="your-password"
|
||||
export SSH_PUBLIC_KEY="your-ssh-public-key"
|
||||
export REPO_URL="https://github.com/your-username/thrillwiki.git"
|
||||
export VM_IP="192.168.20.20" # or "dhcp" for DHCP
|
||||
export VM_GATEWAY="192.168.20.1"
|
||||
```
|
||||
|
||||
### Basic Operations
|
||||
|
||||
```bash
|
||||
# Create and configure VM
|
||||
./vm-manager.py create
|
||||
|
||||
# Start the VM
|
||||
./vm-manager.py start
|
||||
|
||||
# Check VM status
|
||||
./vm-manager.py status
|
||||
|
||||
# Get VM IP address
|
||||
./vm-manager.py ip
|
||||
|
||||
# Complete setup (create + start + get IP)
|
||||
./vm-manager.py setup
|
||||
|
||||
# Stop the VM
|
||||
./vm-manager.py stop
|
||||
|
||||
# Delete VM and all files
|
||||
./vm-manager.py delete
|
||||
```
|
||||
|
||||
### Configuration Validation
|
||||
|
||||
```bash
|
||||
# Validate autoinstall configuration
|
||||
./validate-autoinstall.py
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
### VM Creation Process
|
||||
|
||||
1. **Extract Kernel**: Mount Ubuntu ISO and extract `vmlinuz` and `initrd` from `/casper/`
|
||||
2. **Create Cloud-Init ISO**: Generate configuration ISO with autoinstall settings
|
||||
3. **Generate VM XML**: Create libvirt VM configuration with direct kernel boot
|
||||
4. **Define VM**: Register VM as persistent domain in libvirt
|
||||
|
||||
### Boot Process
|
||||
|
||||
1. **Direct Kernel Boot**: VM starts using extracted kernel and initrd directly
|
||||
2. **Autoinstall Trigger**: Kernel cmdline forces Ubuntu installer into autoinstall mode
|
||||
3. **Cloud-Init Data**: NoCloud datasource provides configuration from CD-ROM
|
||||
4. **Automated Setup**: Ubuntu installs and configures ThrillWiki automatically
|
||||
|
||||
### Network Configuration
|
||||
|
||||
The system supports both static IP and DHCP configurations:
|
||||
|
||||
- **Static IP**: Set `VM_IP` to desired IP address (e.g., "192.168.20.20")
|
||||
- **DHCP**: Set `VM_IP` to "dhcp" for automatic IP assignment
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### VM Console Access
|
||||
Connect to VM console to monitor autoinstall progress:
|
||||
```bash
|
||||
ssh root@unraid-server
|
||||
virsh console thrillwiki-vm
|
||||
```
|
||||
|
||||
### Check VM Logs
|
||||
View autoinstall logs inside the VM:
|
||||
```bash
|
||||
# After VM is accessible
|
||||
ssh ubuntu@vm-ip
|
||||
sudo journalctl -u cloud-init
|
||||
tail -f /var/log/cloud-init.log
|
||||
```
|
||||
|
||||
### Validation Errors
|
||||
If autoinstall validation fails, check:
|
||||
1. YAML syntax in `cloud-init-template.yaml`
|
||||
2. Required fields according to Ubuntu schema
|
||||
3. Proper data types for configuration values
|
||||
|
||||
## Architecture Benefits
|
||||
|
||||
1. **Reliable Boot**: Direct kernel boot eliminates GRUB-related issues
|
||||
2. **Schema Compliance**: Configuration validated against official Ubuntu schema
|
||||
3. **Predictable Behavior**: Explicit kernel parameters ensure consistent autoinstall
|
||||
4. **Clean Separation**: VM configuration, cloud-init, and kernel files are properly organized
|
||||
5. **Easy Maintenance**: Modular design allows independent updates of components
|
||||
|
||||
This implementation provides a robust, schema-compliant solution for automated ThrillWiki deployment on Unraid VMs.
|
||||
@@ -1,245 +0,0 @@
|
||||
# Template VM Setup Instructions
|
||||
|
||||
## Prerequisites for Template-Based Deployment
|
||||
|
||||
Before using the template-based deployment system, you need to:
|
||||
|
||||
1. **Create the template VM** named `thrillwiki-template-ubuntu` on your Unraid server
|
||||
2. **Configure SSH access** with your public key
|
||||
3. **Set up the template** with all required software
|
||||
|
||||
## Step 1: Create Template VM on Unraid
|
||||
|
||||
1. Create a new VM on your Unraid server:
|
||||
- **Name**: `thrillwiki-template-ubuntu`
|
||||
- **OS**: Ubuntu 24.04 LTS
|
||||
- **Memory**: 4GB (you can adjust this later for instances)
|
||||
- **vCPUs**: 2 (you can adjust this later for instances)
|
||||
- **Disk**: 50GB (sufficient for template)
|
||||
|
||||
2. Install Ubuntu 24.04 LTS using standard installation
|
||||
|
||||
## Step 2: Configure Template VM
|
||||
|
||||
SSH into your template VM and run the following setup:
|
||||
|
||||
### Create thrillwiki User
|
||||
```bash
|
||||
# Create the thrillwiki user with password 'thrillwiki'
|
||||
sudo useradd -m -s /bin/bash thrillwiki
|
||||
echo 'thrillwiki:thrillwiki' | sudo chpasswd
|
||||
sudo usermod -aG sudo thrillwiki
|
||||
|
||||
# Switch to thrillwiki user for remaining setup
|
||||
sudo su - thrillwiki
|
||||
```
|
||||
|
||||
### Set Up SSH Access
|
||||
**IMPORTANT**: Add your SSH public key to the template VM:
|
||||
|
||||
```bash
|
||||
# Create .ssh directory
|
||||
mkdir -p ~/.ssh
|
||||
chmod 700 ~/.ssh
|
||||
|
||||
# Add your public key (replace with your actual public key)
|
||||
echo "YOUR_PUBLIC_KEY_HERE" >> ~/.ssh/***REMOVED***
|
||||
chmod 600 ~/.ssh/***REMOVED***
|
||||
```
|
||||
|
||||
**To get your public key** (run this on your Mac):
|
||||
```bash
|
||||
# Generate key if it doesn't exist
|
||||
if [ ! -f ~/.ssh/thrillwiki_vm ]; then
|
||||
ssh-keygen -t rsa -b 4096 -f ~/.ssh/thrillwiki_vm -N "" -C "thrillwiki-template-vm-access"
|
||||
fi
|
||||
|
||||
# Show your public key to copy
|
||||
cat ~/.ssh/thrillwiki_vm.pub
|
||||
```
|
||||
|
||||
Copy this public key and paste it into the template VM's ***REMOVED*** file.
|
||||
|
||||
### Install Required Software
|
||||
```bash
|
||||
# Update system
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# Install essential packages
|
||||
sudo apt install -y \
|
||||
git curl wget build-essential \
|
||||
python3 python3-pip python3-venv python3-dev \
|
||||
postgresql postgresql-contrib postgresql-client \
|
||||
nginx \
|
||||
htop tree vim nano \
|
||||
software-properties-common
|
||||
|
||||
# Install UV (Python package manager)
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
source ~/.cargo/env
|
||||
|
||||
# Add UV to PATH permanently
|
||||
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.bashrc
|
||||
|
||||
# Configure PostgreSQL
|
||||
sudo systemctl enable postgresql
|
||||
sudo systemctl start postgresql
|
||||
|
||||
# Create database user and database
|
||||
sudo -u postgres createuser thrillwiki
|
||||
sudo -u postgres createdb thrillwiki
|
||||
sudo -u postgres psql -c "ALTER USER thrillwiki WITH PASSWORD 'thrillwiki';"
|
||||
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE thrillwiki TO thrillwiki;"
|
||||
|
||||
# Configure Nginx
|
||||
sudo systemctl enable nginx
|
||||
|
||||
# Create ThrillWiki directories
|
||||
mkdir -p ~/thrillwiki ~/logs ~/backups
|
||||
|
||||
# Set up basic environment
|
||||
echo "export DJANGO_SETTINGS_MODULE=thrillwiki.settings" >> ~/.bashrc
|
||||
echo "export DATABASE_URL=[DATABASE-URL-REMOVED] >> ~/.bashrc
|
||||
```
|
||||
|
||||
### Pre-install Common Python Packages (Optional)
|
||||
```bash
|
||||
# Create a base virtual environment with common packages
|
||||
cd ~
|
||||
python3 -m venv base_venv
|
||||
source base_venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
|
||||
# Install common Django packages
|
||||
pip install \
|
||||
django \
|
||||
psycopg2-binary \
|
||||
gunicorn \
|
||||
whitenoise \
|
||||
python-decouple \
|
||||
pillow \
|
||||
requests
|
||||
|
||||
deactivate
|
||||
```
|
||||
|
||||
### Clean Up Template
|
||||
```bash
|
||||
# Clean package cache
|
||||
sudo apt autoremove -y
|
||||
sudo apt autoclean
|
||||
|
||||
# Clear bash history
|
||||
history -c
|
||||
history -w
|
||||
|
||||
# Clear any temporary files
|
||||
sudo find /tmp -type f -delete
|
||||
sudo find /var/tmp -type f -delete
|
||||
|
||||
# Shutdown the template VM
|
||||
sudo shutdown now
|
||||
```
|
||||
|
||||
## Step 3: Verify Template Setup
|
||||
|
||||
After the template VM shuts down, verify it's ready:
|
||||
|
||||
```bash
|
||||
# From your Mac, check the template
|
||||
cd /path/to/your/thrillwiki/project
|
||||
./scripts/unraid/template-utils.sh check
|
||||
```
|
||||
|
||||
## Step 4: Test Template Deployment
|
||||
|
||||
Create a test VM from the template:
|
||||
|
||||
```bash
|
||||
# Deploy a test VM
|
||||
./scripts/unraid/template-utils.sh deploy test-thrillwiki-vm
|
||||
|
||||
# Check if it worked
|
||||
ssh thrillwiki@<VM_IP> "echo 'Template VM working!'"
|
||||
```
|
||||
|
||||
## Template VM Configuration Summary
|
||||
|
||||
Your template VM should now have:
|
||||
|
||||
- ✅ **Username**: `thrillwiki` (password: `thrillwiki`)
|
||||
- ✅ **SSH Access**: Your public key in `/home/thrillwiki/.ssh/***REMOVED***`
|
||||
- ✅ **Python**: Python 3 with UV package manager
|
||||
- ✅ **Database**: PostgreSQL with `thrillwiki` user and database
|
||||
- ✅ **Web Server**: Nginx installed and enabled
|
||||
- ✅ **Directories**: `~/thrillwiki`, `~/logs`, `~/backups` ready
|
||||
|
||||
## SSH Configuration on Your Mac
|
||||
|
||||
The automation scripts will set this up, but you can also configure manually:
|
||||
|
||||
```bash
|
||||
# Add to ~/.ssh/config
|
||||
cat >> ~/.ssh/config << EOF
|
||||
|
||||
# ThrillWiki Template VM
|
||||
Host thrillwiki-vm
|
||||
HostName %h
|
||||
User thrillwiki
|
||||
IdentityFile ~/.ssh/thrillwiki_vm
|
||||
StrictHostKeyChecking no
|
||||
UserKnownHostsFile /dev/null
|
||||
EOF
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Once your template is set up:
|
||||
|
||||
1. **Run the automation setup**:
|
||||
```bash
|
||||
./scripts/unraid/setup-template-automation.sh
|
||||
```
|
||||
|
||||
2. **Deploy VMs quickly**:
|
||||
```bash
|
||||
./scripts/unraid/template-utils.sh deploy my-vm-name
|
||||
```
|
||||
|
||||
3. **Enjoy 5-10x faster deployments** (2-5 minutes instead of 20-30 minutes!)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### SSH Access Issues
|
||||
```bash
|
||||
# Test SSH access to template (when it's running for updates)
|
||||
ssh -i ~/.ssh/thrillwiki_vm thrillwiki@TEMPLATE_VM_IP
|
||||
|
||||
# If access fails, check:
|
||||
# 1. Template VM is running
|
||||
# 2. Public key is in ***REMOVED***
|
||||
# 3. Permissions are correct (700 for .ssh, 600 for ***REMOVED***)
|
||||
```
|
||||
|
||||
### Template VM Updates
|
||||
```bash
|
||||
# Start template VM on Unraid
|
||||
# SSH in and update:
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
~/.cargo/bin/uv --version # Check UV is still working
|
||||
|
||||
# Clean up and shutdown
|
||||
sudo apt autoremove -y && sudo apt autoclean
|
||||
history -c && history -w
|
||||
sudo shutdown now
|
||||
```
|
||||
|
||||
### Permission Issues
|
||||
```bash
|
||||
# If you get permission errors, ensure thrillwiki user owns everything
|
||||
sudo chown -R thrillwiki:thrillwiki /home/thrillwiki/
|
||||
sudo chmod 700 /home/thrillwiki/.ssh
|
||||
sudo chmod 600 /home/thrillwiki/.ssh/***REMOVED***
|
||||
```
|
||||
|
||||
Your template is now ready for lightning-fast VM deployments! ⚡
|
||||
@@ -1,206 +0,0 @@
|
||||
#cloud-config
|
||||
autoinstall:
|
||||
# version is an Autoinstall required field.
|
||||
version: 1
|
||||
|
||||
# Install Ubuntu server packages and ThrillWiki dependencies
|
||||
packages:
|
||||
- ubuntu-server
|
||||
- curl
|
||||
- wget
|
||||
- git
|
||||
- python3
|
||||
- python3-pip
|
||||
- python3-venv
|
||||
- nginx
|
||||
- postgresql
|
||||
- postgresql-contrib
|
||||
- redis-server
|
||||
- nodejs
|
||||
- npm
|
||||
- build-essential
|
||||
- ufw
|
||||
- fail2ban
|
||||
- htop
|
||||
- tree
|
||||
- vim
|
||||
- tmux
|
||||
- qemu-guest-agent
|
||||
|
||||
# User creation
|
||||
identity:
|
||||
realname: 'ThrillWiki Admin'
|
||||
username: thrillwiki
|
||||
# Default [PASSWORD-REMOVED] (change after login)
|
||||
password: '$6$rounds=4096$saltsalt$[AWS-SECRET-REMOVED]AzpI8g8T14F8VnhXo0sUkZV2NV6/.c77tHgVi34DgbPu.'
|
||||
hostname: thrillwiki-vm
|
||||
|
||||
locale: en_US.UTF-8
|
||||
keyboard:
|
||||
layout: us
|
||||
|
||||
package_update: true
|
||||
package_upgrade: true
|
||||
|
||||
# Use direct storage layout (no LVM)
|
||||
storage:
|
||||
swap:
|
||||
size: 0
|
||||
layout:
|
||||
name: direct
|
||||
|
||||
# SSH configuration
|
||||
ssh:
|
||||
allow-pw: true
|
||||
install-server: true
|
||||
authorized-keys:
|
||||
- {SSH_PUBLIC_KEY}
|
||||
|
||||
# Network configuration - will be replaced with proper config
|
||||
network:
|
||||
version: 2
|
||||
ethernets:
|
||||
enp1s0:
|
||||
dhcp4: true
|
||||
dhcp-identifier: mac
|
||||
|
||||
# Commands to run after installation
|
||||
late-commands:
|
||||
# Update GRUB
|
||||
- curtin in-target -- update-grub
|
||||
|
||||
# Enable and start services
|
||||
- curtin in-target -- systemctl enable qemu-guest-agent
|
||||
- curtin in-target -- systemctl enable postgresql
|
||||
- curtin in-target -- systemctl enable redis-server
|
||||
- curtin in-target -- systemctl enable nginx
|
||||
|
||||
# Configure PostgreSQL
|
||||
- curtin in-target -- sudo -u postgres createuser -s thrillwiki
|
||||
- curtin in-target -- sudo -u postgres createdb thrillwiki_db
|
||||
- curtin in-target -- sudo -u postgres psql -c "ALTER USER thrillwiki PASSWORD 'thrillwiki123';"
|
||||
|
||||
# Configure firewall
|
||||
- curtin in-target -- ufw allow OpenSSH
|
||||
- curtin in-target -- ufw allow 'Nginx Full'
|
||||
- curtin in-target -- ufw --force enable
|
||||
|
||||
# Clone ThrillWiki repository if provided
|
||||
- curtin in-target -- bash -c 'if [ -n "{GITHUB_REPO}" ]; then cd /home/thrillwiki && git clone "{GITHUB_REPO}" thrillwiki-app && chown -R thrillwiki:thrillwiki thrillwiki-app; fi'
|
||||
|
||||
# Create deployment script
|
||||
- curtin in-target -- tee /home/thrillwiki/deploy-thrillwiki.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "=== ThrillWiki Deployment Script ==="
|
||||
|
||||
# Check if repo was cloned
|
||||
if [ ! -d "/home/thrillwiki/thrillwiki-app" ]; then
|
||||
echo "Repository not found. Please clone your ThrillWiki repository:"
|
||||
echo "git clone YOUR_REPO_URL thrillwiki-app"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd /home/thrillwiki/thrillwiki-app
|
||||
|
||||
# Create virtual environment
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# Install Python dependencies
|
||||
if [ -f "requirements.txt" ]; then
|
||||
pip install -r requirements.txt
|
||||
else
|
||||
echo "Warning: requirements.txt not found"
|
||||
fi
|
||||
|
||||
# Install Django if not in requirements
|
||||
pip install django psycopg2-binary redis celery gunicorn
|
||||
|
||||
# Set up environment variables
|
||||
cat > ***REMOVED*** << 'ENVEOF'
|
||||
DEBUG=False
|
||||
SECRET_KEY=your-secret-key-change-this
|
||||
DATABASE_URL=[DATABASE-URL-REMOVED]
|
||||
REDIS_URL=redis://localhost:6379/0
|
||||
ALLOWED_HOSTS=localhost,127.0.0.1,thrillwiki-vm
|
||||
ENVEOF
|
||||
|
||||
# Run Django setup commands
|
||||
if [ -f "manage.py" ]; then
|
||||
python manage.py collectstatic --noinput
|
||||
python manage.py migrate
|
||||
echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', 'admin@thrillwiki.com', 'thrillwiki123') if not User.objects.filter(username='admin').exists() else None" | python manage.py shell
|
||||
fi
|
||||
|
||||
# Configure Nginx
|
||||
sudo tee /etc/nginx/sites-available/thrillwiki << 'NGINXEOF'
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
location /static/ {
|
||||
alias /home/thrillwiki/thrillwiki-app/staticfiles/;
|
||||
}
|
||||
|
||||
location /media/ {
|
||||
alias /home/thrillwiki/thrillwiki-app/media/;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
NGINXEOF
|
||||
|
||||
# Enable Nginx site
|
||||
sudo ln -sf /etc/nginx/sites-available/thrillwiki /etc/nginx/sites-enabled/
|
||||
sudo rm -f /etc/nginx/sites-enabled/default
|
||||
sudo systemctl reload nginx
|
||||
|
||||
# Create systemd service for Django
|
||||
sudo tee /etc/systemd/system/thrillwiki.service << 'SERVICEEOF'
|
||||
[Unit]
|
||||
Description=ThrillWiki Django App
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=thrillwiki
|
||||
Group=thrillwiki
|
||||
[AWS-SECRET-REMOVED]wiki-app
|
||||
[AWS-SECRET-REMOVED]wiki-app/venv/bin
|
||||
ExecStart=/home/thrillwiki/thrillwiki-app/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:8000 thrillwiki.wsgi:application
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SERVICEEOF
|
||||
|
||||
# Enable and start ThrillWiki service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable thrillwiki
|
||||
sudo systemctl start thrillwiki
|
||||
|
||||
echo "=== ThrillWiki deployment complete! ==="
|
||||
echo "Access your application at: http://$(hostname -I | awk '{print $1}')"
|
||||
echo "Django Admin: http://$(hostname -I | awk '{print $1}')/admin"
|
||||
echo "Default superuser: admin / thrillwiki123"
|
||||
echo ""
|
||||
echo "Important: Change default passwords!"
|
||||
EOF
|
||||
|
||||
# Make deployment script executable
|
||||
- curtin in-target -- chmod +x /home/thrillwiki/deploy-thrillwiki.sh
|
||||
- curtin in-target -- chown thrillwiki:thrillwiki /home/thrillwiki/deploy-thrillwiki.sh
|
||||
|
||||
# Clean up
|
||||
- curtin in-target -- apt-get autoremove -y
|
||||
- curtin in-target -- apt-get autoclean
|
||||
|
||||
# Reboot after installation
|
||||
shutdown: reboot
|
||||
@@ -1,62 +0,0 @@
|
||||
#cloud-config
|
||||
# Ubuntu autoinstall configuration
|
||||
autoinstall:
|
||||
version: 1
|
||||
locale: en_US.UTF-8
|
||||
keyboard:
|
||||
layout: us
|
||||
network:
|
||||
version: 2
|
||||
ethernets:
|
||||
ens3:
|
||||
dhcp4: true
|
||||
enp1s0:
|
||||
dhcp4: true
|
||||
eth0:
|
||||
dhcp4: true
|
||||
ssh:
|
||||
install-server: true
|
||||
authorized-keys:
|
||||
- {SSH_PUBLIC_KEY}
|
||||
allow-pw: false
|
||||
storage:
|
||||
layout:
|
||||
name: lvm
|
||||
identity:
|
||||
hostname: thrillwiki-vm
|
||||
username: ubuntu
|
||||
password: "$6$rounds=4096$salt$hash" # disabled - ssh key only
|
||||
packages:
|
||||
- openssh-server
|
||||
- curl
|
||||
- git
|
||||
- python3
|
||||
- python3-pip
|
||||
- python3-venv
|
||||
- build-essential
|
||||
- postgresql
|
||||
- postgresql-contrib
|
||||
- nginx
|
||||
- nodejs
|
||||
- npm
|
||||
- wget
|
||||
- ca-certificates
|
||||
- openssl
|
||||
- dnsutils
|
||||
- net-tools
|
||||
early-commands:
|
||||
- systemctl stop ssh
|
||||
late-commands:
|
||||
# Enable sudo for ubuntu user
|
||||
- echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > /target/etc/sudoers.d/ubuntu
|
||||
# Install uv Python package manager
|
||||
- chroot /target su - ubuntu -c 'curl -LsSf https://astral.sh/uv/install.sh | sh || pip3 install uv'
|
||||
# Add uv to PATH
|
||||
- chroot /target su - ubuntu -c 'echo "export PATH=\$HOME/.cargo/bin:\$PATH" >> /home/ubuntu/.bashrc'
|
||||
# Clone ThrillWiki repository
|
||||
- chroot /target su - ubuntu -c 'cd /home/ubuntu && git clone {GITHUB_REPO} thrillwiki'
|
||||
# Setup systemd service for ThrillWiki
|
||||
- systemctl enable postgresql
|
||||
- systemctl enable nginx
|
||||
|
||||
shutdown: reboot
|
||||