mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-09 02:06:30 +00:00
Load resolution evaluation, check and fixups early (#5696)
* Load resolution evaluation, check and fixups early Before #5652, these modules were loaded in the constructor, hence early in `initialize_coresys()`. Moving them late actually exposed an issue where NetworkManager connectivity setter couldn't get the `connectivity_check` evaluation, leading to an exception early in bootstrap. Technically, it might be safe to load the resolution modules only in `Core.connect()`, however then we'd have to load them separately for pytest. Let's go conservative and load them the same place where they got loaded before #5652. * Load resolution modules in a single executor call * Fix pytest
This commit is contained in:
parent
53d97ce0c6
commit
8030b346e0
@ -55,6 +55,7 @@ async def initialize_coresys() -> CoreSys:
|
||||
# Initialize core objects
|
||||
coresys.docker = await DockerAPI(coresys).load_config()
|
||||
coresys.resolution = await ResolutionManager(coresys).load_config()
|
||||
await coresys.resolution.load_modules()
|
||||
coresys.jobs = await JobManager(coresys).load_config()
|
||||
coresys.core = Core(coresys)
|
||||
coresys.plugins = await PluginManager(coresys).load_config()
|
||||
|
@ -32,20 +32,18 @@ class ResolutionCheck(CoreSysAttributes):
|
||||
"""Return all list of all checks."""
|
||||
return list(self._checks.values())
|
||||
|
||||
async def load(self) -> None:
|
||||
"""Load all checks."""
|
||||
def load_modules(self) -> None:
|
||||
"""Load and setup all checks.
|
||||
|
||||
def _load() -> dict[str, CheckBase]:
|
||||
"""Load and setup checks in executor."""
|
||||
Must be run in executor.
|
||||
"""
|
||||
package = f"{__package__}.checks"
|
||||
checks: dict[str, CheckBase] = {}
|
||||
for module in get_valid_modules("checks"):
|
||||
check_module = import_module(f"{package}.{module}")
|
||||
check = check_module.setup(self.coresys)
|
||||
checks[check.slug] = check
|
||||
return checks
|
||||
|
||||
self._checks = await self.sys_run_in_executor(_load)
|
||||
self._checks = checks
|
||||
|
||||
def get(self, slug: str) -> CheckBase:
|
||||
"""Return check based on slug."""
|
||||
|
@ -33,20 +33,18 @@ class ResolutionEvaluation(CoreSysAttributes):
|
||||
"""Return all list of all checks."""
|
||||
return list(self._evalutions.values())
|
||||
|
||||
async def load(self) -> None:
|
||||
"""Load all evaluations."""
|
||||
def load_modules(self) -> None:
|
||||
"""Load and setup all evaluations.
|
||||
|
||||
def _load() -> dict[str, EvaluateBase]:
|
||||
"""Load and setup evaluations in executor."""
|
||||
Must be run in executor.
|
||||
"""
|
||||
package = f"{__package__}.evaluations"
|
||||
evaluations: dict[str, EvaluateBase] = {}
|
||||
for module in get_valid_modules("evaluations"):
|
||||
evaluate_module = import_module(f"{package}.{module}")
|
||||
evaluation = evaluate_module.setup(self.coresys)
|
||||
evaluations[evaluation.slug] = evaluation
|
||||
return evaluations
|
||||
|
||||
self._evalutions = await self.sys_run_in_executor(_load)
|
||||
self._evalutions = evaluations
|
||||
|
||||
def get(self, slug: str) -> EvaluateBase:
|
||||
"""Return check based on slug."""
|
||||
|
@ -22,20 +22,18 @@ class ResolutionFixup(CoreSysAttributes):
|
||||
self.coresys = coresys
|
||||
self._fixups: dict[str, FixupBase] = {}
|
||||
|
||||
async def load(self) -> None:
|
||||
"""Load all fixups."""
|
||||
def load_modules(self) -> None:
|
||||
"""Load and setup all fixups.
|
||||
|
||||
def _load() -> dict[str, FixupBase]:
|
||||
"""Load and setup fixups in executor."""
|
||||
Must be run in executor.
|
||||
"""
|
||||
package = f"{__package__}.fixups"
|
||||
fixups: dict[str, FixupBase] = {}
|
||||
for module in get_valid_modules("fixups"):
|
||||
fixup_module = import_module(f"{package}.{module}")
|
||||
fixup = fixup_module.setup(self.coresys)
|
||||
fixups[fixup.slug] = fixup
|
||||
return fixups
|
||||
|
||||
self._fixups = await self.sys_run_in_executor(_load)
|
||||
self._fixups = fixups
|
||||
|
||||
@property
|
||||
def all_fixes(self) -> list[FixupBase]:
|
||||
|
@ -46,6 +46,17 @@ class ResolutionManager(FileConfiguration, CoreSysAttributes):
|
||||
self._unsupported: list[UnsupportedReason] = []
|
||||
self._unhealthy: list[UnhealthyReason] = []
|
||||
|
||||
async def load_modules(self):
|
||||
"""Load resolution evaluation, check and fixup modules."""
|
||||
|
||||
def _load_modules():
|
||||
"""Load and setup all resolution modules."""
|
||||
self._evaluate.load_modules()
|
||||
self._check.load_modules()
|
||||
self._fixup.load_modules()
|
||||
|
||||
await self.sys_run_in_executor(_load_modules)
|
||||
|
||||
@property
|
||||
def data(self) -> dict[str, Any]:
|
||||
"""Return data."""
|
||||
@ -195,10 +206,6 @@ class ResolutionManager(FileConfiguration, CoreSysAttributes):
|
||||
|
||||
async def load(self):
|
||||
"""Load the resoulution manager."""
|
||||
await self.check.load()
|
||||
await self.fixup.load()
|
||||
await self.evaluate.load()
|
||||
|
||||
# Initial healthcheck when the manager is loaded
|
||||
await self.healthcheck()
|
||||
|
||||
|
@ -328,9 +328,6 @@ async def coresys(
|
||||
coresys_obj._store.save_data = AsyncMock()
|
||||
coresys_obj._mounts.save_data = AsyncMock()
|
||||
|
||||
# Load resolution center
|
||||
await coresys_obj.resolution.load()
|
||||
|
||||
# Mock test client
|
||||
coresys_obj._supervisor.instance._meta = {
|
||||
"Config": {"Labels": {"io.hass.arch": "amd64"}}
|
||||
|
@ -113,6 +113,6 @@ async def test_get_checks(coresys: CoreSys):
|
||||
|
||||
async def test_dynamic_check_loader(coresys: CoreSys):
|
||||
"""Test dynamic check loader, this ensures that all checks have defined a setup function."""
|
||||
await coresys.resolution.check.load()
|
||||
coresys.resolution.check.load_modules()
|
||||
for check in get_valid_modules("checks"):
|
||||
assert check in coresys.resolution.check._checks
|
||||
|
Loading…
x
Reference in New Issue
Block a user