# Testing a clean install in a macOS VM A tart VM on the Mac byre runs on gives a fresh Mac in seconds, to install byre on as a new user would. `tart list` shows the VMs there. ## The base VM `byre-base` is a stopped VM left as just set up, kept in `~/.tart/vms/` (outside any checkout), and never run or installed into. Tests run on clones of it. It has: - the macOS that `tart create --from-ipsw latest` installed (the newest the host supports; `tart get byre-base` and `sw_vers` inside show it), 4 CPUs, 8 GB of memory and an 80 GB disk; - one account, `admin` with password `admin`, signed in automatically at boot, with passwordless `sudo`, the host user's `~/.ssh/id_ed25519.pub` in `authorized_keys`, Remote Login on, and sleep and screen lock off; - no Apple Account, FileVault, Siri, Location Services or analytics, and macOS updates that download without installing; - nothing else: no Homebrew, Command Line Tools, Tailscale or byre. ## Testing ``` tart clone byre-base byre-test tart run byre-test ``` Run `tart run` in the task's terminal: it keeps running while the VM is up, and the VM's screen opens as a `tart` window. `tart ip byre-test` prints the VM's address once it has booted; `ssh admin@` gets in. `tart delete byre-test` throws the clone away. A clone is a copy-on-write copy, so it takes seconds and little disk. Apple's license allows two macOS VMs running at once per Mac, and other tasks may be running one. To install a build, copy `~/byre-deploy/byre.dmg` (or a `mac/bundle.sh` build) in and put `Byre.app` in `/Applications` there. Copy an app bundle as a zip (`ditto -c -k --keepParent` on the host, `ditto -x -k` in the VM), since `scp -r` fails on the symlinks in its frameworks. Open apps in the VM's GUI session from SSH with `sudo launchctl asuser 501 sudo -u admin open /Applications/Byre.app`. The app's Tailscale sign-in opens Safari in the VM. To have the human approve it from their own Mac, read the address over SSH (`sudo launchctl asuser 501 sudo -u admin osascript -e 'tell application "Safari" to get URL of front document'`, which asks once in the VM for Automation of Safari) and open the `https://login.tailscale.com/a/` it names with `show_page` on the human's Mac. ## Driving the VM's screen - Click the `tart` window's title bar first: the VM takes clicks and keys only while its window is the key window. - Keys reach the VM without their modifiers through hands, so Shift, Cmd and symbols typed with `type` or `key` arrive wrong. Type only lowercase text and plain symbols there, and do the rest over SSH. - Scrolling doesn't reach the VM; drag the scroll bar instead. - `screencapture` over SSH fails for lack of Screen Recording in the VM; capture the `tart` window from the host with hands. - Check `screen_list` before acting: another task's `tart` window can sit exactly on top of yours. ## Rebuilding the base Only when it needs a newer macOS. `tart create --from-ipsw latest --disk-size 80 byre-base` downloads the restore image (about 15 GB, cached in `~/.tart/cache/IPSWs/`) and installs it; `tart set byre-base --cpu 4 --memory 8192`. Run it and click through Setup Assistant: "Set up as new", account `admin`/`admin`, skip the Apple Account ("Sign in Later in Settings"), and decline everything else. Then turn on Remote Login from the VM's Terminal: ``` sudo launchctl enable system/com.openssh.sshd; sudo launchctl bootstrap system /System/Library/LaunchDaemons/ssh.plist ``` and over SSH from the host (`ssh-copy-id admin@`, then): ``` echo 'admin ALL=(ALL) NOPASSWD: ALL' | sudo tee /etc/sudoers.d/admin sudo chmod 440 /etc/sudoers.d/admin sudo launchctl asuser 501 sudo sysadminctl -autologin set -userName admin -password admin sudo pmset -a sleep 0 displaysleep 0 sudo shutdown -h now ``` `sysadminctl -autologin` fails with error 22 when run over SSH outside the GUI session, hence `launchctl asuser`. tart itself is installed from its GitHub release (`gh release download --repo cirruslabs/tart`, unpacked to `~/Applications/tart.app`, with `~/bin/tart` linked to `tart.app/Contents/MacOS/tart`), since the Homebrew formula in `cirruslabs/cli` fails on current Homebrew.