#!/usr/bin/env python3 """ Unraid VM Manager for ThrillWiki This script automates VM creation, configuration, and management on Unraid. """ import os import sys import json import time import logging import requests import subprocess from pathlib import Path from typing import Dict, Optional, List # Configuration UNRAID_HOST = os***REMOVED***iron.get('UNRAID_HOST', 'localhost') UNRAID_USER = os***REMOVED***iron.get('UNRAID_USER', 'root') UNRAID_PASSWORD = os***REMOVED***iron.get('UNRAID_PASSWORD', '') VM_NAME = os***REMOVED***iron.get('VM_NAME', 'thrillwiki-vm') VM_TEMPLATE = os***REMOVED***iron.get('VM_TEMPLATE', 'Ubuntu Server 22.04') 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', '') # Network Configuration VM_IP = os***REMOVED***iron.get('VM_IP', '192.168.20.20') 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') # 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', '') GITHUB_API_ENABLED = os***REMOVED***iron.get( 'GITHUB_API_ENABLED', 'false').lower() == 'true' # 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() ] ) logger = logging.getLogger(__name__) class UnraidVMManager: """Manages VMs on Unraid server.""" def __init__(self): self.session = requests.Session() self.base_url = f"http://{UNRAID_HOST}" self.vm_config_path = f"/mnt/user/domains/{VM_NAME}" def authenticate(self) -> bool: """Authenticate with Unraid server.""" try: login_url = f"{self.base_url}/login" login_data = { 'username': UNRAID_USER, 'password': UNRAID_PASSWORD } response = self.session.post(login_url, data=login_data) if response.status_code == 200: logger.info("Successfully authenticated with Unraid") return True else: logger.error(f"Authentication failed: {response.status_code}") return False except Exception as e: logger.error(f"Authentication error: {e}") return False def check_vm_exists(self) -> bool: """Check if VM already exists.""" try: result = subprocess.run( f"ssh {UNRAID_USER}@{UNRAID_HOST} 'virsh list --all | grep {VM_NAME}'", shell=True, capture_output=True, text=True ) return VM_NAME in result.stdout except Exception as e: logger.error(f"Error checking VM existence: {e}") return False def create_vm_xml(self, existing_uuid: str = None) -> str: """Generate VM XML configuration.""" import uuid vm_uuid = existing_uuid if existing_uuid else str(uuid.uuid4()) xml_template = f""" {VM_NAME} {vm_uuid} {VM_MEMORY * 1024} {VM_MEMORY * 1024} {VM_VCPUS} hvm /usr/share/qemu/ovmf-x64/OVMF_CODE-pure-efi.fd /etc/libvirt/qemu/nvram/{vm_uuid}_VARS-pure-efi.fd destroy restart restart /usr/local/sbin/qemu