macOS Tahoe VM images (OpenCore/QEMU), Apple-ID compatible, VNC
Add a macOS image pipeline mirroring the Windows one: unattended install,
generalization and user creation, driven end to end in QEMU on a KVM host.
lib/images/macos:
- makeOpenCore: OSX-KVM OpenCore ESP with a config.plist rewritten per image —
SMBIOS model + serial/MLB (macserial) + UUID + ROM=en0 MAC (built-in NIC pinned
to PciRoot(0x0)/Pci(0x12,0x0)) for Apple ID / iMessage / App Store; boot disk;
OpenCore self-entry hidden. ident.nix derives MAC+UUID from a seed so the NixOS
module and CLI know the NIC MAC at eval time.
- makeImage: one QEMU session driven by vm-driver.py (QMP + screenshot settle
detection + OCR of the menu bar) — boots the recovery via OpenCore, opens
Terminal (Ctrl-F2 -> Utilities -> Terminal), types the bootstrap command;
vmix-install.sh erases the disk as APFS, lays down the host-extracted installer
app skeleton + a byte-exact SharedSupport.dmg (raw disk mapped to that byte range
of the pkg, dd'd in — Recovery's xar truncates an 18 GB member), runs
startosinstall with the vmix agent pkg. OpenCore is then copied into the image's
ESP so it boots standalone with OVMF.
- customizeImage / templates: boot the image with a FAT-then-HFS+ VMIX volume; the
vmix agent (LaunchDaemon) runs a script as root, records status and powers off —
the macOS counterpart of Windows Audit Mode. generalize creates the admin user +
auto-login (kcpassword), suppresses Setup Assistant, sets hostname/timezone,
grows APFS, and assigns a fresh SMBIOS identity. Templates: noUpdates,
performance, remoteAccess (ssh + screen sharing).
- fetchRecovery: Apple recovery BaseSystem, retried until the pinned Tahoe build
(osrecovery load-balances Sequoia/Tahoe during the rollout). makeAgentPkg builds
a distribution flat pkg on Linux (xar+bom+cpio) for startosinstall --installpackage.
CLI: vmix build/copy/run for macOS (run --macos --vnc, reads the image's MAC from
its ESP), and a `vmix macserial` helper. NixOS module: disks.os.file carrying
_vmixOsType="macos" auto-enables the macOS QEMU profile (AppleSMC+OSK, Skylake
CPU spoof, AHCI system disk, VMware SVGA, pinned NIC); macos.{enable,cpu,mac}.
Status: proven through the installer prepare phase (SharedSupport.dmg mounts,
version 26.6.2 read, SU catalog loads). Two blockers remain, documented in
lib/images/macos/README.md: (1) startosinstall's OSISVerifyBaseSystemOperation
rejects the byte-identical plain-UDIF SharedSupport as "pkgdmg missing a footer"
in this Tahoe recovery/VM; (2) Apple's CDN unreliably serves the Tahoe recovery
during rollout (self-hosting the verified BaseSystem is the robust fix).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsESshRCoBoUVWV9qKURUF
This commit is contained in:
parent
6a62a649bd
commit
242e48a5fc
35 changed files with 1842 additions and 36 deletions
44
lib/images/macos/default.nix
Normal file
44
lib/images/macos/default.nix
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
{ pkgs, lib, system, ... }:
|
||||
let
|
||||
upstream = (lib.importJSON ./upstream.json).${system};
|
||||
macos = rec {
|
||||
inherit upstream;
|
||||
qemu = import ./helpers/qemu.nix { inherit pkgs lib; };
|
||||
ident = import ./helpers/ident.nix { inherit lib; };
|
||||
macserial = import ./helpers/macserial.nix { inherit pkgs upstream; };
|
||||
fetchRecovery = import ./helpers/fetchRecovery.nix { inherit pkgs upstream; };
|
||||
installerPayload = import ./helpers/installerPayload.nix { inherit pkgs lib; };
|
||||
makeOpenCore = import ./helpers/makeOpenCore.nix { inherit pkgs lib upstream macserial qemu; };
|
||||
makeVmixVolume = import ./helpers/makeVmixVolume.nix { inherit pkgs lib; };
|
||||
makeAgentPkg = import ./helpers/makeAgentPkg.nix { inherit pkgs lib; };
|
||||
installBootloader = import ./helpers/installBootloader.nix { inherit pkgs lib; };
|
||||
vmixReadback = import ./helpers/vmix-readback.nix { inherit pkgs lib; };
|
||||
vmDriver = ./helpers/vm-driver.py;
|
||||
makeImage = import ./helpers/makeImage.nix {
|
||||
inherit pkgs lib qemu ident installerPayload makeOpenCore makeVmixVolume makeAgentPkg installBootloader vmixReadback vmDriver;
|
||||
};
|
||||
customizeImage = import ./helpers/customizeImage.nix {
|
||||
inherit pkgs lib qemu ident makeVmixVolume makeOpenCore installBootloader vmixReadback vmDriver;
|
||||
};
|
||||
customizeImageFold = builtins.foldl' customizeImage;
|
||||
templates = import ./templates { inherit pkgs lib; };
|
||||
};
|
||||
|
||||
tahoe = import ./tahoe { inherit pkgs lib system macos; };
|
||||
|
||||
# Recursively add .generalize to every image leaf (same shape as windows)
|
||||
addGeneralize = val:
|
||||
if val ? _vmixOsType then
|
||||
val // { generalize = args:
|
||||
let
|
||||
templateArgs = builtins.removeAttrs args [ "vncDisplay" ];
|
||||
displayArgs = lib.optionalAttrs (args ? vncDisplay) { inherit (args) vncDisplay; };
|
||||
in macos.customizeImage val (macos.templates.generalize templateArgs // displayArgs);
|
||||
}
|
||||
else if builtins.isAttrs val then
|
||||
lib.mapAttrs (_: addGeneralize) val
|
||||
else val;
|
||||
in
|
||||
macos // {
|
||||
images = addGeneralize { inherit tahoe; };
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue