Compare commits

..

7 Commits

Author SHA1 Message Date
Jan Čermák
ec0f7c2b9c Use query_dns instead of deprecated query after aiohttp 4.x update (#6478) 2026-01-14 15:22:12 +01:00
Jan Čermák
753021d4d5 Fix 'DockerMount is not JSON serializable' in DockerAPI.run_command (#6477) 2026-01-14 15:21:11 +01:00
Erich Gubler
3e3db696d3 Fix typo in log message when running commands in a container (#6472) 2026-01-14 13:28:15 +01:00
dependabot[bot]
4d708d34c8 Bump aiodns from 3.6.1 to 4.0.0 (#6473)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-13 22:43:50 +01:00
dependabot[bot]
e7a0559692 Bump types-requests from 2.32.4.20250913 to 2.32.4.20260107 (#6464)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-13 22:00:46 +01:00
dependabot[bot]
9ad1bf0f1a Bump sentry-sdk from 2.48.0 to 2.49.0 (#6467)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-12 22:51:15 +01:00
dependabot[bot]
0f30e2cb43 Bump ruff from 0.14.10 to 0.14.11 (#6468)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-12 22:48:34 +01:00
9 changed files with 82 additions and 12 deletions

View File

@@ -1,4 +1,4 @@
aiodns==3.6.1
aiodns==4.0.0
aiodocker==0.24.0
aiohttp==3.13.3
atomicwrites-homeassistant==1.4.1
@@ -25,7 +25,7 @@ pyudev==0.24.4
PyYAML==6.0.3
requests==2.32.5
securetar==2025.12.0
sentry-sdk==2.48.0
sentry-sdk==2.49.0
setuptools==80.9.0
voluptuous==0.16.0
dbus-fast==3.1.2

View File

@@ -8,9 +8,9 @@ pytest-asyncio==1.3.0
pytest-cov==7.0.0
pytest-timeout==2.4.0
pytest==9.0.2
ruff==0.14.10
ruff==0.14.11
time-machine==3.2.0
types-docker==7.1.0.20260109
types-pyyaml==6.0.12.20250915
types-requests==2.32.4.20250913
types-requests==2.32.4.20260107
urllib3==2.6.3

View File

@@ -226,19 +226,19 @@ class DockerHomeAssistant(DockerInterface):
source=self.sys_config.path_extern_homeassistant.as_posix(),
target="/config",
read_only=False,
).to_dict(),
),
DockerMount(
type=MountType.BIND,
source=self.sys_config.path_extern_ssl.as_posix(),
target="/ssl",
read_only=True,
).to_dict(),
),
DockerMount(
type=MountType.BIND,
source=self.sys_config.path_extern_share.as_posix(),
target="/share",
read_only=False,
).to_dict(),
),
],
environment={ENV_TIME: self.sys_timezone},
)

View File

@@ -27,6 +27,7 @@ from docker.api.client import APIClient
from docker.client import DockerClient
from docker.models.containers import Container, ContainerCollection
from docker.models.networks import Network
from docker.types import Mount
from docker.types.daemon import CancellableStream
import requests
@@ -621,6 +622,8 @@ class DockerAPI(CoreSysAttributes):
image: str,
version: str = "latest",
command: str | list[str] | None = None,
*,
mounts: list[DockerMount] | None = None,
**kwargs: Any,
) -> CommandReturn:
"""Create a temporary container and run command.
@@ -632,7 +635,7 @@ class DockerAPI(CoreSysAttributes):
image_with_tag = f"{image}:{version}"
_LOGGER.info("Runing command '%s' on %s", command, image_with_tag)
_LOGGER.info("Running command '%s' on %s", command, image_with_tag)
container = None
try:
container = self.dockerpy.containers.run(
@@ -641,6 +644,11 @@ class DockerAPI(CoreSysAttributes):
detach=True,
network=self.network.name,
use_config_proxy=False,
mounts=(
[cast(Mount, mount.to_dict()) for mount in mounts]
if mounts
else None
),
**kwargs,
)

View File

@@ -22,7 +22,8 @@ async def check_server(
"""Check a DNS server and report issues."""
ip_addr = server[6:] if server.startswith("dns://") else server
async with DNSResolver(loop=loop, nameservers=[ip_addr]) as resolver:
await resolver.query(DNS_CHECK_HOST, qtype)
# following call should be changed to resolver.query() in aiodns 5.x
await resolver.query_dns(DNS_CHECK_HOST, qtype)
def setup(coresys: CoreSys) -> CheckBase:

View File

@@ -10,6 +10,7 @@ import pytest
from requests import RequestException
from supervisor.coresys import CoreSys
from supervisor.docker.const import DockerMount, MountBindOptions, MountType
from supervisor.docker.manager import CommandReturn, DockerAPI
from supervisor.exceptions import DockerError
@@ -43,6 +44,7 @@ async def test_run_command_success(docker: DockerAPI):
use_config_proxy=False,
stdout=True,
stderr=True,
mounts=None,
)
# Verify container cleanup
@@ -74,6 +76,7 @@ async def test_run_command_with_defaults(docker: DockerAPI):
detach=True,
network=docker.network.name,
use_config_proxy=False,
mounts=None,
)
# Verify container.logs was called with default stdout/stderr
@@ -140,6 +143,64 @@ async def test_run_command_custom_stdout_stderr(docker: DockerAPI):
assert result.output == b"output"
async def test_run_command_with_mounts(docker: DockerAPI):
"""Test command execution with mounts are correctly converted."""
# Mock container and its methods
mock_container = MagicMock()
mock_container.wait.return_value = {"StatusCode": 0}
mock_container.logs.return_value = b"output"
# Mock docker containers.run to return our mock container
docker.dockerpy.containers.run.return_value = mock_container
# Create test mounts
mounts = [
DockerMount(
type=MountType.BIND,
source="/dev",
target="/dev",
read_only=True,
bind_options=MountBindOptions(read_only_non_recursive=True),
),
DockerMount(
type=MountType.VOLUME,
source="my_volume",
target="/data",
read_only=False,
),
]
# Execute the command with mounts
result = docker.run_command(image="alpine", command="test", mounts=mounts)
# Verify the result
assert result.exit_code == 0
# Check that mounts were converted correctly
docker.dockerpy.containers.run.assert_called_once_with(
"alpine:latest",
command="test",
detach=True,
network=docker.network.name,
use_config_proxy=False,
mounts=[
{
"Type": "bind",
"Source": "/dev",
"Target": "/dev",
"ReadOnly": True,
"BindOptions": {"ReadOnlyNonRecursive": True},
},
{
"Type": "volume",
"Source": "my_volume",
"Target": "/data",
"ReadOnly": False,
},
],
)
@pytest.mark.usefixtures("path_extern", "tmp_supervisor_data")
async def test_run_container_with_cidfile(coresys: CoreSys, docker: DockerAPI):
"""Test container creation with cidfile and bind mount."""

View File

@@ -18,7 +18,7 @@ def fixture_mock_dns_query():
"""Mock aiodns query."""
with (
patch(
"supervisor.resolution.checks.dns_server.DNSResolver.query",
"supervisor.resolution.checks.dns_server.DNSResolver.query_dns",
new_callable=AsyncMock,
),
):

View File

@@ -15,7 +15,7 @@ from supervisor.resolution.const import ContextType, IssueType
async def fixture_dns_query() -> AsyncMock:
"""Mock aiodns query."""
with patch(
"supervisor.resolution.checks.dns_server.DNSResolver.query",
"supervisor.resolution.checks.dns_server.DNSResolver.query_dns",
new_callable=AsyncMock,
) as dns_query:
yield dns_query

View File

@@ -15,7 +15,7 @@ from supervisor.resolution.const import ContextType, IssueType
async def fixture_dns_query() -> AsyncMock:
"""Mock aiodns query."""
with patch(
"supervisor.resolution.checks.dns_server.DNSResolver.query",
"supervisor.resolution.checks.dns_server.DNSResolver.query_dns",
new_callable=AsyncMock,
) as dns_query:
yield dns_query