Darwin builders on AWS run on EC2 Mac Instances, which are dedicated Mac Mini hosts. These dedicated hosts must be allocated for at least 24 hours at a time. They can be reimaged at any time while allocated, but the reimaging process takes around an hour. Thus, for faster refresh time on hermetic builders, we run buildlets as MacOS guests inside of QEMU on the dedicated hosts.
Note that if you simply need more instances, an AMI with the final state is saved on the AWS account.
To bring up a new host:
mac1
is amd64; mac2
is arm64.ec2-go-builders
for official builders, a custom key for testing. You will need the private key to login.If creating from a fully set-up AMI, you are done!
SSH with the key pair using the “Public IPv4 DNS” address from the “Instances” page. This won't appear until the instance is booted.
$ export KEY_PATH=~/.ssh/ec2-go-builders.pem $ ssh -i $KEY_PATH ec2-user@$INSTANCE
See the AWS docs for setting up remote desktop access. Note that not all VNC client work with Apple's server. Remmina works.
The OS will only use 100GB of the disk by default. You must increase the volume size to utilize the full disk. This can be done while the disk is in use.
Continue below to create a new guest image, or skip ahead to use a pre-created image.
Steps to create a new QEMU macOS guest image:
make dist
) or download a copy of the OpenCore bootloader from https://github.com/thenickdude/KVM-Opencore..iso.gz
file, gunzip
it, and rename to opencore.img
(it is a raw disk image, not actually an iso
).cd scripts/monterey && make Monterey-recovery.dmg
~/sysroot-macos-x86_64
.Sysroot-macos-x86_64
in https://github.com/utmapp/UTM/actions?query=event%3Arelease builds.DYLD_LIBRARY_PATH="$HOME/sysroot-macos-x86_64/lib" "$HOME/sysroot-macos-x86_64/bin/qemu-img" create -f qcow2 macos-monterey.qcow2 128G
$HOME
.$HOME/start-installer.sh macos-monterey.qcow2 opencore.img Monetery-recovery.dmg $OSK_VALUE
to launch the macOS installer in QEMU.NOTE: If networking isn't working on older versions of macOS, swap the networking flag in qemu.sh
.
This starts QEMU with the display on a VNC server at localhost:5901
. Use SSH port forwarding to forward this to your local machine:
$ ssh -i $KEY_PATH -L 5901:localhost:5901 -N ec2-user@$INSTANCE
Then use a VNC client to connect to localhost:5901
.
Once macOS is fully installed, we will install OpenCore on the primary disk and configure it to autoboot to macOS.
diskutil list
.sudo dd if=/dev/disk0s1 of=/dev/disk2s1
sudo mkdir /Volumes/EFI
sudo mount -t msdos /dev/disk2s1 /Volumes/EFI
/Volumes/EFI/EFI/OC/config.plist
.0
to 1
to set the bootloader to automatically boot macOS with a 1s delay.7C436110-AB2A-4BBB-A880-FE41995C9F82
, section, add -v
to the boot-args
string value. This applies the nvram
option mentioned in the setup notes.start-mutable.sh
.$ $HOME/start-mutable.sh macos-monterey.qcow2 $OSK_VALUE
Now complete the remainder of the machine setup. For SSH access, the guest should be reachable at 192.168.64.2 or 192.168.64.3 from the host machine.
Copy complete images to s3://go-builder-data/darwin/
for use on other builders.
s3://go-builder-data/darwin/
and save it to $HOME/macos.qcow2
.~/sysroot-macos-x86_64
.Sysroot-macos-x86_64
in https://github.com/utmapp/UTM/actions?query=event%3Arelease builds.bootptab
to /etc/bootptab
.bootptab
: sudo /bin/launchctl unload -w /System/Library/LaunchDaemons/bootps.plist; sudo /bin/launchctl load -w /System/Library/LaunchDaemons/bootps.plist
.golang.org/x/build/cmd/runqemubuildlet
and copy it to $HOME
.$HOME/loop1.sh
:#!/bin/bash while true; do echo "Running QEMU..." sudo $HOME/runqemubuildlet -guest-os=darwin -macos-version=${MACOS_VERSION?} -osk=${OSK_VALUE?} -guest-index=1 -buildlet-healthz-url="http://192.168.64.101:8080/healthz" done
$HOME/loop2.sh
:#!/bin/bash while true; do echo "Running QEMU..." sudo $HOME/runqemubuildlet -guest-os=darwin -macos-version=${MACOS_VERSION?} -osk=${OSK_VALUE?} -guest-index=2 -buildlet-healthz-url="http://192.168.64.102:8080/healthz" done
Replace `${OSK_VALUE?} with the OSK value described in the previous section.
open -a Terminal.app $HOME/loop1.sh
run-builder1
open -a Terminal.app $HOME/loop2.sh
run-builder2
Note that loop1.sh and loop2.sh guests will have a display at VNC port 5901 and 5902, respectively.
Once image is set up and working, stop the instance and create an AMI copy of the instance. On the EC2 “Instances” page, select the instance, and click “Actions” -> “Image and templates” -> “Create Image”.
Either create a new instance from this image with no SSH access, or edit the instance networking inbound rules to remove SSH access.