mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-14 04:36:31 +00:00
Fix Supervisor logs fallback (#5022)
Supervisor logs fallback in get_supervisor_logs didn't work properly because the exception was caught in api_process_raw instead. This was not discovered in tests because the side effect raised OSError, which isn't handled there. To address that, I split the advanced_logs to two functions, one being a wrapped API handler, one being plain function returning response without any additional error handling. The tests now check for both cases of errors (HassioError and random generic Python error). Refs #5021
This commit is contained in:
parent
1246e429c9
commit
18d9d32bca
@ -401,7 +401,7 @@ class RestAPI(CoreSysAttributes):
|
|||||||
|
|
||||||
async def get_supervisor_logs(*args, **kwargs):
|
async def get_supervisor_logs(*args, **kwargs):
|
||||||
try:
|
try:
|
||||||
return await self._api_host.advanced_logs(
|
return await self._api_host.advanced_logs_handler(
|
||||||
*args, identifier="hassio_supervisor", **kwargs
|
*args, identifier="hassio_supervisor", **kwargs
|
||||||
)
|
)
|
||||||
except Exception as err: # pylint: disable=broad-exception-caught
|
except Exception as err: # pylint: disable=broad-exception-caught
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"""Init file for Supervisor host RESTful API."""
|
"""Init file for Supervisor host RESTful API."""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
import logging
|
import logging
|
||||||
@ -163,8 +164,7 @@ class APIHost(CoreSysAttributes):
|
|||||||
raise APIError() from err
|
raise APIError() from err
|
||||||
return possible_offset
|
return possible_offset
|
||||||
|
|
||||||
@api_process_raw(CONTENT_TYPE_TEXT, error_type=CONTENT_TYPE_TEXT)
|
async def advanced_logs_handler(
|
||||||
async def advanced_logs(
|
|
||||||
self, request: web.Request, identifier: str | None = None, follow: bool = False
|
self, request: web.Request, identifier: str | None = None, follow: bool = False
|
||||||
) -> web.StreamResponse:
|
) -> web.StreamResponse:
|
||||||
"""Return systemd-journald logs."""
|
"""Return systemd-journald logs."""
|
||||||
@ -218,3 +218,10 @@ class APIHost(CoreSysAttributes):
|
|||||||
"Connection reset when trying to fetch data from systemd-journald."
|
"Connection reset when trying to fetch data from systemd-journald."
|
||||||
) from ex
|
) from ex
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
@api_process_raw(CONTENT_TYPE_TEXT, error_type=CONTENT_TYPE_TEXT)
|
||||||
|
async def advanced_logs(
|
||||||
|
self, request: web.Request, identifier: str | None = None, follow: bool = False
|
||||||
|
) -> web.StreamResponse:
|
||||||
|
"""Return systemd-journald logs. Wrapped as standard API handler."""
|
||||||
|
return await self.advanced_logs_handler(request, identifier, follow)
|
||||||
|
@ -6,7 +6,7 @@ from aiohttp.test_utils import TestClient
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from supervisor.coresys import CoreSys
|
from supervisor.coresys import CoreSys
|
||||||
from supervisor.exceptions import StoreGitError, StoreNotFound
|
from supervisor.exceptions import HassioError, StoreGitError, StoreNotFound
|
||||||
from supervisor.store.repository import Repository
|
from supervisor.store.repository import Repository
|
||||||
|
|
||||||
from tests.api import common_test_api_advanced_logs
|
from tests.api import common_test_api_advanced_logs
|
||||||
@ -160,7 +160,7 @@ async def test_api_supervisor_fallback(
|
|||||||
api_client: TestClient, journald_logs: MagicMock, docker_logs: MagicMock
|
api_client: TestClient, journald_logs: MagicMock, docker_logs: MagicMock
|
||||||
):
|
):
|
||||||
"""Check that supervisor logs read from container logs if reading from journald gateway fails badly."""
|
"""Check that supervisor logs read from container logs if reading from journald gateway fails badly."""
|
||||||
journald_logs.side_effect = OSError("Something bad happened!")
|
journald_logs.side_effect = HassioError("Something bad happened!")
|
||||||
|
|
||||||
with patch("supervisor.api._LOGGER.exception") as logger:
|
with patch("supervisor.api._LOGGER.exception") as logger:
|
||||||
resp = await api_client.get("/supervisor/logs")
|
resp = await api_client.get("/supervisor/logs")
|
||||||
@ -176,6 +176,19 @@ async def test_api_supervisor_fallback(
|
|||||||
b"\x1b[36m22-10-11 14:04:23 DEBUG (MainThread) [supervisor.utils.dbus] D-Bus call - org.freedesktop.DBus.Properties.call_get_all on /io/hass/os/AppArmor\x1b[0m",
|
b"\x1b[36m22-10-11 14:04:23 DEBUG (MainThread) [supervisor.utils.dbus] D-Bus call - org.freedesktop.DBus.Properties.call_get_all on /io/hass/os/AppArmor\x1b[0m",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
journald_logs.reset_mock()
|
||||||
|
|
||||||
|
# also check generic Python error
|
||||||
|
journald_logs.side_effect = OSError("Something bad happened!")
|
||||||
|
|
||||||
|
with patch("supervisor.api._LOGGER.exception") as logger:
|
||||||
|
resp = await api_client.get("/supervisor/logs")
|
||||||
|
logger.assert_called_once_with(
|
||||||
|
"Failed to get supervisor logs using advanced_logs API"
|
||||||
|
)
|
||||||
|
assert resp.status == 200
|
||||||
|
assert resp.content_type == "text/plain"
|
||||||
|
|
||||||
|
|
||||||
async def test_api_supervisor_reload(api_client: TestClient):
|
async def test_api_supervisor_reload(api_client: TestClient):
|
||||||
"""Test supervisor reload."""
|
"""Test supervisor reload."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user