golang.org/x/build@v0.0.0-20240506185731-218518f32b70/env/darwin/aws/README.md (about)

     1  # Darwin builders on AWS
     2  
     3  Darwin builders on AWS run on [EC2 Mac
     4  Instances](https://aws.amazon.com/ec2/instance-types/mac/), which are dedicated
     5  Mac Mini hosts. These dedicated hosts must be allocated for at least 24 hours at
     6  a time. They can be reimaged at any time while allocated, but the reimaging
     7  process takes around an hour. Thus, for faster refresh time on hermetic
     8  builders, we run buildlets as MacOS guests inside of QEMU on the dedicated
     9  hosts.
    10  
    11  ## Creating a dedicated host
    12  
    13  Note that if you simply need more instances, an AMI with the final state is
    14  saved on the AWS account.
    15  
    16  To bring up a new host:
    17  
    18  1. In the EC2 console, go to "Dedicated Hosts" -> "Allocate Dedicated Host".
    19  2. Configure host type, zone. Instance family `mac1` is amd64; `mac2` is arm64.
    20  3. Enable "Instance auto-placement", which allows any instance to run on this
    21     host.
    22  4. Once the host is allocated and available, go to the "Instances" page and
    23     click "Launch an instance".
    24  5. Select a macOS AMI. If starting fresh, select the latest macOS version from
    25     "Quick Start". If simply adding more instances, a fully set-up AMI is saved
    26     in "My AMIs".
    27  6. Select a "Key pair" for SSH access. `ec2-go-builders` for official builders,
    28     a custom key for testing. You will need the private key to login.
    29  7. Configure a 200GB disk.
    30  8. If creating from a fully set-up AMI, uncheck "Allow SSH Traffic".
    31  9. Under "Advanced", select "Tenancy" -> "Dedicated host".
    32  10. Other settings can remain at default. Launch instance.
    33  
    34  If creating from a fully set-up AMI, you are done!
    35  
    36  SSH with the key pair using the "Public IPv4 DNS" address from the "Instances"
    37  page. This won't appear until the instance is booted.
    38  
    39  ```sh
    40  $ export KEY_PATH=~/.ssh/ec2-go-builders.pem
    41  $ ssh -i $KEY_PATH ec2-user@$INSTANCE
    42  ```
    43  
    44  [See the AWS
    45  docs](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-mac-instances.html#mac-instance-vnc)
    46  for setting up remote desktop access. Note that not all VNC client work with
    47  Apple's server. [Remmina](https://remmina.org/) works.
    48  
    49  The OS will only use 100GB of the disk by default. You must [increase the volume
    50  size](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-mac-instances.html#mac-instance-increase-volume)
    51  to utilize the full disk. This can be done while the disk is in use.
    52  
    53  Continue below to create a new guest image, or [skip ahead](#guest-creation) to
    54  use a pre-created image.
    55  
    56  ## Creating a new guest image
    57  
    58  Steps to create a new QEMU macOS guest image:
    59  
    60  1. Build (`make dist`) or
    61     [download](https://github.com/thenickdude/KVM-Opencore/releases) a copy of
    62     the OpenCore bootloader from
    63     https://github.com/thenickdude/KVM-Opencore.
    64       1. Grab the `.iso.gz` file, `gunzip` it, and rename to `opencore.img` (it
    65          is a raw disk image, not actually an `iso`).
    66  2. Create a macOS recovery disk image:
    67     1. Clone https://github.com/kholia/OSX-KVM.
    68     2. `cd scripts/monterey && make Monterey-recovery.dmg`
    69  3. Download the UTM QEMU fork and extract to `~/sysroot-macos-x86_64`.
    70     1. Available as `Sysroot-macos-x86_64` in
    71        https://github.com/utmapp/UTM/actions?query=event%3Arelease builds.
    72  4. Create a disk image to install macOS to.
    73     1. `DYLD_LIBRARY_PATH="$HOME/sysroot-macos-x86_64/lib"
    74        "$HOME/sysroot-macos-x86_64/bin/qemu-img" create -f qcow2
    75        macos-monterey.qcow2 128G`
    76  5. Determine the magic Apple OSK value.
    77     1. Either [read it directly from the machine](https://www.nicksherlock.com/2021/10/installing-macos-12-monterey-on-proxmox-7/#:~:text=Fetch%20the%20OSK%20authentication%20key), or [find it in some code](https://github.com/kholia/OSX-KVM/blob/master/OpenCore-Boot-macOS.sh#L45).
    78  6. Copy the shell scripts from this directory to `$HOME`.
    79  6. Use `$HOME/start-installer.sh macos-monterey.qcow2 opencore.img
    80     Monetery-recovery.dmg $OSK_VALUE` to launch the macOS installer in QEMU.
    81  
    82  NOTE: If networking isn't working on older versions of macOS, swap the
    83  networking flag in `qemu.sh`.
    84  
    85  This starts QEMU with the display on a VNC server at `localhost:5901`. Use SSH
    86  port forwarding to forward this to your local machine:
    87  
    88  ```
    89  $ ssh -i $KEY_PATH -L 5901:localhost:5901 -N ec2-user@$INSTANCE
    90  ```
    91  
    92  Then use a VNC client to connect to `localhost:5901`.
    93  
    94  1. Once connected, select "macOS Base Image" from the bootloader to launch the
    95     installer.
    96  2. In the installer, open the Disk Utility, find the ~128GB QEMU hard disk,
    97     click "Erase", name it "macOS", and leave other options at the default
    98     settings.
    99  3. When formatting is complete, close Disk Utililty, and select "Reinstall
   100     macOs Monterey".
   101  4. Click through the installer. The VM will reboot a few times. When it does,
   102     select "macOS Installer" from the bootloader to continue installation.
   103     Installation is complete when "macOS Installer" is replaced with "MacOS".
   104  5. Select "macOS" and go through the macOS setup as described in the [generic
   105     setup notes](../setup-notes.md).
   106  
   107  Once macOS is fully installed, we will install OpenCore on the primary disk and
   108  configure it to autoboot to macOS.
   109  
   110  1. In the guest, find the OpenCore and primary disks with `diskutil list`.
   111      * The OpenCore disk contains only one parition, of type "EFI". e.g., it may
   112        be /dev/disk0, EFI partition /dev/disk0s1.
   113      * The primary disk contains two paritions, one of type "EFI", one of type
   114        "Apple_APFS". e.g., it may be /dev/disk2, EFI partition /dev/disk2s1.
   115  2. Copy the OpenCore EFI partition over the primary disk EFI partition.
   116      * `sudo dd if=/dev/disk0s1 of=/dev/disk2s1`
   117  3. Mount the primary disk EFI partition to edit the configuration.
   118      * `sudo mkdir /Volumes/EFI`
   119      * `sudo mount -t msdos /dev/disk2s1 /Volumes/EFI`
   120  4. Open `/Volumes/EFI/EFI/OC/config.plist`.
   121      * Change the Misc -> Boot -> Timeout option from `0` to `1` to set the
   122        bootloader to automatically boot macOS with a 1s delay.
   123      * In the `7C436110-AB2A-4BBB-A880-FE41995C9F82`, section, add `-v` to the
   124        `boot-args` string value. This applies the `nvram` option mentioned in
   125        [the setup notes](../setup-notes.md).
   126  5. Shutdown the VM and boot it again with `start-mutable.sh`.
   127  
   128  ```sh
   129  $ $HOME/start-mutable.sh macos-monterey.qcow2 $OSK_VALUE
   130  ```
   131  
   132  Now complete the remainder of the [machine setup](../setup-notes.md). For SSH
   133  access, the guest should be reachable at 192.168.64.2 or 192.168.64.3 from the
   134  host machine.
   135  
   136  Copy complete images to `s3://go-builder-data/darwin/` for use on other
   137  builders.
   138  
   139  ## Set up automated guest creation {#guest-creation}
   140  
   141  1. Download the latest image from `s3://go-builder-data/darwin/` and save it to
   142     `$HOME/macos.qcow2`.
   143  2. Download the UTM QEMU fork and extract to `~/sysroot-macos-x86_64`.
   144     1. Available as `Sysroot-macos-x86_64` in
   145        https://github.com/utmapp/UTM/actions?query=event%3Arelease builds.
   146  3. Copy `bootptab` to `/etc/bootptab`.
   147  4. Restart the system DHCP server to pick up the new `bootptab`: `sudo /bin/launchctl unload -w /System/Library/LaunchDaemons/bootps.plist; sudo /bin/launchctl load -w /System/Library/LaunchDaemons/bootps.plist`.
   148  4. Build `golang.org/x/build/cmd/runqemubuildlet` and copy it to `$HOME`.
   149  5. Create `$HOME/loop1.sh`:
   150  
   151  ```sh
   152  #!/bin/bash
   153  
   154  while true; do
   155    echo "Running QEMU..."
   156    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"
   157  done
   158  ```
   159  
   160  4. Create `$HOME/loop2.sh`:
   161  
   162  ```sh
   163  #!/bin/bash
   164  
   165  while true; do
   166    echo "Running QEMU..."
   167    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"
   168  done
   169  ```
   170  
   171  Replace `${OSK_VALUE?} with the OSK value described in the previous section.
   172  
   173  5. Setup Automator:
   174    1. Open Automator
   175    2. File > New > Application
   176    3. Add "Run shell script"
   177    4. `open -a Terminal.app $HOME/loop1.sh`
   178    5. Save to desktop twice as `run-builder1`
   179    2. File > New > Application
   180    3. Add "Run shell script"
   181    4. `open -a Terminal.app $HOME/loop2.sh`
   182    5. Save to desktop twice as `run-builder2`
   183  
   184  Note that loop1.sh and loop2.sh guests will have a display at VNC port 5901 and
   185  5902, respectively.
   186  
   187  6. Setup login:
   188    1. Users & Groups > ec2-user > Login Items > add run-builder1
   189    2. Users & Groups > ec2-user > Login Items > add run-builder2
   190    3. Users & Groups > Login Options > auto-login ec2-user
   191    4. Desktop & Screensaver > uncheck show screensaver
   192  
   193  Once image is set up and working, stop the instance and create an AMI copy of
   194  the instance. On the EC2 "Instances" page, select the instance, and click
   195  "Actions" -> "Image and templates" -> "Create Image".
   196  
   197  Either create a new instance from this image with no SSH access, or edit the
   198  instance networking inbound rules to remove SSH access.
   199  
   200  
   201  ## References
   202  
   203  * [EC2 Mac Instances USer
   204    Guide](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-mac-instances.html):
   205    Contains most of the useful how-tos on working with Mac instances.
   206  * [Remmina](https://remmina.org/): VNC client that works with Apple's [VNC
   207    server](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-mac-instances.html#mac-instance-vnc)
   208    (not all clients work).
   209  * [QEMU MacOS install
   210    guide](https://www.nicksherlock.com/2021/10/installing-macos-12-monterey-on-proxmox-7/):
   211    Guide with similar instructions for MacOS in QEMU.