macOS: guest agent, online templates, virtio-fs shares, persistent home volume

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
This commit is contained in:
Git Sagar 2026-09-09 21:47:41 -03:00
parent 50ad8d521c
commit 0f9373263d
13 changed files with 600 additions and 19 deletions

View file

@ -0,0 +1,58 @@
# User profile templates, applied on the booted image inside the logged-in
# user's session through the guest agent (after generalize with autoLogon).
# settings — { hideWidgets, wallpaper, dockApps, dockAutohide, showHiddenFiles }
{ pkgs, lib, ... }:
let
# Apple Events (osascript → System Events) need per-app automation consent that a
# headless session cannot grant; desktoppr sets the wallpaper through NSWorkspace
# inside the user's session instead (scriptingosx/desktoppr, pinned).
desktoppr = pkgs.fetchurl {
url = "https://github.com/scriptingosx/desktoppr/releases/download/v0.5/desktoppr-0.5-218.pkg";
hash = "sha256-HPtn1wI7xrx7HjyMz1yJGhutIodt938/vHfSeHfMe50=";
};
in
rec {
settings = {
hideWidgets ? true, # no desktop widgets (Sonoma+)
wallpaper ? null, # image file (drv/path) set as the desktop picture
dockApps ? null, # list of app paths, e.g. [ "/System/Applications/Utilities/Terminal.app" ]; null = untouched
dockAutohide ? false,
showHiddenFiles ? false,
darkMode ? null, # true/false/null
}: {
name = "profile";
files = lib.optionals (wallpaper != null) [
{ source = wallpaper; name = "wallpaper.${lib.last (lib.splitString "." (baseNameOf (toString wallpaper)))}"; }
{ source = desktoppr; name = "desktoppr.pkg"; }
];
bootScript = ''
[ -n "$CONSOLE_USER" ] || { echo "vmix: profile needs a logged-in user (generalize with autoLogon)"; exit 1; }
H=$(dscl . -read "/Users/$CONSOLE_USER" NFSHomeDirectory | awk '{print $2}')
D() { as_user defaults write "$@"; }
${lib.optionalString hideWidgets ''
D com.apple.WindowManager StandardHideWidgets -int 1
D com.apple.WindowManager StageManagerHideWidgets -int 1
D com.apple.widgets widgetAppearance -int 0
''}
${lib.optionalString (wallpaper != null) ''
W="/Library/Desktop Pictures/vmix-wallpaper.${lib.last (lib.splitString "." (baseNameOf (toString wallpaper)))}"
mkdir -p "/Library/Desktop Pictures"; cp "$V/wallpaper".* "$W"; chmod 644 "$W"
installer -pkg "$V/desktoppr.pkg" -target / >/dev/null || echo "vmix: WARNING: desktoppr install failed"
as_user /usr/local/bin/desktoppr "$W" || echo "vmix: WARNING: could not set the wallpaper"
''}
${lib.optionalString (dockApps != null) ''
D com.apple.dock persistent-apps -array
${lib.concatMapStringsSep "\n" (a: ''
D com.apple.dock persistent-apps -array-add "<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>${a}</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>"
'') dockApps}
''}
${lib.optionalString dockAutohide ''D com.apple.dock autohide -bool true''}
${lib.optionalString showHiddenFiles ''D com.apple.finder AppleShowAllFiles -bool true''}
${lib.optionalString (darkMode != null) (if darkMode
then ''D -g AppleInterfaceStyle Dark''
else ''as_user defaults delete -g AppleInterfaceStyle 2>/dev/null || true'')}
as_user killall Dock Finder WindowManager 2>/dev/null || true
sleep 3
'';
};
}