mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-19 15:16:33 +00:00
Fix submounts of /dev being read-only with Docker 25+ (#4997)
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.
This commit is contained in:
parent
a9265afd4c
commit
906e400ab7
@ -74,6 +74,7 @@ MOUNT_DBUS = Mount(
|
|||||||
type=MountType.BIND, source="/run/dbus", target="/run/dbus", read_only=True
|
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 = Mount(type=MountType.BIND, source="/dev", target="/dev", read_only=True)
|
||||||
|
MOUNT_DEV.setdefault("BindOptions", {})["ReadOnlyNonRecursive"] = True
|
||||||
MOUNT_DOCKER = Mount(
|
MOUNT_DOCKER = Mount(
|
||||||
type=MountType.BIND,
|
type=MountType.BIND,
|
||||||
source="/run/docker.sock",
|
source="/run/docker.sock",
|
||||||
|
@ -1 +1,6 @@
|
|||||||
"""Docker tests."""
|
"""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}
|
||||||
|
@ -19,6 +19,7 @@ from supervisor.resolution.const import ContextType, IssueType
|
|||||||
from supervisor.resolution.data import Issue
|
from supervisor.resolution.data import Issue
|
||||||
|
|
||||||
from ..common import load_json_fixture
|
from ..common import load_json_fixture
|
||||||
|
from . import DEV_MOUNT
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="addonsdata_system")
|
@pytest.fixture(name="addonsdata_system")
|
||||||
@ -66,11 +67,8 @@ def test_base_volumes_included(
|
|||||||
coresys, addonsdata_system, "basic-addon-config.json"
|
coresys, addonsdata_system, "basic-addon-config.json"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Dev added as ro
|
# Dev added as ro with bind-recursive=writable option
|
||||||
assert (
|
assert DEV_MOUNT in docker_addon.mounts
|
||||||
Mount(type="bind", source="/dev", target="/dev", read_only=True)
|
|
||||||
in docker_addon.mounts
|
|
||||||
)
|
|
||||||
|
|
||||||
# Data added as rw
|
# Data added as rw
|
||||||
assert (
|
assert (
|
||||||
|
@ -9,6 +9,8 @@ from docker.types import Mount
|
|||||||
from supervisor.coresys import CoreSys
|
from supervisor.coresys import CoreSys
|
||||||
from supervisor.docker.manager import DockerAPI
|
from supervisor.docker.manager import DockerAPI
|
||||||
|
|
||||||
|
from . import DEV_MOUNT
|
||||||
|
|
||||||
|
|
||||||
async def test_start(coresys: CoreSys, tmp_supervisor_data: Path, path_extern):
|
async def test_start(coresys: CoreSys, tmp_supervisor_data: Path, path_extern):
|
||||||
"""Test starting audio plugin."""
|
"""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"] == [
|
assert run.call_args.kwargs["ulimits"] == [
|
||||||
{"Name": "rtprio", "Soft": 10, "Hard": 10}
|
{"Name": "rtprio", "Soft": 10, "Hard": 10}
|
||||||
]
|
]
|
||||||
|
|
||||||
assert run.call_args.kwargs["mounts"] == [
|
assert run.call_args.kwargs["mounts"] == [
|
||||||
Mount(type="bind", source="/dev", target="/dev", read_only=True),
|
DEV_MOUNT,
|
||||||
Mount(
|
Mount(
|
||||||
type="bind",
|
type="bind",
|
||||||
source=coresys.config.path_extern_audio.as_posix(),
|
source=coresys.config.path_extern_audio.as_posix(),
|
||||||
|
@ -12,6 +12,8 @@ from supervisor.docker.homeassistant import DockerHomeAssistant
|
|||||||
from supervisor.docker.manager import DockerAPI
|
from supervisor.docker.manager import DockerAPI
|
||||||
from supervisor.homeassistant.const import LANDINGPAGE
|
from supervisor.homeassistant.const import LANDINGPAGE
|
||||||
|
|
||||||
|
from . import DEV_MOUNT
|
||||||
|
|
||||||
|
|
||||||
async def test_homeassistant_start(
|
async def test_homeassistant_start(
|
||||||
coresys: CoreSys, tmp_supervisor_data: Path, path_extern
|
coresys: CoreSys, tmp_supervisor_data: Path, path_extern
|
||||||
@ -42,7 +44,7 @@ async def test_homeassistant_start(
|
|||||||
"HASSIO_TOKEN": ANY,
|
"HASSIO_TOKEN": ANY,
|
||||||
}
|
}
|
||||||
assert run.call_args.kwargs["mounts"] == [
|
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/dbus", target="/run/dbus", read_only=True),
|
||||||
Mount(type="bind", source="/run/udev", target="/run/udev", read_only=True),
|
Mount(type="bind", source="/run/udev", target="/run/udev", read_only=True),
|
||||||
Mount(
|
Mount(
|
||||||
@ -128,7 +130,7 @@ async def test_landingpage_start(
|
|||||||
"HASSIO_TOKEN": ANY,
|
"HASSIO_TOKEN": ANY,
|
||||||
}
|
}
|
||||||
assert run.call_args.kwargs["mounts"] == [
|
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/dbus", target="/run/dbus", read_only=True),
|
||||||
Mount(type="bind", source="/run/udev", target="/run/udev", read_only=True),
|
Mount(type="bind", source="/run/udev", target="/run/udev", read_only=True),
|
||||||
Mount(
|
Mount(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user