Files
supervisor/tests/dbus/agent/test_system.py
T
Jan Čermák 68ed3b5dec Add endpoint to reset Docker storage (#7166)
* Add endpoint to reset Docker storage

Corrupted Docker image layers cannot be always fixed by removing and
re-pulling a single image, because layers are shared between images. The
only (easy) way to recover is wiping all of Docker's storage which is
currently cumbersome and requires OS shell access.

Home Assistant OS added a service that performs the Docker storage wipe
on boot when a flag file exists in home-assistant/operating-system#4982,
and home-assistant/os-agent#283 adds OS Agent DBus interface for
creating that file.

This adds a new API method POST /docker/reset-storage which calls OS
Agent's ScheduleDockerStorageReset and creates a reboot_required issue,
following the same pattern used for the Docker storage driver migration.

This is expected to ship in HAOS 18.3, so the endpoint checks for that
and returns 404 on older OS versions. Technically, it might be nicer to
gate on OS Agent version, but from user perspective it's better to
report the required OS version.

Refs #6555

* Add const for minimum OS version supporting the reset
2026-08-27 12:53:16 +02:00

92 lines
3.0 KiB
Python

"""Test System/Agent dbus interface."""
from dbus_fast.aio.message_bus import MessageBus
import pytest
from supervisor.dbus.agent import OSAgent
from supervisor.exceptions import DBusNotConnectedError
from tests.dbus_service_mocks.agent_system import System as SystemService
from tests.dbus_service_mocks.base import DBusServiceMock
@pytest.fixture(name="system_service", autouse=True)
async def fixture_system_service(
os_agent_services: dict[str, DBusServiceMock],
) -> SystemService:
"""Mock System dbus service."""
return os_agent_services["agent_system"]
async def test_dbus_osagent_system_wipe(
system_service: SystemService, dbus_session_bus: MessageBus
):
"""Test wipe data partition on host."""
system_service.ScheduleWipeDevice.calls.clear()
os_agent = OSAgent()
with pytest.raises(DBusNotConnectedError):
await os_agent.system.schedule_wipe_device()
await os_agent.connect(dbus_session_bus)
assert await os_agent.system.schedule_wipe_device() is True
assert system_service.ScheduleWipeDevice.calls == [()]
async def test_dbus_osagent_system_schedule_docker_storage_reset(
system_service: SystemService, dbus_session_bus: MessageBus
):
"""Test scheduling Docker storage reset on host."""
system_service.ScheduleDockerStorageReset.calls.clear()
os_agent = OSAgent()
with pytest.raises(DBusNotConnectedError):
await os_agent.system.schedule_docker_storage_reset()
await os_agent.connect(dbus_session_bus)
assert await os_agent.system.schedule_docker_storage_reset() is True
assert system_service.ScheduleDockerStorageReset.calls == [()]
async def test_dbus_osagent_system_ssh_auth_keys(
system_service: SystemService, dbus_session_bus: MessageBus
):
"""Test add and clear of SSH authorized keys on host."""
system_service.AddSSHAuthKey.calls.clear()
system_service.ClearSSHAuthKeys.calls.clear()
os_agent = OSAgent()
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDXD8u9KB94/l1YukYflKOsO7KzoSEQD4dNNlWY9zaQP test@example.com"
with pytest.raises(DBusNotConnectedError):
await os_agent.system.add_ssh_auth_key(key)
with pytest.raises(DBusNotConnectedError):
await os_agent.system.clear_ssh_auth_keys()
await os_agent.connect(dbus_session_bus)
await os_agent.system.clear_ssh_auth_keys()
await os_agent.system.add_ssh_auth_key(key)
assert system_service.ClearSSHAuthKeys.calls == [()]
assert system_service.AddSSHAuthKey.calls == [(key,)]
async def test_dbus_osagent_system_list_ssh_auth_keys(
system_service: SystemService, dbus_session_bus: MessageBus
):
"""Test listing SSH authorized keys on host."""
system_service.response_list_ssh_auth_keys = ["ssh-ed25519 AAAA test@example.com"]
os_agent = OSAgent()
with pytest.raises(DBusNotConnectedError):
await os_agent.system.list_ssh_auth_keys()
await os_agent.connect(dbus_session_bus)
assert await os_agent.system.list_ssh_auth_keys() == [
"ssh-ed25519 AAAA test@example.com"
]