diff --git a/rock/deployments/docker.py b/rock/deployments/docker.py index a0262bdf33..fb1da33ce7 100644 --- a/rock/deployments/docker.py +++ b/rock/deployments/docker.py @@ -180,6 +180,8 @@ def _build_runtime_args(self) -> list[str]: if self._config.use_kata_runtime: return [ "--cap-add=ALL", + "--device-cgroup-rule", + "c 10:232 rwm", "--security-opt", "seccomp=unconfined", "--runtime=io.containerd.kata.v2", diff --git a/rock/rocklet/local_files/docker_run.sh b/rock/rocklet/local_files/docker_run.sh index cc7e1a1977..2bac89a20e 100755 --- a/rock/rocklet/local_files/docker_run.sh +++ b/rock/rocklet/local_files/docker_run.sh @@ -28,6 +28,27 @@ is_nix() { fi } +# Kata guest KVM is a misc character device. Its number belongs to the guest +# kernel and can differ from the outer host's /dev/kvm device number. +setup_kata_guest_kvm() { + local kvm_major=10 + local kvm_minor=232 + local registered_minor + + if [ ! -r /proc/misc ]; then + echo "Kata guest KVM setup failed: /proc/misc is unavailable." >&2 + return 1 + fi + registered_minor=$(awk '$2 == "kvm" { print $1; exit }' /proc/misc) + if [ "${registered_minor}" != "${kvm_minor}" ]; then + echo "Kata guest KVM setup failed: expected misc device ${kvm_major}:${kvm_minor}, found minor ${registered_minor:-none}." >&2 + return 1 + fi + + rm -f /dev/kvm + mknod -m 600 /dev/kvm c "${kvm_major}" "${kvm_minor}" +} + # Kata DinD: set up loop device and mount disk image for Docker storage setup_kata_dind() { local docker_root="/var/lib/docker" @@ -79,7 +100,10 @@ if [ "$(is_nix)" = "true" ]; then fi if [ "${ROCK_KATA_RUNTIME}" = "true" ]; then - echo "Kata runtime detected, setting up DinD disk..." + echo "Kata runtime detected, setting up guest KVM and DinD disk..." + if ! setup_kata_guest_kvm; then + echo "WARNING: Kata guest KVM setup failed; continuing without /dev/kvm." >&2 + fi setup_kata_dind fi diff --git a/tests/unit/deployments/test_docker_env_injection.py b/tests/unit/deployments/test_docker_env_injection.py index 59c6e86166..3ebd2ea4e5 100644 --- a/tests/unit/deployments/test_docker_env_injection.py +++ b/tests/unit/deployments/test_docker_env_injection.py @@ -99,3 +99,22 @@ def test_kata_runtime_env_absent_when_disabled(self): mock_env.ROCK_TIME_ZONE = "UTC" args = deployment._build_env_args() assert "ROCK_KATA_RUNTIME=true" not in args + + +class TestBuildRuntimeArgs: + def test_kata_runtime_grants_guest_kvm_device_number(self): + deployment = _make_deployment(use_kata_runtime=True) + + args = deployment._build_runtime_args() + + rule_index = args.index("--device-cgroup-rule") + assert args[rule_index + 1] == "c 10:232 rwm" + assert "--device=/dev/kvm" not in args + + def test_default_runtime_does_not_grant_guest_kvm_device(self): + deployment = _make_deployment(use_kata_runtime=False) + + args = deployment._build_runtime_args() + + assert args == ["--privileged"] + assert "--device-cgroup-rule" not in args