1 """Repairs implementation for supervisor integration."""
3 from __future__
import annotations
5 from collections.abc
import Callable, Coroutine
6 from types
import MethodType
9 from aiohasupervisor
import SupervisorError
10 from aiohasupervisor.models
import ContextType
11 import voluptuous
as vol
17 from .
import get_addons_info, get_issues_info
19 ISSUE_KEY_ADDON_BOOT_FAIL,
20 ISSUE_KEY_ADDON_DETACHED_ADDON_REMOVED,
21 ISSUE_KEY_SYSTEM_DOCKER_CONFIG,
22 PLACEHOLDER_KEY_ADDON,
23 PLACEHOLDER_KEY_COMPONENTS,
24 PLACEHOLDER_KEY_REFERENCE,
26 from .handler
import get_supervisor_client
27 from .issues
import Issue, Suggestion
30 "help_url":
"https://www.home-assistant.io/help/",
31 "community_url":
"https://community.home-assistant.io/",
34 SUGGESTION_CONFIRMATION_REQUIRED = {
35 "addon_execute_remove",
36 "system_adopt_data_disk",
37 "system_execute_reboot",
41 EXTRA_PLACEHOLDERS = {
42 "issue_mount_mount_failed": {
43 "storage_url":
"/config/storage",
45 ISSUE_KEY_ADDON_DETACHED_ADDON_REMOVED: HELP_URLS,
50 """Handler for an issue fixing flow."""
52 _data: dict[str, Any] |
None =
None
53 _issue: Issue |
None =
None
55 def __init__(self, hass: HomeAssistant, issue_id: str) ->
None:
56 """Initialize repair flow."""
62 def issue(self) -> Issue | None:
63 """Get associated issue."""
65 if not self.
_issue_issue
and supervisor_issues:
72 """Get description placeholders for steps."""
75 placeholders = EXTRA_PLACEHOLDERS.get(self.
issueissue.key, {})
76 if self.
issueissue.reference:
77 placeholders |= {PLACEHOLDER_KEY_REFERENCE: self.
issueissue.reference}
79 return placeholders
or None
82 """Return form for suggestion."""
83 return self.async_show_form(
84 step_id=suggestion.key,
85 data_schema=vol.Schema({}),
91 """Handle the first step of a fix flow."""
93 if not self.
issueissue
or not self.
issueissue.suggestions:
94 return self.async_create_entry(data={})
99 for suggestion
in self.
issueissue.suggestions:
102 f
"async_step_{suggestion.key}",
103 MethodType(self.
_async_step_async_step(suggestion), self),
106 if len(self.
issueissue.suggestions) > 1:
113 """Show the fix menu."""
114 assert self.
issueissue
116 return self.async_show_menu(
118 menu_options=[suggestion.key
for suggestion
in self.
issueissue.suggestions],
123 self, suggestion: Suggestion, confirmed: bool =
False
125 """Handle applying a suggestion as a flow step. Optionally request confirmation."""
126 if not confirmed
and suggestion.key
in SUGGESTION_CONFIRMATION_REQUIRED:
130 await self.
_supervisor_client_supervisor_client.resolution.apply_suggestion(suggestion.uuid)
131 except SupervisorError:
132 return self.async_abort(reason=
"apply_suggestion_fail")
134 return self.async_create_entry(data={})
138 suggestion: Suggestion,
140 [SupervisorIssueRepairFlow, dict[str, str] |
None],
141 Coroutine[Any, Any, FlowResult],
143 """Generate a step handler for a suggestion."""
146 self: SupervisorIssueRepairFlow, user_input: dict[str, str] |
None =
None
148 """Handle a flow step for a suggestion."""
150 suggestion, confirmed=user_input
is not None
157 """Handler for docker config issue fixing flow."""
161 """Get description placeholders for steps."""
162 placeholders = {PLACEHOLDER_KEY_COMPONENTS:
""}
164 if supervisor_issues
and self.
issueissue:
166 components: list[str] = []
167 for issue
in supervisor_issues.issues:
168 if issue.key == self.
issueissue.key
or issue.type != self.
issueissue.type:
171 if issue.context == ContextType.CORE:
172 components.insert(0,
"Home Assistant")
173 elif issue.context == ContextType.ADDON:
178 for slug, info
in addons.items()
179 if slug == issue.reference
181 issue.reference
or "",
185 placeholders[PLACEHOLDER_KEY_COMPONENTS] =
"\n- ".join(components)
191 """Handler for addon issue fixing flows."""
195 """Get description placeholders for steps."""
196 placeholders: dict[str, str] = super().description_placeholders
or {}
197 if self.
issueissue
and self.
issueissue.reference:
199 if addons
and self.
issueissue.reference
in addons:
200 placeholders[PLACEHOLDER_KEY_ADDON] = addons[self.
issueissue.reference][
204 placeholders[PLACEHOLDER_KEY_ADDON] = self.
issueissue.reference
206 return placeholders
or None
212 data: dict[str, str | int | float |
None] |
None,
216 issue = supervisor_issues
and supervisor_issues.get_issue(issue_id)
217 if issue
and issue.key == ISSUE_KEY_SYSTEM_DOCKER_CONFIG:
219 if issue
and issue.key
in {
220 ISSUE_KEY_ADDON_DETACHED_ADDON_REMOVED,
221 ISSUE_KEY_ADDON_BOOT_FAIL,
dict[str, str]|None description_placeholders(self)
dict[str, str]|None description_placeholders(self)
Callable[[SupervisorIssueRepairFlow, dict[str, str]|None], Coroutine[Any, Any, FlowResult],] _async_step(Suggestion suggestion)
FlowResult async_step_init(self, None _=None)
FlowResult _async_form_for_suggestion(self, Suggestion suggestion)
dict[str, str]|None description_placeholders(self)
FlowResult async_step_fix_menu(self, None _=None)
FlowResult _async_step_apply_suggestion(self, Suggestion suggestion, bool confirmed=False)
None __init__(self, HomeAssistant hass, str issue_id)
dict[str, dict[str, Any]]|None get_addons_info(HomeAssistant hass)
SupervisorIssues|None get_issues_info(HomeAssistant hass)
SupervisorClient get_supervisor_client(HomeAssistant hass)
RepairsFlow async_create_fix_flow(HomeAssistant hass, str issue_id, dict[str, str|int|float|None]|None data)