Add uninstall addon suggestion to detached_addon_removed (#5105)

This commit is contained in:
Mike Degatano 2024-06-03 10:38:34 -04:00 committed by GitHub
parent 9fd2c91c55
commit e57de4a3c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 96 additions and 2 deletions

View File

@ -2,7 +2,7 @@
from ...const import CoreState from ...const import CoreState
from ...coresys import CoreSys from ...coresys import CoreSys
from ..const import ContextType, IssueType from ..const import ContextType, IssueType, SuggestionType
from .base import CheckBase from .base import CheckBase
@ -22,6 +22,7 @@ class CheckDetachedAddonRemoved(CheckBase):
IssueType.DETACHED_ADDON_REMOVED, IssueType.DETACHED_ADDON_REMOVED,
ContextType.ADDON, ContextType.ADDON,
reference=addon.slug, reference=addon.slug,
suggestions=[SuggestionType.EXECUTE_REMOVE],
) )
async def approve_check(self, reference: str | None = None) -> bool: async def approve_check(self, reference: str | None = None) -> bool:

View File

@ -0,0 +1,52 @@
"""Helpers to fix addon issue by removing it."""
import logging
from ...coresys import CoreSys
from ...exceptions import AddonsError, ResolutionFixupError
from ..const import ContextType, IssueType, SuggestionType
from .base import FixupBase
_LOGGER: logging.Logger = logging.getLogger(__name__)
def setup(coresys: CoreSys) -> FixupBase:
"""Check setup function."""
return FixupAddonExecuteRemove(coresys)
class FixupAddonExecuteRemove(FixupBase):
"""Storage class for fixup."""
async def process_fixup(self, reference: str | None = None) -> None:
"""Initialize the fixup class."""
if not (addon := self.sys_addons.get(reference, local_only=True)):
_LOGGER.info("Addon %s already removed", reference)
return
# Remove addon
_LOGGER.info("Remove addon: %s", reference)
try:
addon.uninstall()
except AddonsError as err:
_LOGGER.error("Could not remove %s due to %s", reference, err)
raise ResolutionFixupError() from None
@property
def suggestion(self) -> SuggestionType:
"""Return a SuggestionType enum."""
return SuggestionType.EXECUTE_REMOVE
@property
def context(self) -> ContextType:
"""Return a ContextType enum."""
return ContextType.ADDON
@property
def issues(self) -> list[IssueType]:
"""Return a IssueType enum list."""
return [IssueType.DETACHED_ADDON_REMOVED]
@property
def auto(self) -> bool:
"""Return if a fixup can be apply as auto fix."""
return False

View File

@ -37,6 +37,7 @@ async def test_check(coresys: CoreSys, install_addon_ssh: Addon):
assert coresys.resolution.issues[0].type is IssueType.DETACHED_ADDON_MISSING assert coresys.resolution.issues[0].type is IssueType.DETACHED_ADDON_MISSING
assert coresys.resolution.issues[0].context is ContextType.ADDON assert coresys.resolution.issues[0].context is ContextType.ADDON
assert coresys.resolution.issues[0].reference == install_addon_ssh.slug assert coresys.resolution.issues[0].reference == install_addon_ssh.slug
assert len(coresys.resolution.suggestions) == 0
async def test_approve(coresys: CoreSys, install_addon_ssh: Addon): async def test_approve(coresys: CoreSys, install_addon_ssh: Addon):

View File

@ -9,7 +9,7 @@ from supervisor.coresys import CoreSys
from supervisor.resolution.checks.detached_addon_removed import ( from supervisor.resolution.checks.detached_addon_removed import (
CheckDetachedAddonRemoved, CheckDetachedAddonRemoved,
) )
from supervisor.resolution.const import ContextType, IssueType from supervisor.resolution.const import ContextType, IssueType, SuggestionType
async def test_base(coresys: CoreSys): async def test_base(coresys: CoreSys):
@ -28,6 +28,7 @@ async def test_check(
await detached_addon_removed() await detached_addon_removed()
assert len(coresys.resolution.issues) == 0 assert len(coresys.resolution.issues) == 0
assert len(coresys.resolution.suggestions) == 0
(addons_dir := tmp_supervisor_data / "addons" / "local").mkdir() (addons_dir := tmp_supervisor_data / "addons" / "local").mkdir()
with patch.object( with patch.object(
@ -42,6 +43,11 @@ async def test_check(
assert coresys.resolution.issues[0].context is ContextType.ADDON assert coresys.resolution.issues[0].context is ContextType.ADDON
assert coresys.resolution.issues[0].reference == install_addon_ssh.slug assert coresys.resolution.issues[0].reference == install_addon_ssh.slug
assert len(coresys.resolution.suggestions) == 1
assert coresys.resolution.suggestions[0].type is SuggestionType.EXECUTE_REMOVE
assert coresys.resolution.suggestions[0].context is ContextType.ADDON
assert coresys.resolution.suggestions[0].reference == install_addon_ssh.slug
async def test_approve( async def test_approve(
coresys: CoreSys, install_addon_ssh: Addon, tmp_supervisor_data: Path coresys: CoreSys, install_addon_ssh: Addon, tmp_supervisor_data: Path

View File

@ -0,0 +1,34 @@
"""Test evaluation base."""
from unittest.mock import patch
from supervisor.addons.addon import Addon
from supervisor.coresys import CoreSys
from supervisor.resolution.const import ContextType, IssueType, SuggestionType
from supervisor.resolution.data import Issue, Suggestion
from supervisor.resolution.fixups.addon_execute_remove import FixupAddonExecuteRemove
async def test_fixup(coresys: CoreSys, install_addon_ssh: Addon):
"""Test fixup."""
addon_execute_remove = FixupAddonExecuteRemove(coresys)
assert addon_execute_remove.auto is False
coresys.resolution.suggestions = Suggestion(
SuggestionType.EXECUTE_REMOVE,
ContextType.ADDON,
reference=install_addon_ssh.slug,
)
coresys.resolution.issues = Issue(
IssueType.DETACHED_ADDON_REMOVED,
ContextType.ADDON,
reference=install_addon_ssh.slug,
)
with patch.object(Addon, "uninstall") as uninstall:
await addon_execute_remove()
assert uninstall.called
assert len(coresys.resolution.suggestions) == 0
assert len(coresys.resolution.issues) == 0