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`
This commit is contained in:
pacnpal
2025-09-24 21:21:50 -04:00
parent 82cbdecc4c
commit 4373d18176
186 changed files with 0 additions and 43099 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 942 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 942 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 770 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 942 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 770 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 942 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

View File

@@ -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

View File

@@ -1 +0,0 @@
[GITHUB-TOKEN-REMOVED]

View File

@@ -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***

View File

@@ -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

View File

@@ -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 300399 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!")

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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 "$@"

View File

@@ -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***

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,10 +0,0 @@
{
"permissions": {
"additionalDirectories": [
"/Users/talor/thrillwiki_django_no_react"
],
"allow": [
"Bash(uv run:*)"
]
}
}

View File

@@ -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.

View File

@@ -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! 🚀

View File

@@ -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.

View File

@@ -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! ⚡

View File

@@ -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

View File

@@ -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

Some files were not shown because too many files have changed in this diff Show More