Commit 98fc499
authored
* feat: add snapshot delete + fix backup progress heartbeats (#1861)
- ha_manage_backup(scope='snapshot', action='create'/'restore') now emits
MCP progress heartbeats during the wait so clients don't idle-abort a
long-running backup; raised the internal poll ceiling 300s -> 1800s
(HA's own frontend imposes no timeout at all on backup creation)
- New (scope='snapshot', action='delete') action, off by default via
enable_snapshot_delete, layered with guards even when enabled: requires
confirm=True, never deletes scheduled/automatic backups, enforces a
snapshot_delete_min_age_days floor (default 7, an HA-stamped date an
agent can't forge), and never deletes the single newest snapshot
remaining
- Wires the two new settings through both HA add-on flavors
(config.yaml + start.py) and the web settings UI
- Unit + e2e coverage, including a real create->delete->verify-gone
round trip against a live HA test instance
* fix: add missing translations for the two new backup settings
CI caught it: test_translations_cover_every_schema_key requires every
config.yaml schema key to have a matching translations/en.yaml entry.
enable_snapshot_delete and snapshot_delete_min_age_days were wired into
config.yaml + start.py but the translations file was missed, in both
add-on flavors.
* fix: guard against a null result key in backup/info + backup/delete responses
Gemini Code Assist review: info_result.get("result", {}) and
delete_result.get("result", {}) only substitute the default when the key
is ABSENT, not when it's present with value None — a well-formed-but-null
"result" would raise AttributeError on the following .get() call. Switch
to the (x.get("result") or {}) pattern already used elsewhere in this
file (_build_success_response_if_found, _poll_backup_completion).
* fix: wire enable_snapshot_delete through the embedded/HAOS e2e backends
The container-embedded (E2E_BACKEND=embedded) and HAOS embedded/inaddon
backends run ha-mcp inside the HA instance itself, in a separate process
from pytest — os.environ[...] set in the pytest process, and
monkeypatch.setenv + _reset_global_settings(), never reach it. Both need
their own delivery mechanism:
- container-embedded: seed backup_settings.json (BACKUP_OVERRIDE_FIELDS)
in the embedded server's data dir, alongside the existing
feature_flags.json (FEATURE_FLAG_FIELDS) — two different override
files since ha_mcp.config reads the two registries separately.
- HAOS embedded/inaddon (qcow2): generalize
stage_embedded_server_feature_flags_in_qcow2 to take a filename, and
call it a second time for backup_settings.json.
Also skip the age-floor-disabled success-path e2e test under all three
out-of-process backends — the guard-rejection tests already exercise the
real delete path end-to-end there; only the "actually completes"
happy-path needs live settings mutation from the test process.
* fix: three codex-review gaps in snapshot delete
- Refuse deletion when backup/info reports agent_errors: an unreachable
agent means the backups list may be incomplete, so the newest-snapshot
and scheduled-backup guards can't be trusted.
- min_age_days=0 now unconditionally skips the age comparison instead of
relying on the arithmetic reduction, which broke under clock skew
between the ha-mcp host and the HA instance that stamped the date.
- backup/delete now passes an elevated _wait_timeout (60s vs the 30s
client default): it fans out to every configured agent server-side,
including slow/rate-limited remote ones, before responding.
* fix: skip TestSnapshotDelete on the HAOS inaddon e2e tier
The inaddon tier runs the real dev add-on against its own
Supervisor-managed options.json (config.yaml's shipped
enable_snapshot_delete=false default) — unlike container-embedded /
HAOS-embedded, which get the setting via a seeded backup_settings.json
override file, there is no in-process server here to seed a file for
(overriding would mean POSTing to the real Supervisor options API).
Mirrors the existing skip precedent in
tests/src/e2e/policy/test_readonly_mode.py for settings that can't be
forced under this tier.
* fix: address kingpanther13 review on snapshot delete
- Fail closed when with_automatic_settings is None, not just True
- Pin newest-before-age-floor evaluation order with a regression test
- Wire ctx heartbeat into delete_backup's WS wait
- Pin heartbeat throttle behavior with a regression test
- Fix docstring/comment ordering-accuracy nits
1 parent 3e13a71 commit 98fc499
19 files changed
Lines changed: 1607 additions & 41 deletions
File tree
- homeassistant-addon-dev
- translations
- homeassistant-addon
- translations
- src/ha_mcp
- settings_ui
- tools
- tests/src
- e2e
- workflows/convenience
- unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
60 | 66 | | |
61 | 67 | | |
62 | 68 | | |
| |||
82 | 88 | | |
83 | 89 | | |
84 | 90 | | |
| 91 | + | |
| 92 | + | |
85 | 93 | | |
86 | 94 | | |
87 | 95 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
156 | 156 | | |
157 | 157 | | |
158 | 158 | | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
159 | 174 | | |
160 | 175 | | |
161 | 176 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
58 | 64 | | |
59 | 65 | | |
60 | 66 | | |
| |||
70 | 76 | | |
71 | 77 | | |
72 | 78 | | |
| 79 | + | |
| 80 | + | |
73 | 81 | | |
74 | 82 | | |
75 | 83 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
383 | 383 | | |
384 | 384 | | |
385 | 385 | | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
386 | 391 | | |
387 | 392 | | |
388 | 393 | | |
| |||
518 | 523 | | |
519 | 524 | | |
520 | 525 | | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
521 | 534 | | |
522 | 535 | | |
523 | 536 | | |
| |||
675 | 688 | | |
676 | 689 | | |
677 | 690 | | |
| 691 | + | |
| 692 | + | |
678 | 693 | | |
679 | 694 | | |
680 | 695 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
100 | 100 | | |
101 | 101 | | |
102 | 102 | | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
103 | 118 | | |
104 | 119 | | |
105 | 120 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
347 | 347 | | |
348 | 348 | | |
349 | 349 | | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
350 | 370 | | |
351 | 371 | | |
352 | 372 | | |
| |||
1486 | 1506 | | |
1487 | 1507 | | |
1488 | 1508 | | |
| 1509 | + | |
| 1510 | + | |
| 1511 | + | |
| 1512 | + | |
1489 | 1513 | | |
1490 | 1514 | | |
1491 | 1515 | | |
| |||
1640 | 1664 | | |
1641 | 1665 | | |
1642 | 1666 | | |
| 1667 | + | |
| 1668 | + | |
| 1669 | + | |
| 1670 | + | |
| 1671 | + | |
| 1672 | + | |
| 1673 | + | |
1643 | 1674 | | |
1644 | 1675 | | |
1645 | 1676 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
278 | 278 | | |
279 | 279 | | |
280 | 280 | | |
| 281 | + | |
281 | 282 | | |
282 | 283 | | |
283 | 284 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1053 | 1053 | | |
1054 | 1054 | | |
1055 | 1055 | | |
| 1056 | + | |
| 1057 | + | |
| 1058 | + | |
| 1059 | + | |
| 1060 | + | |
| 1061 | + | |
| 1062 | + | |
| 1063 | + | |
1056 | 1064 | | |
1057 | 1065 | | |
1058 | 1066 | | |
| |||
1104 | 1112 | | |
1105 | 1113 | | |
1106 | 1114 | | |
| 1115 | + | |
1107 | 1116 | | |
1108 | 1117 | | |
1109 | 1118 | | |
| |||
0 commit comments