Merge nucleic/mellow-dewy-falcon-rjhr into main

This commit is contained in:
2026-08-07 02:30:26 -07:00
parent d64b3f3e9b
commit e7163de22f
9 changed files with 403 additions and 47 deletions
+68
View File
@@ -33,6 +33,8 @@ gitea-macos-runner service status
| `doctor` says `runner download url → 403` but the URL works in a browser | Old build: the check used `HEAD`, and the presigned redirect target is signed per method | Upgrade — the check now uses a ranged `GET`. If it persists, the asset really is missing |
| Disk filling up | Copy-on-write clones grow as jobs write | Raise `storage.minFreeDiskGB`; delete stale clones in `storeDir/vms` |
| `image build` appears to hang during install | Normal — macOS install is slow | Wait. **Do not stop the VM mid-install**; if you did, delete the image and rebuild |
| `image build` prints its banner and then nothing, at 0% CPU | Old build: the build task was queued behind the `NSApplication` run loop and never started | Upgrade — the task is now detached. Stage lines should appear within seconds |
| `image build` stuck at `loading restore image metadata…` | A truncated or partial `.ipsw` — the framework blocks rather than failing | Upgrade (the file is now size- and magic-checked first); re-download the IPSW |
---
@@ -363,6 +365,72 @@ concurrent clones diverging.
---
## `image build` prints the banner and then nothing at all
**Symptom.** `image build` prints
```
building image 'default' (this takes a while; the IPSW alone is ~15 GB)
```
and then stops — no stage lines, no progress bar, no error. Activity Monitor shows the process
using no CPU and no VM services running. Ctrl-C does nothing.
**Cause.** A bug in releases before this fix. `image build` hosts an `NSApplication` run loop
(Virtualization.framework requires one), and the work was started with a `Task` that inherited the
main actor. Because `NSApplication.run()` is itself reached from Swift's async `main`, the main
dispatch queue already had a block in flight and would not re-enter — so the build task was queued
behind a run loop that never yields and never got a first tick. Nothing ran, including the code
that would have reported the error. `SIGINT`/`SIGTERM` handling was stuck the same way, which is
why Ctrl-C did not work either.
**Fix.** Upgrade. The build task is now detached and signals are handled off the main queue. You
should see stage lines within a second or two:
```
resolving restore image…
loading restore image metadata…
creating VM bundle (disk 64 GB)…
installing macOS [########----------------------] 27%
```
If a build still goes quiet, the line last printed tells you which stage owns the silence — see
below.
---
## `image build` sits at "loading restore image metadata…"
**Symptom.** The build reaches `loading restore image metadata…` and stays there. After a minute it
adds:
```
still loading — a truncated or partially downloaded .ipsw can block here; verify the download completed
```
**Cause.** `VZMacOSRestoreImage.image(from:)` reads the whole archive's metadata and reports no
progress while it does. On a healthy ~21 GB IPSW this takes seconds to a minute or two. On a
*partial* download it can block for a very long time instead of failing.
**Fix.** The obvious checks are now made before the framework is handed the file — it must exist, be
a regular file, be at least 1 GB, and start with the zip magic `PK` — so an incomplete download now
fails immediately with its actual size rather than hanging. If you are on an older build, check by
hand:
```sh
ls -la ~/Downloads/UniversalMac_*.ipsw # ~15-22 GB, no .download/.crdownload sibling
xxd -l 2 -p ~/Downloads/UniversalMac_*.ipsw # must print 504b
```
Anything smaller, or not starting `504b`, is an incomplete or wrong file: delete it and download it
again.
> A pattern that matches **more than one** IPSW is refused outright, listing the matches — for
> example `~/Downloads/UniversalMac_27.0_*.ipsw` when two 27.0 builds are sitting in `~/Downloads`.
> Name exactly one of them.
---
## `image build` hangs at install
**Symptom.** `image build` sits for a long time at the macOS install phase with little visible