mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-15 21:26:29 +00:00
Skip unnecessary mounts and privileges for landingpage (#4518)
* Skip unnecessary mounts for landingpage * Remove privileged and cgroup rules from landingpage
This commit is contained in:
parent
6adb4fbcf7
commit
f30d21361f
@ -66,10 +66,14 @@ class DockerHomeAssistant(DockerInterface):
|
||||
def cgroups_rules(self) -> list[str]:
|
||||
"""Return a list of needed cgroups permission."""
|
||||
return (
|
||||
self.sys_hardware.policy.get_cgroups_rules(PolicyGroup.UART)
|
||||
+ self.sys_hardware.policy.get_cgroups_rules(PolicyGroup.VIDEO)
|
||||
+ self.sys_hardware.policy.get_cgroups_rules(PolicyGroup.GPIO)
|
||||
+ self.sys_hardware.policy.get_cgroups_rules(PolicyGroup.USB)
|
||||
[]
|
||||
if self.sys_homeassistant.version == LANDINGPAGE
|
||||
else (
|
||||
self.sys_hardware.policy.get_cgroups_rules(PolicyGroup.UART)
|
||||
+ self.sys_hardware.policy.get_cgroups_rules(PolicyGroup.VIDEO)
|
||||
+ self.sys_hardware.policy.get_cgroups_rules(PolicyGroup.GPIO)
|
||||
+ self.sys_hardware.policy.get_cgroups_rules(PolicyGroup.USB)
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
@ -79,54 +83,62 @@ class DockerHomeAssistant(DockerInterface):
|
||||
MOUNT_DEV,
|
||||
MOUNT_DBUS,
|
||||
MOUNT_UDEV,
|
||||
# Add folders
|
||||
# HA config folder
|
||||
Mount(
|
||||
type=MountType.BIND.value,
|
||||
source=self.sys_config.path_extern_homeassistant.as_posix(),
|
||||
target="/config",
|
||||
read_only=False,
|
||||
),
|
||||
Mount(
|
||||
type=MountType.BIND.value,
|
||||
source=self.sys_config.path_extern_ssl.as_posix(),
|
||||
target="/ssl",
|
||||
read_only=True,
|
||||
),
|
||||
Mount(
|
||||
type=MountType.BIND.value,
|
||||
source=self.sys_config.path_extern_share.as_posix(),
|
||||
target="/share",
|
||||
read_only=False,
|
||||
propagation=PropagationMode.RSLAVE.value,
|
||||
),
|
||||
Mount(
|
||||
type=MountType.BIND.value,
|
||||
source=self.sys_config.path_extern_media.as_posix(),
|
||||
target="/media",
|
||||
read_only=False,
|
||||
propagation=PropagationMode.RSLAVE.value,
|
||||
),
|
||||
# Configuration audio
|
||||
Mount(
|
||||
type=MountType.BIND.value,
|
||||
source=self.sys_homeassistant.path_extern_pulse.as_posix(),
|
||||
target="/etc/pulse/client.conf",
|
||||
read_only=True,
|
||||
),
|
||||
Mount(
|
||||
type=MountType.BIND.value,
|
||||
source=self.sys_plugins.audio.path_extern_pulse.as_posix(),
|
||||
target="/run/audio",
|
||||
read_only=True,
|
||||
),
|
||||
Mount(
|
||||
type=MountType.BIND.value,
|
||||
source=self.sys_plugins.audio.path_extern_asound.as_posix(),
|
||||
target="/etc/asound.conf",
|
||||
read_only=True,
|
||||
),
|
||||
]
|
||||
|
||||
# Landingpage does not need all this access
|
||||
if self.sys_homeassistant.version != LANDINGPAGE:
|
||||
mounts.extend(
|
||||
[
|
||||
# All other folders
|
||||
Mount(
|
||||
type=MountType.BIND.value,
|
||||
source=self.sys_config.path_extern_ssl.as_posix(),
|
||||
target="/ssl",
|
||||
read_only=True,
|
||||
),
|
||||
Mount(
|
||||
type=MountType.BIND.value,
|
||||
source=self.sys_config.path_extern_share.as_posix(),
|
||||
target="/share",
|
||||
read_only=False,
|
||||
propagation=PropagationMode.RSLAVE.value,
|
||||
),
|
||||
Mount(
|
||||
type=MountType.BIND.value,
|
||||
source=self.sys_config.path_extern_media.as_posix(),
|
||||
target="/media",
|
||||
read_only=False,
|
||||
propagation=PropagationMode.RSLAVE.value,
|
||||
),
|
||||
# Configuration audio
|
||||
Mount(
|
||||
type=MountType.BIND.value,
|
||||
source=self.sys_homeassistant.path_extern_pulse.as_posix(),
|
||||
target="/etc/pulse/client.conf",
|
||||
read_only=True,
|
||||
),
|
||||
Mount(
|
||||
type=MountType.BIND.value,
|
||||
source=self.sys_plugins.audio.path_extern_pulse.as_posix(),
|
||||
target="/run/audio",
|
||||
read_only=True,
|
||||
),
|
||||
Mount(
|
||||
type=MountType.BIND.value,
|
||||
source=self.sys_plugins.audio.path_extern_asound.as_posix(),
|
||||
target="/etc/asound.conf",
|
||||
read_only=True,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
# Machine ID
|
||||
if MACHINE_ID.exists():
|
||||
mounts.append(MOUNT_MACHINE_ID)
|
||||
@ -154,7 +166,7 @@ class DockerHomeAssistant(DockerInterface):
|
||||
name=self.name,
|
||||
hostname=self.name,
|
||||
detach=True,
|
||||
privileged=True,
|
||||
privileged=self.sys_homeassistant.version != LANDINGPAGE,
|
||||
init=False,
|
||||
security_opt=self.security_opt,
|
||||
network_mode="host",
|
||||
|
147
tests/docker/test_homeassistant.py
Normal file
147
tests/docker/test_homeassistant.py
Normal file
@ -0,0 +1,147 @@
|
||||
"""Test Home Assistant container."""
|
||||
|
||||
from ipaddress import IPv4Address
|
||||
from pathlib import Path
|
||||
from unittest.mock import ANY, patch
|
||||
|
||||
from awesomeversion import AwesomeVersion
|
||||
from docker.types import Mount
|
||||
|
||||
from supervisor.coresys import CoreSys
|
||||
from supervisor.docker.homeassistant import DockerHomeAssistant
|
||||
from supervisor.docker.manager import DockerAPI
|
||||
from supervisor.homeassistant.const import LANDINGPAGE
|
||||
|
||||
|
||||
async def test_homeassistant_start(
|
||||
coresys: CoreSys, tmp_supervisor_data: Path, path_extern
|
||||
):
|
||||
"""Test starting homeassistant."""
|
||||
coresys.homeassistant.version = AwesomeVersion("2023.8.1")
|
||||
|
||||
with patch.object(DockerAPI, "run") as run, patch.object(
|
||||
DockerHomeAssistant, "is_running", side_effect=[False, False, True]
|
||||
), patch("supervisor.homeassistant.core.asyncio.sleep"):
|
||||
await coresys.homeassistant.core.start()
|
||||
|
||||
run.assert_called_once()
|
||||
assert run.call_args.kwargs["name"] == "homeassistant"
|
||||
assert run.call_args.kwargs["hostname"] == "homeassistant"
|
||||
assert run.call_args.kwargs["privileged"] is True
|
||||
assert run.call_args.kwargs["oom_score_adj"] == -300
|
||||
assert run.call_args.kwargs["device_cgroup_rules"]
|
||||
assert run.call_args.kwargs["extra_hosts"] == {
|
||||
"supervisor": IPv4Address("172.30.32.2"),
|
||||
"observer": IPv4Address("172.30.32.6"),
|
||||
}
|
||||
assert run.call_args.kwargs["environment"] == {
|
||||
"SUPERVISOR": IPv4Address("172.30.32.2"),
|
||||
"HASSIO": IPv4Address("172.30.32.2"),
|
||||
"TZ": ANY,
|
||||
"SUPERVISOR_TOKEN": ANY,
|
||||
"HASSIO_TOKEN": ANY,
|
||||
}
|
||||
assert run.call_args.kwargs["mounts"] == [
|
||||
Mount(type="bind", source="/dev", target="/dev", 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=coresys.config.path_extern_homeassistant.as_posix(),
|
||||
target="/config",
|
||||
read_only=False,
|
||||
),
|
||||
Mount(
|
||||
type="bind",
|
||||
source=coresys.config.path_extern_ssl.as_posix(),
|
||||
target="/ssl",
|
||||
read_only=True,
|
||||
),
|
||||
Mount(
|
||||
type="bind",
|
||||
source=coresys.config.path_extern_share.as_posix(),
|
||||
target="/share",
|
||||
read_only=False,
|
||||
propagation="rslave",
|
||||
),
|
||||
Mount(
|
||||
type="bind",
|
||||
source=coresys.config.path_extern_media.as_posix(),
|
||||
target="/media",
|
||||
read_only=False,
|
||||
propagation="rslave",
|
||||
),
|
||||
Mount(
|
||||
type="bind",
|
||||
source=coresys.homeassistant.path_extern_pulse.as_posix(),
|
||||
target="/etc/pulse/client.conf",
|
||||
read_only=True,
|
||||
),
|
||||
Mount(
|
||||
type="bind",
|
||||
source=coresys.plugins.audio.path_extern_pulse.as_posix(),
|
||||
target="/run/audio",
|
||||
read_only=True,
|
||||
),
|
||||
Mount(
|
||||
type="bind",
|
||||
source=coresys.plugins.audio.path_extern_asound.as_posix(),
|
||||
target="/etc/asound.conf",
|
||||
read_only=True,
|
||||
),
|
||||
Mount(
|
||||
type="bind",
|
||||
source="/etc/machine-id",
|
||||
target="/etc/machine-id",
|
||||
read_only=True,
|
||||
),
|
||||
]
|
||||
assert "volumes" not in run.call_args.kwargs
|
||||
|
||||
|
||||
async def test_landingpage_start(
|
||||
coresys: CoreSys, tmp_supervisor_data: Path, path_extern
|
||||
):
|
||||
"""Test starting landingpage."""
|
||||
coresys.homeassistant.version = LANDINGPAGE
|
||||
|
||||
with patch.object(DockerAPI, "run") as run, patch.object(
|
||||
DockerHomeAssistant, "is_running", return_value=False
|
||||
):
|
||||
await coresys.homeassistant.core.start()
|
||||
|
||||
run.assert_called_once()
|
||||
assert run.call_args.kwargs["name"] == "homeassistant"
|
||||
assert run.call_args.kwargs["hostname"] == "homeassistant"
|
||||
assert run.call_args.kwargs["privileged"] is False
|
||||
assert run.call_args.kwargs["oom_score_adj"] == -300
|
||||
assert not run.call_args.kwargs["device_cgroup_rules"]
|
||||
assert run.call_args.kwargs["extra_hosts"] == {
|
||||
"supervisor": IPv4Address("172.30.32.2"),
|
||||
"observer": IPv4Address("172.30.32.6"),
|
||||
}
|
||||
assert run.call_args.kwargs["environment"] == {
|
||||
"SUPERVISOR": IPv4Address("172.30.32.2"),
|
||||
"HASSIO": IPv4Address("172.30.32.2"),
|
||||
"TZ": ANY,
|
||||
"SUPERVISOR_TOKEN": ANY,
|
||||
"HASSIO_TOKEN": ANY,
|
||||
}
|
||||
assert run.call_args.kwargs["mounts"] == [
|
||||
Mount(type="bind", source="/dev", target="/dev", 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=coresys.config.path_extern_homeassistant.as_posix(),
|
||||
target="/config",
|
||||
read_only=False,
|
||||
),
|
||||
Mount(
|
||||
type="bind",
|
||||
source="/etc/machine-id",
|
||||
target="/etc/machine-id",
|
||||
read_only=True,
|
||||
),
|
||||
]
|
||||
assert "volumes" not in run.call_args.kwargs
|
Loading…
x
Reference in New Issue
Block a user