Skip to content

Commit 5247cd9

Browse files
committed
feature: use Rosetta AOT Caching with CDI
This change introduces device configuration to enable Rosetta AOT Caching in Docker VMs. - Modify Rosetta Caching Options from Abstract Socket to Unix Domain Socket: Unix Domain Socket can be mounted within a container using the Container Device Interface (CDI) mechanism. This requires merging the following pull request: Code-Hex/vz#195. - Register Rosettad AOT Caching Daemon as a service: - `/etc/systemd/system/rosettad.service` on systemd - `/etc/init.d/rosettad` on OpenRC - Add "lima.io/rosetta=cached" device specification to `{~/.config,/etc}/cdi/rosetta.yaml` see: https://github.com/cncf-tags/container-device-interface/blob/main/SPEC.md - Add `{~/.config,/etc}/docker/daemon.json` to `docker{,-rootful}.yaml` - `.features.cdi = true` to enable CDI - Add `enable_cdi = true` to `{~/.config,/etc}/containerd/config.toml` To enable Rosetta AOT Caching in docker, use `--device=lima.io/rosetta=cached`. see: https://docs.docker.com/build/building/cdi/ Signed-off-by: Norio Nomura <norio.nomura@gmail.com>
1 parent 6414eca commit 5247cd9

File tree

5 files changed

+105
-1
lines changed

5 files changed

+105
-1
lines changed

pkg/cidata/cidata.TEMPLATE.d/boot/40-install-containerd.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ if [ "${LIMA_CIDATA_CONTAINERD_SYSTEM}" = 1 ]; then
4545
mkdir -p /etc/containerd /etc/buildkit
4646
cat >"/etc/containerd/config.toml" <<EOF
4747
version = 2
48+
[plugins."io.containerd.grpc.v1.cri"]
49+
enable_cdi = true
4850
[proxy_plugins]
4951
[proxy_plugins."stargz"]
5052
type = "snapshot"
@@ -67,6 +69,8 @@ if [ "${LIMA_CIDATA_CONTAINERD_USER}" = 1 ]; then
6769
mkdir -p "${LIMA_CIDATA_HOME}/.config/containerd"
6870
cat >"${LIMA_CIDATA_HOME}/.config/containerd/config.toml" <<EOF
6971
version = 2
72+
[plugins."io.containerd.grpc.v1.cri"]
73+
enable_cdi = true
7074
[proxy_plugins]
7175
[proxy_plugins."fuse-overlayfs"]
7276
type = "snapshot"

pkg/driver/vz/boot/05-rosetta-volume.sh

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,81 @@ else
3131
# remove binfmt.d(5) configuration if it exists
3232
[ ! -f "$binfmtd_conf" ] || rm "$binfmtd_conf"
3333
fi
34+
35+
if [ -x /mnt/lima-rosetta/rosettad ]; then
36+
CACHE_DIRECTORY=/var/cache/rosettad
37+
DEFAULT_SOCKET=${CACHE_DIRECTORY}/uds/rosetta.sock
38+
EXPECTED_SOCKET=/run/rosettad/rosetta.sock
39+
40+
# Create rosettad service
41+
if [ -f /sbin/openrc-run ]; then
42+
cat >/etc/init.d/rosettad <<EOF
43+
#!/sbin/openrc-run
44+
name="rosettad"
45+
description="Rosetta AOT Caching Daemon"
46+
required_dirs=/mnt/lima-rosetta
47+
required_files=/mnt/lima-rosetta/rosettad
48+
command=/mnt/lima-rosetta/rosettad
49+
command_args="daemon ${CACHE_DIRECTORY}"
50+
command_background=true
51+
pidfile="/run/rosettad.pid"
52+
start_pre() {
53+
# To detect creation of the socket by rosettad, remove the old socket before starting
54+
test ! -e "${DEFAULT_SOCKET}" || rm -f "${DEFAULT_SOCKET}"
55+
}
56+
start_post() {
57+
# Set the socket permission to world-writable
58+
while ! chmod -f go+w "${DEFAULT_SOCKET}"; do sleep 1; done
59+
# Create the symlink as expected by the configuration to enable Rosetta AOT caching
60+
mkdir -p "$(dirname "${EXPECTED_SOCKET}")"
61+
ln -sf "${DEFAULT_SOCKET}" "${EXPECTED_SOCKET}"
62+
}
63+
EOF
64+
chmod 755 /etc/init.d/rosettad
65+
rc-update add rosettad default
66+
rc-service rosettad start
67+
else
68+
cat >/etc/systemd/system/rosettad.service <<EOF
69+
[Unit]
70+
Description=Rosetta AOT Caching Daemon
71+
RequiresMountsFor=/mnt/lima-rosetta
72+
[Service]
73+
RuntimeDirectory=rosettad
74+
CacheDirectory=rosettad
75+
# To detect creation of the socket by rosettad, remove the old socket
76+
ExecStartPre=sh -c "test ! -e \"${DEFAULT_SOCKET}\" || rm -f \"${DEFAULT_SOCKET}\""
77+
ExecStart=/mnt/lima-rosetta/rosettad daemon "${CACHE_DIRECTORY}"
78+
# Set the socket permission to world-writable and create the symlink as expected by the configuration to enable Rosetta AOT caching.
79+
ExecStartPost=sh -c "while ! chmod -f go+w \"${DEFAULT_SOCKET}\"; do sleep 1; done; ln -sf \"${DEFAULT_SOCKET}\" \"${EXPECTED_SOCKET}\""
80+
OOMPolicy=continue
81+
OOMScoreAdjust=-500
82+
[Install]
83+
WantedBy=default.target
84+
EOF
85+
systemctl is-enabled rosettad || systemctl enable --now rosettad
86+
fi
87+
88+
# Create CDI configuration for Rosetta
89+
mkdir -p /etc/cdi /var/run/cdi /etc/buildkit/cdi
90+
cat >/etc/cdi/rosetta.yaml <<EOF
91+
cdiVersion: "0.6.0"
92+
kind: "lima-vm.io/rosetta"
93+
devices:
94+
- name: cached
95+
containerEdits:
96+
mounts:
97+
- hostPath: /var/cache/rosettad/uds/rosetta.sock
98+
containerPath: /run/rosettad/rosetta.sock
99+
options: [bind]
100+
annotations:
101+
org.mobyproject.buildkit.device.autoallow: true
102+
EOF
103+
# nerdctl requires user-specific CDI configuration directories
104+
mkdir -p "${LIMA_CIDATA_HOME}/.config/cdi"
105+
ln -sf /etc/cdi/rosetta.yaml "${LIMA_CIDATA_HOME}/.config/cdi/"
106+
chown -R "${LIMA_CIDATA_USER}" "${LIMA_CIDATA_HOME}/.config"
107+
else
108+
# Remove CDI configuration for Rosetta AOT Caching
109+
[ ! -f /etc/cdi/rosetta.yaml ] || rm /etc/cdi/rosetta.yaml
110+
[ ! -d "${LIMA_CIDATA_HOME}/.config/cdi/rosetta.yaml" ] || rm "${LIMA_CIDATA_HOME}/.config/cdi/rosetta.yaml"
111+
fi

pkg/driver/vz/rosetta_directory_share_arm64.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func createRosettaDirectoryShareConfiguration() (*vz.VirtioFileSystemDeviceConfi
4444
return nil, fmt.Errorf("failed to get macOS product version: %w", err)
4545
}
4646
if !macOSProductVersion.LessThan(*semver.New("14.0.0")) {
47-
cachingOption, err := vz.NewLinuxRosettaAbstractSocketCachingOptions("rosetta")
47+
cachingOption, err := vz.NewLinuxRosettaUnixSocketCachingOptions("/run/rosettad/rosetta.sock")
4848
if err != nil {
4949
return nil, fmt.Errorf("failed to create a new rosetta directory share caching option: %w", err)
5050
}

templates/docker-rootful.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ provision:
3838
SocketUser={{.User}}
3939
EOF
4040
fi
41+
daemon_json="/etc/docker/daemon.json"
42+
if [ ! -f "${daemon_json}" ]; then
43+
mkdir -p "$(dirname "${daemon_json}")"
44+
cat > "${daemon_json}" <<EOF
45+
{
46+
"features": {
47+
"cdi": true
48+
}
49+
}
50+
EOF
51+
fi
4152
export DEBIAN_FRONTEND=noninteractive
4253
curl -fsSL https://get.docker.com | sh
4354
probes:

templates/docker.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ provision:
3939
script: |
4040
#!/bin/bash
4141
set -eux -o pipefail
42+
daemon_json="{{.Home}}/.config/docker/daemon.json"
43+
if [ ! -f "${daemon_json}" ]; then
44+
mkdir -p "$(dirname "${daemon_json}")"
45+
cat > "${daemon_json}" <<EOF
46+
{
47+
"features": {
48+
"cdi": true
49+
}
50+
}
51+
EOF
52+
fi
4253
systemctl --user start dbus
4354
dockerd-rootless-setuptool.sh install
4455
docker context use rootless

0 commit comments

Comments
 (0)