mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-08-13 19:19:21 +00:00
Compare commits
1 Commits
2024.10.3
...
trigger-sy
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e415923553 |
26
.github/workflows/ci.yaml
vendored
26
.github/workflows/ci.yaml
vendored
@@ -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: |
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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(
|
||||
|
@@ -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."
|
||||
|
@@ -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
|
||||
|
@@ -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):
|
||||
|
@@ -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__)
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user