Compare commits

..

1 Commits

Author SHA1 Message Date
ludeeus
e415923553 Trigger backup sync when backup is complete 2024-10-16 04:54:29 +00:00
10 changed files with 73 additions and 35 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.2
uses: actions/cache@v4.1.1
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.2
uses: actions/cache@v4.1.1
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.2
uses: actions/cache@v4.1.1
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.2
uses: actions/cache@v4.1.1
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.2
uses: actions/cache@v4.1.1
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.2
uses: actions/cache@v4.1.1
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.2
uses: actions/cache@v4.1.1
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.2
uses: actions/cache@v4.1.1
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.2
uses: actions/cache@v4.1.1
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.2
uses: actions/cache@v4.1.1
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.2
uses: actions/cache@v4.1.1
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.2
uses: actions/cache@v4.1.1
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.2
uses: actions/cache@v4.1.1
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.3
cryptography==43.0.1
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.17.0
setuptools==75.2.0
sentry-sdk==2.16.0
setuptools==75.1.0
voluptuous==0.15.2
dbus-fast==2.24.3
typing_extensions==4.12.2

View File

@@ -1,4 +1,4 @@
coverage==7.6.4
coverage==7.6.3
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.7.0
ruff==0.6.9
time-machine==2.16.0
typing_extensions==4.12.2
urllib3==2.2.3

View File

@@ -413,7 +413,6 @@ 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 ClientConnectionResetError, web
from aiohttp import web
from aiohttp.hdrs import ACCEPT, RANGE
import voluptuous as vol
from voluptuous.error import CoerceInvalid
@@ -260,10 +260,7 @@ class APIHost(CoreSysAttributes):
response.headers["X-First-Cursor"] = cursor
await response.prepare(request)
headers_returned = True
# 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")
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,7 +10,10 @@ 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,
@@ -21,7 +24,9 @@ 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
@@ -299,6 +304,18 @@ 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,6 +32,7 @@ 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,6 +34,7 @@ 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,17 +183,6 @@ 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,6 +1169,40 @@ 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,