vmix.nix/lib/images/macos/tahoe/default.nix
Git Sagar 58a317f5d2 macOS Tahoe: working fully-offline unattended install
The base image (macos.images.tahoe.upstream) now installs and boots end to end
with no dependency on Apple's servers — proven on the KVM host: the finished
qcow2 boots standalone (OpenCore from its own ESP) to the macOS 26.6.2 loginwindow.

Install driving (vm-driver.py, screenshot + OCR over QMP):
- map the whole InstallAssistant.pkg as a raw disk and dd it byte-exact into the
  app as SharedSupport.dmg (it is a pkgdmg: xar + koly footer — the bare xar
  member fails startosinstall with "pkgdmg is missing a footer")
- offline install: no NIC + /etc/hosts blackhole of Apple install/verify
  endpoints so startosinstall's calls fail fast instead of hanging
  (SecureBootModel=Disabled allows the sealed-volume install offline)
- keep the recovery display awake with a tiny mouse jiggle; coarse settle
  fingerprint so the cursor is not seen as a change
- guest watchdog re-erases/retries a startosinstall attempt that stalls or runs
  too long (prepare is intermittently slow)
- disk-aware boot watchdog: QMP system_reset only when the screen is dark AND the
  disk is idle (never interrupts a slow-but-working boot); recovery-restart if a
  post-prepare reboot lands back on recovery
- detect the bright loginwindow and power the VM down (install complete); a
  black + disk-idle screen is treated as a completed halt
- copy OpenCore into the image ESP so it boots standalone

recovery.file pins a content-addressed local BaseSystem.dmg (Apple's CDN
load-balances Sequoia/Tahoe during the rollout). fetchRecovery retries to the
pinned hash when used instead.

Not yet done: .generalize (user creation) — the first-boot agent LaunchDaemon is
blocked by Ventura+ Background Task Management on headless boots; next step is
offline user injection from the agent pkg postinstall.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsESshRCoBoUVWV9qKURUF
2026-09-10 13:33:38 -03:00

14 lines
782 B
Nix

{ pkgs, lib, system, macos, ... }:
let
up = macos.upstream.tahoe;
# 18 GB full installer (App Store InstallAssistant.pkg, pinned)
installer = pkgs.fetchurl { inherit (up.installer) url hash; name = "InstallAssistant.pkg"; };
# Recovery BaseSystem.dmg: a pre-verified local store file when `recovery.file` is set
# (Apple's CDN rotates Sequoia/Tahoe during the rollout), else fetched + pinned.
# `nix store add-path --name macos-tahoe-BaseSystem.dmg BaseSystem.dmg` yields the same
# content-addressed path on any host that has the file.
recovery = if up.recovery ? file
then builtins.storePath up.recovery.file
else macos.fetchRecovery { inherit (up.recovery) shortname sha256; };
in
import ./images.nix { inherit pkgs lib system macos installer recovery; }