Skip to content

Commit c2d5249

Browse files
committed
servo-macos15-arm: initial
1 parent 33f9fcd commit c2d5249

File tree

4 files changed

+372
-1
lines changed

4 files changed

+372
-1
lines changed

monitor/src/image.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ use shell::{log_output_as_info, reflink_or_copy_with_warning};
2828
use tracing::{error, info, warn};
2929

3030
use crate::{
31-
image::{macos13::Macos13, ubuntu2204::Ubuntu2204, windows10::Windows10},
31+
image::{
32+
macos13::{Macos13, MacosUtm},
33+
ubuntu2204::Ubuntu2204,
34+
windows10::Windows10,
35+
},
3236
policy::Policy,
3337
};
3438

@@ -46,6 +50,10 @@ static IMAGES: LazyLock<BTreeMap<String, Box<dyn Image + Send + Sync>>> = LazyLo
4650
"servo-macos15".to_owned(),
4751
Box::new(Macos13::new(ByteSize::gib(90), Duration::from_secs(2000))),
4852
);
53+
result.insert(
54+
"servo-macos15-arm".to_owned(),
55+
Box::new(MacosUtm::default()),
56+
);
4957
result.insert(
5058
"servo-ubuntu2204".to_owned(),
5159
Box::new(Ubuntu2204::new(

monitor/src/image/macos13.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,37 @@ impl Image for Macos13 {
7474
}
7575
}
7676

77+
#[derive(Default)]
78+
pub struct MacosUtm;
79+
80+
#[expect(unused_variables)]
81+
impl Image for MacosUtm {
82+
fn rebuild(&self, profile: &Profile, snapshot_name: &str) -> eyre::Result<()> {
83+
let profile_name = &profile.profile_name;
84+
let rebuild_guest_name = &profile.rebuild_guest_name(snapshot_name);
85+
hypervisor::utm::clone_guest(&format!("{profile_name}-clean"), rebuild_guest_name)?;
86+
Ok(())
87+
}
88+
fn delete_template(&self, profile: &Profile, snapshot_name: &str) -> eyre::Result<()> {
89+
todo!()
90+
}
91+
fn register_runner(&self, profile: &Profile, runner_guest_name: &str) -> eyre::Result<String> {
92+
todo!()
93+
}
94+
fn create_runner(
95+
&self,
96+
profile: &Profile,
97+
snapshot_name: &str,
98+
runner_guest_name: &str,
99+
runner_id: usize,
100+
) -> eyre::Result<String> {
101+
todo!()
102+
}
103+
fn destroy_runner(&self, runner_guest_name: &str, runner_id: usize) -> eyre::Result<()> {
104+
todo!()
105+
}
106+
}
107+
77108
pub(super) fn rebuild(
78109
profile: &Profile,
79110
snapshot_name: &str,
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/usr/bin/env zsh
2+
set -euxo pipefail -o bsdecho
3+
4+
download() {
5+
curl -fsSLO "http://192.168.100.1:8000/image-deps/macos13/$1"
6+
}
7+
8+
install_github_actions_runner() {
9+
if ! [ -e actions-runner-osx-x64.tar.gz ]; then
10+
download actions-runner-osx-x64.tar.gz
11+
rm -Rf actions-runner
12+
mkdir -p actions-runner
13+
( cd actions-runner; tar xf ../actions-runner-osx-x64.tar.gz )
14+
fi
15+
}
16+
17+
bake_servo_repo() (
18+
# Note the parentheses around this block, so we only cd for this function
19+
cd ~/a/servo/servo
20+
21+
# Fix the remote url, since it’s still set to our cache
22+
git remote set-url origin https://github.com/servo/servo.git
23+
24+
# Install the Rust toolchain, for checkouts without servo#35795
25+
rustup show active-toolchain || rustup toolchain install
26+
27+
./mach bootstrap --force
28+
# Build the same way as a typical macOS libservo job, to allow for incremental builds.
29+
# FIXME: `cargo build -p libservo` is busted on most platforms <https://github.com/servo/servo/issues/37939>
30+
# FIXME: `cargo build -p libservo` is untested in CI <https://github.com/servo/servo/issues/38015>
31+
# cargo build -p libservo --all-targets --release --target-dir target/libservo
32+
# Build the same way as a typical macOS build job, to allow for incremental builds.
33+
./mach build --use-crown --locked --release
34+
)
35+
36+
start_github_actions_runner() {
37+
curl -fsS --max-time 5 --retry 99 --retry-all-errors http://192.168.100.1:8000/github-jitconfig | jq -er . > jitconfig
38+
actions-runner/run.sh --jitconfig $(cat jitconfig)
39+
}
40+
41+
mkdir -p /Users/servo/ci
42+
cd /Users/servo/ci
43+
44+
# Resize the window to occupy more of the 1280x800 display
45+
# - Method based on <https://apple.stackexchange.com/a/290802>
46+
# - Another method for exclusive fullscreen <https://apple.stackexchange.com/a/58962>
47+
# - Another method with unclear automation <https://apple.stackexchange.com/a/228052>
48+
osascript -e 'tell application "Terminal"' -e 'activate' -e 'set the bounds of the first window to {0,0,1280,600}' -e 'end tell'
49+
50+
# Disable sleep and display sleep
51+
# <https://apple.stackexchange.com/a/458157>
52+
sudo pmset sleep 0
53+
sudo pmset displaysleep 0
54+
55+
# ~/.cargo/env requires HOME to be set
56+
export HOME=/Users/servo
57+
58+
# Ensure uv is on PATH
59+
export PATH=$HOME/.local/bin:$PATH
60+
61+
if ! [ -e image-built ]; then
62+
# Install Xcode CLT (Command Line Tools) non-interactively
63+
# <https://github.com/actions/runner-images/blob/3d5f09a90fd475a3531b0ef57325aa7e27b24595/images/macos/scripts/build/install-xcode-clt.sh>
64+
download install-xcode-clt.sh
65+
chmod +x install-xcode-clt.sh
66+
sudo -i mkdir -p /var/root/utils
67+
sudo -i touch /var/root/utils/utils.sh
68+
sudo -i $PWD/install-xcode-clt.sh
69+
70+
# Install Homebrew
71+
if ! [ -e /usr/local/bin/brew ]; then
72+
download install-homebrew.sh
73+
chmod +x install-homebrew.sh
74+
NONINTERACTIVE=1 ./install-homebrew.sh
75+
fi
76+
77+
set -- gnu-tar # Install gtar(1)
78+
set -- "$@" jq # Used by start_github_actions_runner()
79+
80+
brew install "$@"
81+
82+
# Install rustup and the latest Rust
83+
if ! [ -e ~/.rustup ]; then
84+
download rustup-init
85+
chmod +x rustup-init
86+
./rustup-init -y --quiet
87+
mkdir -p ~/.cargo
88+
curl -fsSLo ~/.cargo/config.toml http://192.168.100.1:8000/image-deps/cargo-config.toml
89+
fi
90+
91+
# Install uv
92+
if ! [ -e ~/.local/bin/uv ]; then
93+
download uv-installer.sh
94+
chmod +x uv-installer.sh
95+
./uv-installer.sh
96+
fi
97+
fi
98+
99+
# Set up Cargo
100+
. ~/.cargo/env
101+
102+
if ! [ -e image-built ]; then
103+
# Clone and bake the Servo repo
104+
mkdir -p ~/a/servo
105+
git clone http://192.168.100.1:8000/cache/servo/.git ~/a/servo/servo
106+
bake_servo_repo
107+
108+
install_github_actions_runner
109+
touch image-built
110+
sudo shutdown -h now
111+
exit # `shutdown` does not exit
112+
else
113+
start_github_actions_runner
114+
fi
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
<?xml version='1.0' encoding='UTF-8'?>
2+
<!-- Based on <https://github.com/kholia/OSX-KVM/blob/182e2dd0715175801521f6342ac7cc715044cb12/macOS-libvirt-Catalina.xml> -->
3+
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
4+
<!--
5+
macOS libvirt XML configuration.
6+
7+
Run "virt-xml-validate macOS-libvirt-Catalina.xml" to validate this file.
8+
9+
To install this file, you may place it at ~/.config/libvirt/qemu/
10+
and run: virsh define macOS-libvirt.xml.
11+
12+
This configuration has been tested in Ubuntu 20.04 with stock QEMU-KVM.
13+
14+
Move/rename images and loader/nvmram files and paths as you wish.
15+
16+
!!! Don't forget to replace CHANGEME with your values !!!
17+
18+
Adjust memory and currentMemory to 3145728 if you want only 3 GiB.
19+
20+
Consider removing some cpu features if your hardware lacks support.
21+
22+
Replace spice with vnc if you prefer it.
23+
24+
Current network configuration is a local bridge (192.168.12x.x).
25+
Change it to if you prefer a public bridge instead:
26+
Change interface to <interface type='user'>
27+
and remove the <source bridge='virbr0'/>
28+
Or use virt-manager to edit this line instead of virsh edit.
29+
30+
Note: Default configuration caused severe clock problems
31+
under Fedora 27 w/ i7-5820K. This is because Darwin uses
32+
tsc (time since last tick) for time, and for me did not
33+
fall back to rtc in the event of a clock mismatch with
34+
libvirt's default time source. Therefore we must explicitly
35+
give the clock a tsc timer for kvm to pass to the guest.
36+
See comments on the <kvm> and <clock> attributes.
37+
-->
38+
<name>servo-macos15.init</name>
39+
<uuid>25cb2b90-081e-44b2-a9ac-5cee8370ae44</uuid>
40+
<memory unit="KiB">25165824</memory>
41+
<currentMemory unit="KiB">25165824</currentMemory>
42+
<memoryBacking>
43+
<hugepages/>
44+
</memoryBacking>
45+
<vcpu placement='static'>16</vcpu>
46+
<os>
47+
<type arch='x86_64' machine='pc-q35-4.2'>hvm</type>
48+
<!-- We don't need patched OVMF anymore when using latest OpenCore, stock one is okay -->
49+
<loader readonly='yes' type='pflash'>/var/lib/libvirt/images/OSX-KVM/OVMF_CODE.fd</loader>
50+
<nvram>/var/lib/libvirt/images/OSX-KVM/OVMF_VARS.fd</nvram>
51+
</os>
52+
<features>
53+
<acpi/>
54+
<apic/>
55+
</features>
56+
<clock offset='utc'>
57+
<timer name='rtc' tickpolicy='catchup'/>
58+
<timer name='pit' tickpolicy='delay'/>
59+
<timer name='hpet' present='no'/>
60+
</clock>
61+
<on_poweroff>destroy</on_poweroff>
62+
<on_reboot>restart</on_reboot>
63+
<on_crash>restart</on_crash>
64+
<devices>
65+
<emulator>/run/libvirt/nix-emulators/qemu-system-x86_64</emulator>
66+
<disk type='file' device='disk'>
67+
<driver name='qemu' type='qcow2' cache='writeback' io='threads'/>
68+
<source file='/var/lib/libvirt/images/OSX-KVM/OpenCore/OpenCore.macos15.qcow2'/>
69+
<target dev='sda' bus='sata'/>
70+
<boot order='2'/>
71+
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
72+
</disk>
73+
<disk type='block' device='disk'>
74+
<!-- TODO: can we benefit from these OSX-KVM defaults? -->
75+
<!-- <driver name='qemu' type='qcow2' cache='writeback' io='threads'/> -->
76+
<driver name='qemu' type='raw' cache='none' io='native' discard='unmap'/>
77+
<!-- virt-clone(1) will replace this with the first `-f` -->
78+
<source dev='/dev/null'/>
79+
<target dev='sdb' bus='sata'/>
80+
<boot order='1'/>
81+
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
82+
</disk>
83+
<disk type="file" device="disk">
84+
<driver name="qemu" type="raw" cache="writeback"/>
85+
<source file="/var/lib/libvirt/images/OSX-KVM/BaseSystem.macos15.img"/>
86+
<target dev="sdc" bus="sata"/>
87+
<boot order="3"/>
88+
<address type="drive" controller="0" bus="0" target="0" unit="2"/>
89+
</disk>
90+
<controller type='sata' index='0'>
91+
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
92+
</controller>
93+
<controller type='pci' index='0' model='pcie-root'/>
94+
<controller type='pci' index='1' model='pcie-root-port'>
95+
<model name='pcie-root-port'/>
96+
<target chassis='1' port='0x8'/>
97+
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
98+
</controller>
99+
<controller type='pci' index='2' model='pcie-root-port'>
100+
<model name='pcie-root-port'/>
101+
<target chassis='2' port='0x9'/>
102+
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
103+
</controller>
104+
<controller type='pci' index='3' model='pcie-root-port'>
105+
<model name='pcie-root-port'/>
106+
<target chassis='3' port='0xa'/>
107+
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
108+
</controller>
109+
<controller type='pci' index='4' model='pcie-root-port'>
110+
<model name='pcie-root-port'/>
111+
<target chassis='4' port='0xb'/>
112+
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x3'/>
113+
</controller>
114+
<controller type='pci' index='5' model='pcie-root-port'>
115+
<model name='pcie-root-port'/>
116+
<target chassis='5' port='0xc'/>
117+
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x4'/>
118+
</controller>
119+
<controller type='pci' index='6' model='pcie-root-port'>
120+
<model name='pcie-root-port'/>
121+
<target chassis='6' port='0xd'/>
122+
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x5'/>
123+
</controller>
124+
<controller type='pci' index='7' model='pcie-root-port'>
125+
<model name='pcie-root-port'/>
126+
<target chassis='7' port='0xe'/>
127+
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x6'/>
128+
</controller>
129+
<controller type='virtio-serial' index='0'>
130+
<address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
131+
</controller>
132+
<controller type='usb' index='0' model='ich9-ehci1'>
133+
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x7'/>
134+
</controller>
135+
<controller type='usb' index='0' model='ich9-uhci1'>
136+
<master startport='0'/>
137+
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0' multifunction='on'/>
138+
</controller>
139+
<controller type='usb' index='0' model='ich9-uhci2'>
140+
<master startport='2'/>
141+
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x1'/>
142+
</controller>
143+
<controller type='usb' index='0' model='ich9-uhci3'>
144+
<master startport='4'/>
145+
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x2'/>
146+
</controller>
147+
<!-- Make sure you put your nic in bus 0x0 and slot 0x0y(y is numeric), this will make nic built-in and apple-store work-->
148+
<interface type="bridge">
149+
<mac address="52:54:00:e6:85:40"/>
150+
<source bridge="cinet"/>
151+
<model type="vmxnet3"/>
152+
<address type="pci" domain="0x0000" bus="0x00" slot="0x00" function="0x0"/>
153+
</interface>
154+
<serial type='pty'>
155+
<target type='isa-serial' port='0'>
156+
<model name='isa-serial'/>
157+
</target>
158+
</serial>
159+
<console type='pty'>
160+
<target type='serial' port='0'/>
161+
</console>
162+
<channel type='unix'>
163+
<target type='virtio' name='org.qemu.guest_agent.0'/>
164+
<address type='virtio-serial' controller='0' bus='0' port='1'/>
165+
</channel>
166+
<graphics type='spice' autoport='yes'>
167+
<listen type='address'/>
168+
</graphics>
169+
<video>
170+
<model type="virtio" heads="1" primary="yes"/>
171+
</video>
172+
<!-- If you wanna passthrough GPU, make sure the gfx and audio are in the same bus (like 0x01) but different function (0x00 and 0x01)-->
173+
<!-- <hostdev mode='subsystem' type='pci' managed='yes'>
174+
<driver name='vfio'/>
175+
<source>
176+
<address domain='0x0000' bus='0x2d' slot='0x00' function='0x0'/>
177+
</source>
178+
<rom file='/mnt/disks/backups/BIOS/RX580/Ellesmere.rom'/>
179+
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0' multifunction='on'/>
180+
</hostdev>
181+
<hostdev mode='subsystem' type='pci' managed='yes'>
182+
<driver name='vfio'/>
183+
<source>
184+
<address domain='0x0000' bus='0x2d' slot='0x00' function='0x1'/>
185+
</source>
186+
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x1'/>
187+
</hostdev> -->
188+
<!-- If you wanna passthrough onboard audio(like 30:00.4), make sure you put it in bus 0x00 and slot 0x0y(y is numeric), otherwise AppleALC won't recognized it -->
189+
<!-- <hostdev mode='subsystem' type='pci' managed='yes'>
190+
<driver name='vfio'/>
191+
<source>
192+
<address domain='0x0000' bus='0x30' slot='0x00' function='0x4'/>
193+
</source>
194+
<address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
195+
</hostdev> -->
196+
<memballoon model='none'/>
197+
</devices>
198+
<!-- Note: Enable the next line when SELinux is enabled -->
199+
<!-- seclabel type='dynamic' model='selinux' relabel='yes'/> -->
200+
<qemu:commandline>
201+
<qemu:arg value='-device'/>
202+
<qemu:arg value='isa-applesmc,osk=ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc'/>
203+
<qemu:arg value='-smbios'/>
204+
<qemu:arg value='type=2'/>
205+
<qemu:arg value='-usb'/>
206+
<qemu:arg value='-device'/>
207+
<qemu:arg value='usb-tablet'/>
208+
<qemu:arg value='-device'/>
209+
<qemu:arg value='usb-kbd'/>
210+
<qemu:arg value='-cpu'/>
211+
<qemu:arg value='Haswell-noTSX,kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on,+ssse3,+sse4.2,+popcnt,+avx,+aes,+xsave,+xsaveopt,check'/>
212+
<!-- <qemu:arg value='Penryn,vendor=GenuineIntel,+hypervisor,+invtsc,kvm=on,+fma,+avx,+avx2,+aes,+ssse3,+sse4_2,+popcnt,+sse4a,+bmi1,+bmi2'/> -->
213+
<!-- If you wanna use cpu host-passthrough mode, uncomments below-->
214+
<!-- <qemu:arg value='host,vendor=GenuineIntel,+hypervisor,+invtsc,kvm=on,+fma,+avx,+avx2,+aes,+ssse3,+sse4_2,+popcnt,+sse4a,+bmi1,+bmi2'/> -->
215+
<!-- If you wanna use cpu emulating mode like Skylake-Server, uncomments below-->
216+
<!-- <qemu:arg value='Skylake-Server,vendor=GenuineIntel,+hypervisor,+invtsc,kvm=on,+fma,+avx,+avx2,+aes,+ssse3,+sse4_2,+popcnt,+sse4a,+bmi1,+bmi2'/> -->
217+
</qemu:commandline>
218+
</domain>

0 commit comments

Comments
 (0)