Compare commits

..

8 Commits

Author SHA1 Message Date
dependabot[bot]
9c99bf368f Bump actions/cache from 4.1.1 to 4.1.2 (#5366)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 08:40:18 +02:00
Jan Čermák
6f196c9dea Suppress ClientConnectionResetError when returning logs (#5358)
When client requests (or more often follows) some busy logs and closes
the connection while the StreamWriter tries to write into it, an
exception is raised. This should be harmless, and unless there's another
way to handle this gracefully (I'm not aware of), then it should be safe
to ignore the exception in this context.
2024-10-21 10:11:22 +02:00
dependabot[bot]
fcac17f335 Bump coverage from 7.6.3 to 7.6.4 (#5365)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 09:04:55 +02:00
dependabot[bot]
f5a026cdd8 Bump cryptography from 43.0.1 to 43.0.3 (#5364)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 09:02:50 +02:00
dependabot[bot]
c6488c1ee3 Bump ruff from 0.6.9 to 0.7.0 (#5359)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-18 08:41:51 +02:00
dependabot[bot]
f47d0d2867 Bump sentry-sdk from 2.16.0 to 2.17.0 (#5360)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-18 08:39:06 +02:00
dependabot[bot]
96df335b36 Bump setuptools from 75.1.0 to 75.2.0 (#5357)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-17 08:29:15 +02:00
Jan Čermák
cc9a931baa Fix Supervisor log fallback for the /follow endpoint (#5354)
When an error occurs when streaming Supervisor logs, the fallback method
receives the follow kwarg as well, which is invalid for the Docker log
handler:

 TypeError: APISupervisor.logs() got an unexpected keyword argument 'follow'

The exception is still printed to the logs but with all the extra noise
caused by this error. Removing the argument makes the stack trace more
comprehensible and the fallback actually works as desired.
2024-10-16 09:04:24 +02:00
10 changed files with 35 additions and 73 deletions

View File

@@ -33,7 +33,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: venv
key: |
@@ -47,7 +47,7 @@ jobs:
pip install -r requirements.txt -r requirements_tests.txt
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: ${{ env.PRE_COMMIT_CACHE }}
lookup-only: true
@@ -75,7 +75,7 @@ jobs:
python-version: ${{ needs.prepare.outputs.python-version }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: venv
key: |
@@ -87,7 +87,7 @@ jobs:
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: ${{ env.PRE_COMMIT_CACHE }}
key: |
@@ -118,7 +118,7 @@ jobs:
python-version: ${{ needs.prepare.outputs.python-version }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: venv
key: |
@@ -130,7 +130,7 @@ jobs:
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: ${{ env.PRE_COMMIT_CACHE }}
key: |
@@ -176,7 +176,7 @@ jobs:
python-version: ${{ needs.prepare.outputs.python-version }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: venv
key: |
@@ -188,7 +188,7 @@ jobs:
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: ${{ env.PRE_COMMIT_CACHE }}
key: |
@@ -220,7 +220,7 @@ jobs:
python-version: ${{ needs.prepare.outputs.python-version }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: venv
key: |
@@ -232,7 +232,7 @@ jobs:
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: ${{ env.PRE_COMMIT_CACHE }}
key: |
@@ -264,7 +264,7 @@ jobs:
python-version: ${{ needs.prepare.outputs.python-version }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: venv
key: |
@@ -300,7 +300,7 @@ jobs:
cosign-release: "v2.4.0"
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: venv
key: |
@@ -355,7 +355,7 @@ jobs:
python-version: ${{ needs.prepare.outputs.python-version }}
- name: Restore Python virtual environment
id: cache-venv
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: venv
key: |

View File

@@ -7,7 +7,7 @@ brotli==1.1.0
ciso8601==2.3.1
colorlog==6.8.2
cpe==1.3.1
cryptography==43.0.1
cryptography==43.0.3
debugpy==1.8.7
deepmerge==2.0
dirhash==0.5.0
@@ -21,8 +21,8 @@ pyudev==0.24.3
PyYAML==6.0.2
requests==2.32.3
securetar==2024.2.1
sentry-sdk==2.16.0
setuptools==75.1.0
sentry-sdk==2.17.0
setuptools==75.2.0
voluptuous==0.15.2
dbus-fast==2.24.3
typing_extensions==4.12.2

View File

@@ -1,4 +1,4 @@
coverage==7.6.3
coverage==7.6.4
pre-commit==4.0.1
pylint==3.3.1
pytest-aiohttp==1.0.5
@@ -6,7 +6,7 @@ pytest-asyncio==0.23.6
pytest-cov==5.0.0
pytest-timeout==2.3.1
pytest==8.3.3
ruff==0.6.9
ruff==0.7.0
time-machine==2.16.0
typing_extensions==4.12.2
urllib3==2.2.3

View File

@@ -413,6 +413,7 @@ class RestAPI(CoreSysAttributes):
# No need to capture HostNotSupportedError to Sentry, the cause
# is known and reported to the user using the resolution center.
capture_exception(err)
kwargs.pop("follow", None) # Follow is not supported for Docker logs
return await api_supervisor.logs(*args, **kwargs)
self.webapp.add_routes(

View File

@@ -4,7 +4,7 @@ import asyncio
from contextlib import suppress
import logging
from aiohttp import web
from aiohttp import ClientConnectionResetError, web
from aiohttp.hdrs import ACCEPT, RANGE
import voluptuous as vol
from voluptuous.error import CoerceInvalid
@@ -260,7 +260,10 @@ class APIHost(CoreSysAttributes):
response.headers["X-First-Cursor"] = cursor
await response.prepare(request)
headers_returned = True
await response.write(line.encode("utf-8") + b"\n")
# When client closes the connection while reading busy logs, we
# sometimes get this exception. It should be safe to ignore it.
with suppress(ClientConnectionResetError):
await response.write(line.encode("utf-8") + b"\n")
except ConnectionResetError as ex:
raise APIError(
"Connection reset when trying to fetch data from systemd-journald."

View File

@@ -10,10 +10,7 @@ from pathlib import Path
from ..addons.addon import Addon
from ..const import (
ATTR_DATA,
ATTR_DAYS_UNTIL_STALE,
ATTR_SLUG,
ATTR_TYPE,
FILE_HASSIO_BACKUPS,
FOLDER_HOMEASSISTANT,
CoreState,
@@ -24,9 +21,7 @@ from ..exceptions import (
BackupInvalidError,
BackupJobError,
BackupMountDownError,
HomeAssistantWSError,
)
from ..homeassistant.const import WSType
from ..jobs.const import JOB_GROUP_BACKUP_MANAGER, JobCondition, JobExecutionLimit
from ..jobs.decorator import Job
from ..jobs.job_group import JobGroup
@@ -304,18 +299,6 @@ class BackupManager(FileConfiguration, JobGroup):
# Ignore exceptions from waiting for addon startup, addon errors handled elsewhere
await asyncio.gather(*addon_start_tasks, return_exceptions=True)
try:
await self.sys_homeassistant.websocket.async_send_command(
{
ATTR_TYPE: WSType.BACKUP_SYNC,
ATTR_DATA: {
ATTR_SLUG: backup.slug,
},
},
)
except HomeAssistantWSError as err:
_LOGGER.error("Can't send backup sync to Home Assistant: %s", err)
return backup
finally:
self.sys_core.state = CoreState.RUNNING

View File

@@ -32,7 +32,6 @@ class WSType(StrEnum):
SUPERVISOR_EVENT = "supervisor/event"
BACKUP_START = "backup/start"
BACKUP_END = "backup/end"
BACKUP_SYNC = "backup/sync"
class WSEvent(StrEnum):

View File

@@ -34,7 +34,6 @@ MIN_VERSION = {
WSType.SUPERVISOR_EVENT: "2021.2.4",
WSType.BACKUP_START: "2022.1.0",
WSType.BACKUP_END: "2022.1.0",
WSType.BACKUP_SYNC: "2024.10.99",
}
_LOGGER: logging.Logger = logging.getLogger(__name__)

View File

@@ -183,6 +183,17 @@ 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",
]
# check fallback also works for the follow endpoint (no mock reset needed)
with patch("supervisor.api._LOGGER.exception") as logger:
resp = await api_client.get("/supervisor/logs/follow")
logger.assert_called_once_with(
"Failed to get supervisor logs using advanced_logs API"
)
assert resp.status == 200
assert resp.content_type == "text/plain"
journald_logs.reset_mock()
# also check generic Python error

View File

@@ -1169,40 +1169,6 @@ async def test_backup_progress(
]
async def test_backup_sync_notification(
coresys: CoreSys,
install_addon_ssh: Addon,
container: MagicMock,
ha_ws_client: AsyncMock,
tmp_supervisor_data,
path_extern,
):
"""Test backup sync notification."""
container.status = "running"
install_addon_ssh.path_data.mkdir()
coresys.core.state = CoreState.RUNNING
ha_ws_client.ha_version = AwesomeVersion("9999.9.9")
coresys.hardware.disk.get_disk_free_space = lambda x: 5000
ha_ws_client.async_send_command.reset_mock()
partial_backup: Backup = await coresys.backups.do_backup_partial()
await asyncio.sleep(0)
messages = [
call.args[0]
for call in ha_ws_client.async_send_command.call_args_list
if call.args[0]["type"] == WSType.BACKUP_SYNC
]
assert messages == [
{
"data": {
"slug": partial_backup.slug,
},
"type": WSType.BACKUP_SYNC,
},
]
async def test_restore_progress(
request: pytest.FixtureRequest,
coresys: CoreSys,