Compare commits

...

2 Commits

Author SHA1 Message Date
Stefan Agner
ecf3bc85a1 Merge branch 'dev' into add-deprecated-arch-addon-repair 2026-03-16 13:47:05 +01:00
Mike Degatano
bd9d323c46 Add repair for deprecated arch addon issue 2026-03-13 23:06:35 +00:00
5 changed files with 106 additions and 0 deletions

View File

@@ -130,6 +130,7 @@ ISSUE_KEY_ADDON_DETACHED_ADDON_REMOVED = "issue_addon_detached_addon_removed"
ISSUE_KEY_ADDON_PWNED = "issue_addon_pwned"
ISSUE_KEY_SYSTEM_FREE_SPACE = "issue_system_free_space"
ISSUE_KEY_ADDON_DEPRECATED = "issue_addon_deprecated_addon"
ISSUE_KEY_ADDON_DEPRECATED_ARCH = "issue_addon_deprecated_arch_addon"
ISSUE_MOUNT_MOUNT_FAILED = "issue_mount_mount_failed"
@@ -170,6 +171,7 @@ EXTRA_PLACEHOLDERS = {
"more_info_pwned": "https://www.home-assistant.io/more-info/pwned-passwords",
},
ISSUE_KEY_ADDON_DEPRECATED: HELP_URLS,
ISSUE_KEY_ADDON_DEPRECATED_ARCH: HELP_URLS,
}

View File

@@ -45,6 +45,7 @@ from .const import (
EVENT_SUPPORTED_CHANGED,
EXTRA_PLACEHOLDERS,
ISSUE_KEY_ADDON_BOOT_FAIL,
ISSUE_KEY_ADDON_DEPRECATED_ARCH,
ISSUE_KEY_ADDON_DETACHED_ADDON_MISSING,
ISSUE_KEY_ADDON_DETACHED_ADDON_REMOVED,
ISSUE_KEY_ADDON_PWNED,
@@ -88,6 +89,7 @@ ISSUE_KEYS_FOR_REPAIRS = {
"issue_system_disk_lifetime",
ISSUE_KEY_SYSTEM_FREE_SPACE,
ISSUE_KEY_ADDON_PWNED,
ISSUE_KEY_ADDON_DEPRECATED_ARCH,
}
_LOGGER = logging.getLogger(__name__)

View File

@@ -19,6 +19,7 @@ from .const import (
EXTRA_PLACEHOLDERS,
ISSUE_KEY_ADDON_BOOT_FAIL,
ISSUE_KEY_ADDON_DEPRECATED,
ISSUE_KEY_ADDON_DEPRECATED_ARCH,
ISSUE_KEY_ADDON_DETACHED_ADDON_REMOVED,
ISSUE_KEY_ADDON_PWNED,
ISSUE_KEY_SYSTEM_DOCKER_CONFIG,
@@ -231,6 +232,7 @@ async def async_create_fix_flow(
ISSUE_KEY_ADDON_DETACHED_ADDON_REMOVED,
ISSUE_KEY_ADDON_BOOT_FAIL,
ISSUE_KEY_ADDON_PWNED,
ISSUE_KEY_ADDON_DEPRECATED_ARCH,
}:
return AddonIssueRepairFlow(hass, issue_id)

View File

@@ -85,6 +85,19 @@
},
"title": "Installed app is deprecated"
},
"issue_addon_deprecated_arch_addon": {
"fix_flow": {
"abort": {
"apply_suggestion_fail": "Could not uninstall the app. Check the Supervisor logs for more details."
},
"step": {
"addon_execute_remove": {
"description": "App {addon} only supports architectures and/or machines which are no longer supported by Home Assistant. It will not be able to receive updates and will stop working in a future release.\n\nSelecting **Submit** will uninstall this deprecated app. Alternatively, you can check [Home Assistant help]({help_url}) and the [community forum]({community_url}) for alternatives to migrate to."
}
}
},
"title": "Installed app does not work on supported architectures and/or machines"
},
"issue_addon_detached_addon_missing": {
"description": "Repository for app {addon} is missing. This means it will not get updates, and backups may not be restored correctly as the Home Assistant Supervisor may not be able to build/download the resources required.\n\nPlease check the [app's documentation]({addon_url}) for installation instructions and add the repository to the store.",
"title": "Missing repository for an installed app"

View File

@@ -1087,3 +1087,90 @@ async def test_supervisor_issue_deprecated_addon(
assert not issue_registry.async_get_issue(domain="hassio", issue_id=issue_uuid.hex)
supervisor_client.resolution.apply_suggestion.assert_called_once_with(sugg_uuid)
@pytest.mark.parametrize(
"all_setup_requests", [{"include_addons": True}], indirect=True
)
@pytest.mark.usefixtures("all_setup_requests")
async def test_supervisor_issue_deprecated_arch_addon(
hass: HomeAssistant,
supervisor_client: AsyncMock,
hass_client: ClientSessionGenerator,
issue_registry: ir.IssueRegistry,
) -> None:
"""Test fix flow for supervisor issue for add-on using deprecated architecture or machine."""
mock_resolution_info(
supervisor_client,
issues=[
Issue(
type=IssueType.DEPRECATED_ARCH_ADDON,
context=ContextType.ADDON,
reference="test",
uuid=(issue_uuid := uuid4()),
),
],
suggestions_by_issue={
issue_uuid: [
Suggestion(
type=SuggestionType.EXECUTE_REMOVE,
context=ContextType.ADDON,
reference="test",
uuid=(sugg_uuid := uuid4()),
auto=False,
),
]
},
)
assert await async_setup_component(hass, "hassio", {})
repair_issue = issue_registry.async_get_issue(
domain="hassio", issue_id=issue_uuid.hex
)
assert repair_issue
client = await hass_client()
resp = await client.post(
"/api/repairs/issues/fix",
json={"handler": "hassio", "issue_id": repair_issue.issue_id},
)
assert resp.status == HTTPStatus.OK
data = await resp.json()
flow_id = data["flow_id"]
assert data == {
"type": "form",
"flow_id": flow_id,
"handler": "hassio",
"step_id": "addon_execute_remove",
"data_schema": [],
"errors": None,
"description_placeholders": {
"reference": "test",
"addon": "test",
"help_url": "https://www.home-assistant.io/help/",
"community_url": "https://community.home-assistant.io/",
},
"last_step": True,
"preview": None,
}
resp = await client.post(f"/api/repairs/issues/fix/{flow_id}")
assert resp.status == HTTPStatus.OK
data = await resp.json()
flow_id = data["flow_id"]
assert data == {
"type": "create_entry",
"flow_id": flow_id,
"handler": "hassio",
"description": None,
"description_placeholders": None,
}
assert not issue_registry.async_get_issue(domain="hassio", issue_id=issue_uuid.hex)
supervisor_client.resolution.apply_suggestion.assert_called_once_with(sugg_uuid)