Skip to content

Commit

Permalink
Fix submounts of /dev being read-only with Docker 25+ (#4997)
Browse files Browse the repository at this point in the history
As described in #4996, Docker 25+ changes made sub-mounts of the /dev
filesystem to be mounted read-only. Revert to the previous behavior by
adjusting the ReadOnlyNonRecursive option. Cleaner way would be to
upstream support for setting this option via Mount class arguments, so
this change is meant to be rather a hotfix for the issue. Even better
approach would be mounting /dev non-recursively, and taking care of
creating all necessary filesystems when creating containers in
Supervisor.
  • Loading branch information
sairon committed Apr 2, 2024
1 parent a9265af commit 906e400
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 8 deletions.
1 change: 1 addition & 0 deletions supervisor/docker/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 5 additions & 0 deletions tests/docker/__init__.py
Original file line number Diff line number Diff line change
@@ -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}
8 changes: 3 additions & 5 deletions tests/docker/test_addon.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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 (
Expand Down
5 changes: 4 additions & 1 deletion tests/docker/test_audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand All @@ -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(),
Expand Down
6 changes: 4 additions & 2 deletions tests/docker/test_homeassistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down

0 comments on commit 906e400

Please sign in to comment.