Apple's built-in QEMU guest agent (AppleQEMUGuestAgent, launched by launchd when a virtio console port org.qemu.guest_agent.0 appears; guest-exec as root) is attached by vmix run --macos and the NixOS module. AppleVirtIO.kext on x86 Tahoe drives virtio-fs, block, console, input, net — verified in QEMU. - customizeImage: `bootScript` — online step through the guest agent (driver mode qga): boot the image, run the script as root with the VMIX volume, shut down through the agent. `as_user` runs commands in the logged-in session. - templates.software: pkg/app (offline in the PE), script/homebrew (online). - templates.profile.settings: widgets, wallpaper (pinned desktoppr — Apple Events need TCC consent that a headless session cannot give), dock apps, autohide, dark mode, hidden files. - generalize: persistHome (fstab LABEL=vmix-home /Users), hideWidgets offline. - formatVolume: formats a blank disk image as APFS by booting the PE (~35 s); idempotent. - NixOS module: macos.guestAgent (/run/vmix/qga-<name>.sock), shares via virtiofsd + vhost-user-fs (Apple automount tag for the first share, others mounted through the agent), macos.homeDisk (created + formatted on first start, virtio-blk), SPICE keeps -vga vmware for macOS. - CLI: vmix run --macos --share DIR --home FILE --qga PATH. - qemu.nix helpers; README section. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsESshRCoBoUVWV9qKURUF
46 lines
2.2 KiB
Nix
46 lines
2.2 KiB
Nix
{ 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; };
|
|
makeBootDisk = import ./helpers/makeBootDisk.nix { inherit pkgs lib; };
|
|
makeRecoveryPE = import ./helpers/makeRecoveryPE.nix { inherit pkgs lib; };
|
|
makeVmixVolume = import ./helpers/makeVmixVolume.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 makeBootDisk makeVmixVolume installBootloader vmixReadback vmDriver;
|
|
};
|
|
customizeImage = import ./helpers/customizeImage.nix {
|
|
inherit pkgs lib qemu ident makeVmixVolume makeOpenCore makeBootDisk installBootloader vmixReadback vmDriver;
|
|
};
|
|
customizeImageFold = builtins.foldl' customizeImage;
|
|
formatVolume = import ./helpers/formatVolume.nix { inherit pkgs lib qemu makeVmixVolume makeBootDisk vmDriver; };
|
|
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; };
|
|
}
|