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
This commit is contained in:
parent
242e48a5fc
commit
58a317f5d2
9 changed files with 415 additions and 128 deletions
|
|
@ -3,6 +3,12 @@ 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 = macos.fetchRecovery { inherit (up.recovery) shortname sha256; };
|
||||
# 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; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue