mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-23 09:06:29 +00:00
Fix new version handling with Plugins (#2159)
This commit is contained in:
parent
0c6c6a6620
commit
01064564b4
@ -2,10 +2,9 @@
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from packaging.version import LegacyVersion, parse as pkg_parse
|
||||
|
||||
from ..coresys import CoreSys, CoreSysAttributes
|
||||
from ..exceptions import HassioError
|
||||
from ..resolution.const import ContextType, IssueType, SuggestionType
|
||||
from .audio import Audio
|
||||
from .cli import HaCli
|
||||
from .dns import CoreDNS
|
||||
@ -18,12 +17,6 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
class PluginManager(CoreSysAttributes):
|
||||
"""Manage supported function for plugins."""
|
||||
|
||||
required_cli: LegacyVersion = pkg_parse("2020.10.0")
|
||||
required_dns: LegacyVersion = pkg_parse("9")
|
||||
required_audio: LegacyVersion = pkg_parse("17")
|
||||
required_observer: LegacyVersion = pkg_parse("2020.10.1")
|
||||
required_multicast: LegacyVersion = pkg_parse("3")
|
||||
|
||||
def __init__(self, coresys: CoreSys):
|
||||
"""Initialize plugin manager."""
|
||||
self.coresys: CoreSys = coresys
|
||||
@ -72,44 +65,49 @@ class PluginManager(CoreSysAttributes):
|
||||
try:
|
||||
await plugin.load()
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
_LOGGER.warning("Can't load plugin %s: %s", type(plugin).__name__, err)
|
||||
_LOGGER.warning("Can't load plugin %s: %s", plugin.slug, err)
|
||||
self.sys_resolution.create_issue(
|
||||
IssueType.FATAL_ERROR,
|
||||
ContextType.PLUGIN,
|
||||
reference=plugin.slug,
|
||||
suggestions=[SuggestionType.EXECUTE_REPAIR],
|
||||
)
|
||||
self.sys_capture_exception(err)
|
||||
|
||||
# Check requirements
|
||||
for plugin, required_version in (
|
||||
(self._audio, self.required_audio),
|
||||
(self._dns, self.required_dns),
|
||||
(self._cli, self.required_cli),
|
||||
(self._observer, self.required_observer),
|
||||
(self._multicast, self.required_multicast),
|
||||
await self.sys_updater.reload()
|
||||
for plugin in (
|
||||
self.dns,
|
||||
self.audio,
|
||||
self.cli,
|
||||
self.observer,
|
||||
self.multicast,
|
||||
):
|
||||
# Check if need an update
|
||||
try:
|
||||
if pkg_parse(plugin.version) >= required_version:
|
||||
continue
|
||||
except TypeError:
|
||||
_LOGGER.warning(
|
||||
"Unexpected issue while checking requirements for %s",
|
||||
type(plugin).__name__,
|
||||
)
|
||||
if not plugin.need_update:
|
||||
continue
|
||||
|
||||
_LOGGER.info(
|
||||
"%s does not have the required version %s, updating",
|
||||
type(plugin).__name__,
|
||||
required_version,
|
||||
"%s does not have the latest version %s, updating",
|
||||
plugin.slug,
|
||||
plugin.latest_version,
|
||||
)
|
||||
try:
|
||||
await plugin.update(version=str(required_version))
|
||||
await plugin.update()
|
||||
except HassioError:
|
||||
_LOGGER.error(
|
||||
"Can't update %s to %s but it's a reuirement, the Supervisor is now in an unhealthy state!",
|
||||
type(plugin).__name__,
|
||||
required_version,
|
||||
"Can't update %s to %s, the Supervisor healthy could be compromised!",
|
||||
plugin.slug,
|
||||
plugin.latest_version,
|
||||
)
|
||||
self.sys_resolution.create_issue(
|
||||
IssueType.UPDATE_FAILED,
|
||||
ContextType.PLUGIN,
|
||||
reference=plugin.slug,
|
||||
suggestions=[SuggestionType.EXECUTE_UPDATE],
|
||||
)
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
_LOGGER.warning(
|
||||
"Can't update plugin %s: %s", type(plugin).__name__, err
|
||||
)
|
||||
_LOGGER.warning("Can't update plugin %s: %s", plugin.slug, err)
|
||||
self.sys_capture_exception(err)
|
||||
|
||||
async def repair(self) -> None:
|
||||
@ -136,5 +134,5 @@ class PluginManager(CoreSysAttributes):
|
||||
try:
|
||||
await plugin.stop()
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
_LOGGER.warning("Can't stop plugin %s: %s", type(plugin).__name__, err)
|
||||
_LOGGER.warning("Can't stop plugin %s: %s", plugin.slug, err)
|
||||
self.sys_capture_exception(err)
|
||||
|
@ -30,6 +30,8 @@ ASOUND_TMPL: Path = Path(__file__).parents[1].joinpath("data/asound.tmpl")
|
||||
class Audio(JsonConfig, CoreSysAttributes):
|
||||
"""Home Assistant core object for handle audio."""
|
||||
|
||||
slug: str = "audio"
|
||||
|
||||
def __init__(self, coresys: CoreSys):
|
||||
"""Initialize hass object."""
|
||||
super().__init__(FILE_HASSIO_AUDIO, SCHEMA_AUDIO_CONFIG)
|
||||
|
@ -25,6 +25,8 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
class HaCli(CoreSysAttributes, JsonConfig):
|
||||
"""HA cli interface inside supervisor."""
|
||||
|
||||
slug: str = "cli"
|
||||
|
||||
def __init__(self, coresys: CoreSys):
|
||||
"""Initialize cli handler."""
|
||||
super().__init__(FILE_HASSIO_CLI, SCHEMA_CLI_CONFIG)
|
||||
|
@ -42,6 +42,8 @@ class HostEntry:
|
||||
class CoreDNS(JsonConfig, CoreSysAttributes):
|
||||
"""Home Assistant core object for handle it."""
|
||||
|
||||
slug: str = "dns"
|
||||
|
||||
def __init__(self, coresys: CoreSys):
|
||||
"""Initialize hass object."""
|
||||
super().__init__(FILE_HASSIO_DNS, SCHEMA_DNS_CONFIG)
|
||||
|
@ -24,6 +24,8 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
class Multicast(JsonConfig, CoreSysAttributes):
|
||||
"""Home Assistant core object for handle it."""
|
||||
|
||||
slug: str = "multicast"
|
||||
|
||||
def __init__(self, coresys: CoreSys):
|
||||
"""Initialize hass object."""
|
||||
super().__init__(FILE_HASSIO_MULTICAST, SCHEMA_MULTICAST_CONFIG)
|
||||
|
@ -26,6 +26,8 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
class Observer(CoreSysAttributes, JsonConfig):
|
||||
"""Supervisor observer instance."""
|
||||
|
||||
slug: str = "observer"
|
||||
|
||||
def __init__(self, coresys: CoreSys):
|
||||
"""Initialize observer handler."""
|
||||
super().__init__(FILE_HASSIO_OBSERVER, SCHEMA_OBSERVER_CONFIG)
|
||||
|
@ -12,6 +12,7 @@ class ContextType(str, Enum):
|
||||
|
||||
SYSTEM = "system"
|
||||
SUPERVISOR = "supervisor"
|
||||
PLUGIN = "plugin"
|
||||
ADDON = "addon"
|
||||
CORE = "core"
|
||||
OS = "os"
|
||||
@ -39,6 +40,7 @@ class IssueType(str, Enum):
|
||||
MISSING_IMAGE = "missing_image"
|
||||
UPDATE_FAILED = "update_failed"
|
||||
UPDATE_ROLLBACK = "update_rollback"
|
||||
FATAL_ERROR = "fatal_error"
|
||||
|
||||
|
||||
class SuggestionType(str, Enum):
|
||||
@ -46,4 +48,5 @@ class SuggestionType(str, Enum):
|
||||
|
||||
CLEAR_FULL_SNAPSHOT = "clear_full_snapshot"
|
||||
CREATE_FULL_SNAPSHOT = "create_full_snapshot"
|
||||
SYSTEM_REPAIR = "system_repair"
|
||||
EXECUTE_UPDATE = "execute_update"
|
||||
EXECUTE_REPAIR = "execute_repair"
|
||||
|
@ -129,12 +129,12 @@ async def test_resolution_create_issue_suggestion(coresys: CoreSys):
|
||||
IssueType.UPDATE_ROLLBACK,
|
||||
ContextType.CORE,
|
||||
"slug",
|
||||
[SuggestionType.SYSTEM_REPAIR],
|
||||
[SuggestionType.EXECUTE_REPAIR],
|
||||
)
|
||||
|
||||
assert IssueType.UPDATE_ROLLBACK == coresys.resolution.issues[-1].type
|
||||
assert ContextType.CORE == coresys.resolution.issues[-1].context
|
||||
assert coresys.resolution.issues[-1].reference == "slug"
|
||||
|
||||
assert SuggestionType.SYSTEM_REPAIR == coresys.resolution.suggestions[-1].type
|
||||
assert SuggestionType.EXECUTE_REPAIR == coresys.resolution.suggestions[-1].type
|
||||
assert ContextType.CORE == coresys.resolution.suggestions[-1].context
|
||||
|
Loading…
x
Reference in New Issue
Block a user