diff --git a/supervisor/docker/const.py b/supervisor/docker/const.py index 2a9740586e1..cb9a34e4f83 100644 --- a/supervisor/docker/const.py +++ b/supervisor/docker/const.py @@ -74,6 +74,7 @@ class PropagationMode(StrEnum): type=MountType.BIND, source="/run/dbus", target="/run/dbus", read_only=True ) MOUNT_DEV = Mount(type=MountType.BIND, source="/dev", target="/dev", read_only=True) +MOUNT_DEV.setdefault("BindOptions", {})["ReadOnlyNonRecursive"] = True MOUNT_DOCKER = Mount( type=MountType.BIND, source="/run/docker.sock", diff --git a/tests/docker/__init__.py b/tests/docker/__init__.py index 65ac125c1ac..6437e7cf515 100644 --- a/tests/docker/__init__.py +++ b/tests/docker/__init__.py @@ -1 +1,6 @@ """Docker tests.""" +from docker.types import Mount + +# dev mount with equivalent of bind-recursive=writable specified via dict value +DEV_MOUNT = Mount(type="bind", source="/dev", target="/dev", read_only=True) +DEV_MOUNT["BindOptions"] = {"ReadOnlyNonRecursive": True} diff --git a/tests/docker/test_addon.py b/tests/docker/test_addon.py index f9a52aa6825..3f18524db52 100644 --- a/tests/docker/test_addon.py +++ b/tests/docker/test_addon.py @@ -19,6 +19,7 @@ from supervisor.resolution.data import Issue from ..common import load_json_fixture +from . import DEV_MOUNT @pytest.fixture(name="addonsdata_system") @@ -66,11 +67,8 @@ def test_base_volumes_included( coresys, addonsdata_system, "basic-addon-config.json" ) - # Dev added as ro - assert ( - Mount(type="bind", source="/dev", target="/dev", read_only=True) - in docker_addon.mounts - ) + # Dev added as ro with bind-recursive=writable option + assert DEV_MOUNT in docker_addon.mounts # Data added as rw assert ( diff --git a/tests/docker/test_audio.py b/tests/docker/test_audio.py index 0b3e23b974d..9f8c0c3c7ce 100644 --- a/tests/docker/test_audio.py +++ b/tests/docker/test_audio.py @@ -9,6 +9,8 @@ from supervisor.coresys import CoreSys from supervisor.docker.manager import DockerAPI +from . import DEV_MOUNT + async def test_start(coresys: CoreSys, tmp_supervisor_data: Path, path_extern): """Test starting audio plugin.""" @@ -26,8 +28,9 @@ async def test_start(coresys: CoreSys, tmp_supervisor_data: Path, path_extern): assert run.call_args.kwargs["ulimits"] == [ {"Name": "rtprio", "Soft": 10, "Hard": 10} ] + assert run.call_args.kwargs["mounts"] == [ - Mount(type="bind", source="/dev", target="/dev", read_only=True), + DEV_MOUNT, Mount( type="bind", source=coresys.config.path_extern_audio.as_posix(), diff --git a/tests/docker/test_homeassistant.py b/tests/docker/test_homeassistant.py index 97968369cbf..02fd2fe42a3 100644 --- a/tests/docker/test_homeassistant.py +++ b/tests/docker/test_homeassistant.py @@ -12,6 +12,8 @@ from supervisor.docker.manager import DockerAPI from supervisor.homeassistant.const import LANDINGPAGE +from . import DEV_MOUNT + async def test_homeassistant_start( coresys: CoreSys, tmp_supervisor_data: Path, path_extern @@ -42,7 +44,7 @@ async def test_homeassistant_start( "HASSIO_TOKEN": ANY, } assert run.call_args.kwargs["mounts"] == [ - Mount(type="bind", source="/dev", target="/dev", read_only=True), + DEV_MOUNT, Mount(type="bind", source="/run/dbus", target="/run/dbus", read_only=True), Mount(type="bind", source="/run/udev", target="/run/udev", read_only=True), Mount( @@ -128,7 +130,7 @@ async def test_landingpage_start( "HASSIO_TOKEN": ANY, } assert run.call_args.kwargs["mounts"] == [ - Mount(type="bind", source="/dev", target="/dev", read_only=True), + DEV_MOUNT, Mount(type="bind", source="/run/dbus", target="/run/dbus", read_only=True), Mount(type="bind", source="/run/udev", target="/run/udev", read_only=True), Mount(