mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-21 09:11:08 -05:00
Refactor test utilities and enhance ASGI settings
- Cleaned up and standardized assertions in ApiTestMixin for API response validation. - Updated ASGI settings to use os.environ for setting the DJANGO_SETTINGS_MODULE. - Removed unused imports and improved formatting in settings.py. - Refactored URL patterns in urls.py for better readability and organization. - Enhanced view functions in views.py for consistency and clarity. - Added .flake8 configuration for linting and style enforcement. - Introduced type stubs for django-environ to improve type checking with Pylance.
This commit is contained in:
@@ -3,79 +3,79 @@
|
||||
Unraid VM Manager for ThrillWiki - Main Orchestrator
|
||||
Follows the Ubuntu autoinstall guide exactly:
|
||||
1. Creates modified Ubuntu ISO with autoinstall configuration
|
||||
2. Manages VM lifecycle on Unraid server
|
||||
2. Manages VM lifecycle on Unraid server
|
||||
3. Handles ThrillWiki deployment automation
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import logging
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
# Import our modular components
|
||||
from iso_builder import UbuntuISOBuilder
|
||||
from vm_manager import UnraidVMManager
|
||||
|
||||
# Configuration
|
||||
UNRAID_HOST = os***REMOVED***iron.get("UNRAID_HOST", "localhost")
|
||||
UNRAID_USER = os***REMOVED***iron.get("UNRAID_USER", "root")
|
||||
VM_NAME = os***REMOVED***iron.get("VM_NAME", "thrillwiki-vm")
|
||||
VM_MEMORY = int(os***REMOVED***iron.get("VM_MEMORY", 4096)) # MB
|
||||
VM_VCPUS = int(os***REMOVED***iron.get("VM_VCPUS", 2))
|
||||
VM_DISK_SIZE = int(os***REMOVED***iron.get("VM_DISK_SIZE", 50)) # GB
|
||||
SSH_PUBLIC_KEY = os***REMOVED***iron.get("SSH_PUBLIC_KEY", "")
|
||||
UNRAID_HOST = os.environ.get("UNRAID_HOST", "localhost")
|
||||
UNRAID_USER = os.environ.get("UNRAID_USER", "root")
|
||||
VM_NAME = os.environ.get("VM_NAME", "thrillwiki-vm")
|
||||
VM_MEMORY = int(os.environ.get("VM_MEMORY", 4096)) # MB
|
||||
VM_VCPUS = int(os.environ.get("VM_VCPUS", 2))
|
||||
VM_DISK_SIZE = int(os.environ.get("VM_DISK_SIZE", 50)) # GB
|
||||
SSH_PUBLIC_KEY = os.environ.get("SSH_PUBLIC_KEY", "")
|
||||
|
||||
# Network Configuration
|
||||
VM_IP = os***REMOVED***iron.get("VM_IP", "dhcp")
|
||||
VM_GATEWAY = os***REMOVED***iron.get("VM_GATEWAY", "192.168.20.1")
|
||||
VM_NETMASK = os***REMOVED***iron.get("VM_NETMASK", "255.255.255.0")
|
||||
VM_NETWORK = os***REMOVED***iron.get("VM_NETWORK", "192.168.20.0/24")
|
||||
VM_IP = os.environ.get("VM_IP", "dhcp")
|
||||
VM_GATEWAY = os.environ.get("VM_GATEWAY", "192.168.20.1")
|
||||
VM_NETMASK = os.environ.get("VM_NETMASK", "255.255.255.0")
|
||||
VM_NETWORK = os.environ.get("VM_NETWORK", "192.168.20.0/24")
|
||||
|
||||
# GitHub Configuration
|
||||
REPO_URL = os***REMOVED***iron.get("REPO_URL", "")
|
||||
GITHUB_USERNAME = os***REMOVED***iron.get("GITHUB_USERNAME", "")
|
||||
GITHUB_TOKEN = os***REMOVED***iron.get("GITHUB_TOKEN", "")
|
||||
REPO_URL = os.environ.get("REPO_URL", "")
|
||||
GITHUB_USERNAME = os.environ.get("GITHUB_USERNAME", "")
|
||||
GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN", "")
|
||||
|
||||
# Ubuntu version preference
|
||||
UBUNTU_VERSION = os***REMOVED***iron.get("UBUNTU_VERSION", "24.04")
|
||||
UBUNTU_VERSION = os.environ.get("UBUNTU_VERSION", "24.04")
|
||||
|
||||
# Setup logging
|
||||
os.makedirs("logs", exist_ok=True)
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s - %(levelname)s - %(message)s",
|
||||
handlers=[logging.FileHandler("logs/unraid-vm.log"), logging.StreamHandler()],
|
||||
handlers=[
|
||||
logging.FileHandler("logs/unraid-vm.log"),
|
||||
logging.StreamHandler(),
|
||||
],
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ThrillWikiVMOrchestrator:
|
||||
"""Main orchestrator for ThrillWiki VM deployment."""
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.vm_manager = UnraidVMManager(VM_NAME, UNRAID_HOST, UNRAID_USER)
|
||||
self.iso_builder = None
|
||||
|
||||
|
||||
def create_autoinstall_user_data(self) -> str:
|
||||
"""Create autoinstall user-data configuration."""
|
||||
# Read autoinstall template
|
||||
template_path = Path(__file__).parent / "autoinstall-user-data.yaml"
|
||||
if not template_path.exists():
|
||||
raise FileNotFoundError(f"Autoinstall template not found: {template_path}")
|
||||
|
||||
with open(template_path, 'r', encoding='utf-8') as f:
|
||||
|
||||
with open(template_path, "r", encoding="utf-8") as f:
|
||||
template = f.read()
|
||||
|
||||
# Replace placeholders using string replacement (avoiding .format() due to curly braces in YAML)
|
||||
|
||||
# Replace placeholders using string replacement (avoiding .format() due
|
||||
# to curly braces in YAML)
|
||||
user_data = template.replace(
|
||||
"{SSH_PUBLIC_KEY}", SSH_PUBLIC_KEY if SSH_PUBLIC_KEY else "# No SSH key provided"
|
||||
).replace(
|
||||
"{GITHUB_REPO}", REPO_URL if REPO_URL else ""
|
||||
)
|
||||
|
||||
"{SSH_PUBLIC_KEY}",
|
||||
SSH_PUBLIC_KEY if SSH_PUBLIC_KEY else "# No SSH key provided",
|
||||
).replace("{GITHUB_REPO}", REPO_URL if REPO_URL else "")
|
||||
|
||||
# Update network configuration based on VM_IP setting
|
||||
if VM_IP.lower() == "dhcp":
|
||||
# Keep DHCP configuration as-is
|
||||
@@ -91,74 +91,74 @@ class ThrillWikiVMOrchestrator:
|
||||
- 8.8.8.8
|
||||
- 8.8.4.4"""
|
||||
user_data = user_data.replace("dhcp4: true", network_config)
|
||||
|
||||
|
||||
return user_data
|
||||
|
||||
|
||||
def build_autoinstall_iso(self) -> Path:
|
||||
"""Build Ubuntu autoinstall ISO following the guide."""
|
||||
logger.info("🔨 Building Ubuntu autoinstall ISO...")
|
||||
|
||||
|
||||
# Create ISO builder
|
||||
self.iso_builder = UbuntuISOBuilder(VM_NAME)
|
||||
|
||||
|
||||
# Create user-data configuration
|
||||
user_data = self.create_autoinstall_user_data()
|
||||
|
||||
|
||||
# Build autoinstall ISO
|
||||
iso_output_path = Path(f"/tmp/{VM_NAME}-ubuntu-autoinstall.iso")
|
||||
|
||||
|
||||
success = self.iso_builder.build_autoinstall_iso(
|
||||
user_data=user_data,
|
||||
output_path=iso_output_path,
|
||||
ubuntu_version=UBUNTU_VERSION
|
||||
ubuntu_version=UBUNTU_VERSION,
|
||||
)
|
||||
|
||||
|
||||
if not success:
|
||||
raise RuntimeError("Failed to build autoinstall ISO")
|
||||
|
||||
|
||||
logger.info(f"✅ Autoinstall ISO built successfully: {iso_output_path}")
|
||||
return iso_output_path
|
||||
|
||||
|
||||
def deploy_vm(self) -> bool:
|
||||
"""Complete VM deployment process."""
|
||||
try:
|
||||
logger.info("🚀 Starting ThrillWiki VM deployment...")
|
||||
|
||||
|
||||
# Step 1: Check SSH connectivity
|
||||
logger.info("📡 Testing Unraid connectivity...")
|
||||
if not self.vm_manager.authenticate():
|
||||
logger.error("❌ Cannot connect to Unraid server")
|
||||
return False
|
||||
|
||||
|
||||
# Step 2: Build autoinstall ISO
|
||||
logger.info("🔨 Building Ubuntu autoinstall ISO...")
|
||||
iso_path = self.build_autoinstall_iso()
|
||||
|
||||
|
||||
# Step 3: Upload ISO to Unraid
|
||||
logger.info("📤 Uploading autoinstall ISO to Unraid...")
|
||||
remote_iso_path = self.vm_manager.upload_iso_to_unraid(iso_path)
|
||||
|
||||
self.vm_manager.upload_iso_to_unraid(iso_path)
|
||||
|
||||
# Step 4: Create/update VM configuration
|
||||
logger.info("⚙️ Creating VM configuration...")
|
||||
success = self.vm_manager.create_vm(
|
||||
vm_memory=VM_MEMORY,
|
||||
vm_vcpus=VM_VCPUS,
|
||||
vm_vcpus=VM_VCPUS,
|
||||
vm_disk_size=VM_DISK_SIZE,
|
||||
vm_ip=VM_IP
|
||||
vm_ip=VM_IP,
|
||||
)
|
||||
|
||||
|
||||
if not success:
|
||||
logger.error("❌ Failed to create VM configuration")
|
||||
return False
|
||||
|
||||
|
||||
# Step 5: Start VM
|
||||
logger.info("🟢 Starting VM...")
|
||||
success = self.vm_manager.start_vm()
|
||||
|
||||
|
||||
if not success:
|
||||
logger.error("❌ Failed to start VM")
|
||||
return False
|
||||
|
||||
|
||||
logger.info("🎉 VM deployment completed successfully!")
|
||||
logger.info("")
|
||||
logger.info("📋 Next Steps:")
|
||||
@@ -167,9 +167,9 @@ class ThrillWikiVMOrchestrator:
|
||||
logger.info("3. Use 'python main.py ip' to get VM IP when ready")
|
||||
logger.info("4. SSH to VM and run /home/thrillwiki/deploy-thrillwiki.sh")
|
||||
logger.info("")
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ VM deployment failed: {e}")
|
||||
return False
|
||||
@@ -177,7 +177,7 @@ class ThrillWikiVMOrchestrator:
|
||||
# Cleanup ISO builder temp files
|
||||
if self.iso_builder:
|
||||
self.iso_builder.cleanup()
|
||||
|
||||
|
||||
def get_vm_info(self) -> dict:
|
||||
"""Get VM information."""
|
||||
return {
|
||||
@@ -186,7 +186,7 @@ class ThrillWikiVMOrchestrator:
|
||||
"ip": self.vm_manager.get_vm_ip(),
|
||||
"memory": VM_MEMORY,
|
||||
"vcpus": VM_VCPUS,
|
||||
"disk_size": VM_DISK_SIZE
|
||||
"disk_size": VM_DISK_SIZE,
|
||||
}
|
||||
|
||||
|
||||
@@ -204,17 +204,26 @@ Examples:
|
||||
python main.py status # Get VM status
|
||||
python main.py delete # Remove VM completely
|
||||
""",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
)
|
||||
|
||||
|
||||
parser.add_argument(
|
||||
"action",
|
||||
choices=["setup", "create", "start", "stop", "status", "ip", "delete", "info"],
|
||||
help="Action to perform"
|
||||
choices=[
|
||||
"setup",
|
||||
"create",
|
||||
"start",
|
||||
"stop",
|
||||
"status",
|
||||
"ip",
|
||||
"delete",
|
||||
"info",
|
||||
],
|
||||
help="Action to perform",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
# Create orchestrator
|
||||
orchestrator = ThrillWikiVMOrchestrator()
|
||||
|
||||
@@ -225,7 +234,9 @@ Examples:
|
||||
|
||||
elif args.action == "create":
|
||||
logger.info("⚙️ Creating VM configuration...")
|
||||
success = orchestrator.vm_manager.create_vm(VM_MEMORY, VM_VCPUS, VM_DISK_SIZE, VM_IP)
|
||||
success = orchestrator.vm_manager.create_vm(
|
||||
VM_MEMORY, VM_VCPUS, VM_DISK_SIZE, VM_IP
|
||||
)
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
elif args.action == "start":
|
||||
@@ -248,7 +259,9 @@ Examples:
|
||||
if ip:
|
||||
print(f"VM IP: {ip}")
|
||||
print(f"SSH: ssh thrillwiki@{ip}")
|
||||
print(f"Deploy: ssh thrillwiki@{ip} '/home/thrillwiki/deploy-thrillwiki.sh'")
|
||||
print(
|
||||
f"Deploy: ssh thrillwiki@{ip} '/home/thrillwiki/deploy-thrillwiki.sh'"
|
||||
)
|
||||
sys.exit(0)
|
||||
else:
|
||||
print("❌ Failed to get VM IP (VM may not be ready yet)")
|
||||
|
||||
Reference in New Issue
Block a user