Skip to main content

Architecture Overview

OSX Proxmox Next follows a plan-then-execute architecture. User input flows through validation and planning before any Proxmox commands run. This makes dry-run previews possible and keeps side effects isolated to a single executor module.

Data Flow

VM Creation

VM Edit

Key Domain Types

Defined in domain.py:

@dataclass
class VmConfig:
vmid: int
name: str
macos: str # "ventura" | "sonoma" | "sequoia" | "tahoe"
cores: int
memory_mb: int
disk_gb: int
bridge: str # e.g. "vmbr0"
storage: str
smbios_serial: str # auto-generated if empty
smbios_uuid: str
smbios_mlb: str
smbios_rom: str
smbios_model: str
net_model: str # default "vmxnet3"
# ... additional fields

@dataclass
class EditChanges:
name: str | None = None # rename VM
cores: int | None = None # new core count
memory_mb: int | None = None # new RAM in MB
bridge: str | None = None # new network bridge
disk_gb_add: int | None = None # extend disk by N GB
disk_name: str = "virtio0" # disk device to resize
nic_model: str | None = None # None = preserve existing

@dataclass
class PlanStep:
title: str
argv: list[str]
risk: str # "safe" | "action"

@property
def command(self) -> str:
return shlex_join(self.argv)

Supported macOS Versions

KeyLabelMajor Version
venturamacOS Ventura 1313
sonomamacOS Sonoma 1414
sequoiamacOS Sequoia 1515
tahoemacOS Tahoe 2626

Validation Constants

ConstraintValue
Min VMID100
Max VMID999999
Min cores2
Min memory4096 MB
Min disk64 GB
Bridge formatvmbr<N>

Module Responsibilities

ModuleResponsibility
domain.pyCore types (VmConfig, EditChanges, PlanStep), validation rules, supported OS map
planner.pyConverts a VmConfig into an ordered list[PlanStep] (build_plan). Also builds edit plans (build_edit_plan) from EditChanges, preserving MAC/NIC when changing bridge
executor.pyRuns PlanStep[] against Proxmox via ProxmoxAdapter. Supports dry-run (log only) and live execution. Emits StepResult per step with return codes and output
downloader.pyDownloads OpenCore ISO from GitHub releases and macOS recovery images from Apple's osrecovery API. Handles retries, progress callbacks, and board-ID mapping per OS version
smbios.pyGenerates Apple-format serial numbers, MLB with mod-34 checksum, UUID, and ROM. Pure Python, no external binaries
smbios_planner.pyBuilds SMBIOS-related PlanStep objects for inclusion in VM creation plans
infrastructure.pyProxmoxAdapter abstraction for shell command execution on the Proxmox host
defaults.pyHardware detection: CPU vendor, core count, hybrid topology, RAM
rollback.pyConfig snapshot (saved to generated/snapshots/ before destructive ops) and rollback hints for manual recovery
diagnostics.pyDiagnostic log bundle export
app.pyTUI wizard entry point. Composes _WizardMixin, _EditMixin, and _ManageMixin
_wizard_mixin.pyTUI 6-step VM creation flow: Preflight, OS selection, Storage, Config, Dry Run, Install
_edit_mixin.pyTUI VM edit flow: verifies VM exists, creates snapshot, stops VM, applies EditChanges, optionally restarts
_manage_mixin.pyTUI manage mode: lists macOS VMs, provides per-VM edit/start/stop/destroy actions
script_renderer.pyGenerates shell scripts for OpenCore disk creation (GPT + ESP partitioning, config.plist patching)
preflight.pyAsset presence checks (required_assets): verifies OpenCore ISO and recovery image exist before apply
assets.pyAsset path resolution and download hint generation for missing OpenCore/recovery files
services/Detection service (storage targets, next VMID with overflow protection, VM listing), edit service (worker for applying EditChanges)
models/WizardState dataclass — reactive TUI state shared across all mixin steps (dry_log, live_log_lines, form field values)

CPU Strategy

The planner selects CPU arguments based on detected hardware:

CPU TypeQEMU -cpu Flag
Intel (non-hybrid)host passthrough
Intel hybrid (12th gen+)Cascadelake-Server
AMDCascadelake-Server
Intel Xeonhost passthrough (with e1000 NIC)
Intel pre-Skylake (Penryn)Penryn emulation (with e1000 NIC)
Manual overrideUser-specified model

AMD and hybrid Intel use Cascadelake-Server emulation because macOS hardware validation fails on non-standard topologies.

Executor Results

The executor produces typed results for each step:

@dataclass
class StepResult:
title: str
command: str
ok: bool
returncode: int
output: str

@dataclass
class ApplyResult:
ok: bool
results: list[StepResult]
log_path: Path

All runs (dry-run and live) are logged to generated/logs/apply-<timestamp>.log.