mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-09 18:26: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
|
# Initialize core objects
|
||||||
coresys.docker = await DockerAPI(coresys).load_config()
|
coresys.docker = await DockerAPI(coresys).load_config()
|
||||||
coresys.resolution = await ResolutionManager(coresys).load_config()
|
coresys.resolution = await ResolutionManager(coresys).load_config()
|
||||||
|
await coresys.resolution.load_modules()
|
||||||
coresys.jobs = await JobManager(coresys).load_config()
|
coresys.jobs = await JobManager(coresys).load_config()
|
||||||
coresys.core = Core(coresys)
|
coresys.core = Core(coresys)
|
||||||
coresys.plugins = await PluginManager(coresys).load_config()
|
coresys.plugins = await PluginManager(coresys).load_config()
|
||||||
|
@ -32,20 +32,18 @@ class ResolutionCheck(CoreSysAttributes):
|
|||||||
"""Return all list of all checks."""
|
"""Return all list of all checks."""
|
||||||
return list(self._checks.values())
|
return list(self._checks.values())
|
||||||
|
|
||||||
async def load(self) -> None:
|
def load_modules(self) -> None:
|
||||||
"""Load all checks."""
|
"""Load and setup all checks.
|
||||||
|
|
||||||
def _load() -> dict[str, CheckBase]:
|
Must be run in executor.
|
||||||
"""Load and setup checks in executor."""
|
"""
|
||||||
package = f"{__package__}.checks"
|
package = f"{__package__}.checks"
|
||||||
checks: dict[str, CheckBase] = {}
|
checks: dict[str, CheckBase] = {}
|
||||||
for module in get_valid_modules("checks"):
|
for module in get_valid_modules("checks"):
|
||||||
check_module = import_module(f"{package}.{module}")
|
check_module = import_module(f"{package}.{module}")
|
||||||
check = check_module.setup(self.coresys)
|
check = check_module.setup(self.coresys)
|
||||||
checks[check.slug] = check
|
checks[check.slug] = check
|
||||||
return checks
|
self._checks = checks
|
||||||
|
|
||||||
self._checks = await self.sys_run_in_executor(_load)
|
|
||||||
|
|
||||||
def get(self, slug: str) -> CheckBase:
|
def get(self, slug: str) -> CheckBase:
|
||||||
"""Return check based on slug."""
|
"""Return check based on slug."""
|
||||||
|
@ -33,20 +33,18 @@ class ResolutionEvaluation(CoreSysAttributes):
|
|||||||
"""Return all list of all checks."""
|
"""Return all list of all checks."""
|
||||||
return list(self._evalutions.values())
|
return list(self._evalutions.values())
|
||||||
|
|
||||||
async def load(self) -> None:
|
def load_modules(self) -> None:
|
||||||
"""Load all evaluations."""
|
"""Load and setup all evaluations.
|
||||||
|
|
||||||
def _load() -> dict[str, EvaluateBase]:
|
Must be run in executor.
|
||||||
"""Load and setup evaluations in executor."""
|
"""
|
||||||
package = f"{__package__}.evaluations"
|
package = f"{__package__}.evaluations"
|
||||||
evaluations: dict[str, EvaluateBase] = {}
|
evaluations: dict[str, EvaluateBase] = {}
|
||||||
for module in get_valid_modules("evaluations"):
|
for module in get_valid_modules("evaluations"):
|
||||||
evaluate_module = import_module(f"{package}.{module}")
|
evaluate_module = import_module(f"{package}.{module}")
|
||||||
evaluation = evaluate_module.setup(self.coresys)
|
evaluation = evaluate_module.setup(self.coresys)
|
||||||
evaluations[evaluation.slug] = evaluation
|
evaluations[evaluation.slug] = evaluation
|
||||||
return evaluations
|
self._evalutions = evaluations
|
||||||
|
|
||||||
self._evalutions = await self.sys_run_in_executor(_load)
|
|
||||||
|
|
||||||
def get(self, slug: str) -> EvaluateBase:
|
def get(self, slug: str) -> EvaluateBase:
|
||||||
"""Return check based on slug."""
|
"""Return check based on slug."""
|
||||||
|
@ -22,20 +22,18 @@ class ResolutionFixup(CoreSysAttributes):
|
|||||||
self.coresys = coresys
|
self.coresys = coresys
|
||||||
self._fixups: dict[str, FixupBase] = {}
|
self._fixups: dict[str, FixupBase] = {}
|
||||||
|
|
||||||
async def load(self) -> None:
|
def load_modules(self) -> None:
|
||||||
"""Load all fixups."""
|
"""Load and setup all fixups.
|
||||||
|
|
||||||
def _load() -> dict[str, FixupBase]:
|
Must be run in executor.
|
||||||
"""Load and setup fixups in executor."""
|
"""
|
||||||
package = f"{__package__}.fixups"
|
package = f"{__package__}.fixups"
|
||||||
fixups: dict[str, FixupBase] = {}
|
fixups: dict[str, FixupBase] = {}
|
||||||
for module in get_valid_modules("fixups"):
|
for module in get_valid_modules("fixups"):
|
||||||
fixup_module = import_module(f"{package}.{module}")
|
fixup_module = import_module(f"{package}.{module}")
|
||||||
fixup = fixup_module.setup(self.coresys)
|
fixup = fixup_module.setup(self.coresys)
|
||||||
fixups[fixup.slug] = fixup
|
fixups[fixup.slug] = fixup
|
||||||
return fixups
|
self._fixups = fixups
|
||||||
|
|
||||||
self._fixups = await self.sys_run_in_executor(_load)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def all_fixes(self) -> list[FixupBase]:
|
def all_fixes(self) -> list[FixupBase]:
|
||||||
|
@ -46,6 +46,17 @@ class ResolutionManager(FileConfiguration, CoreSysAttributes):
|
|||||||
self._unsupported: list[UnsupportedReason] = []
|
self._unsupported: list[UnsupportedReason] = []
|
||||||
self._unhealthy: list[UnhealthyReason] = []
|
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
|
@property
|
||||||
def data(self) -> dict[str, Any]:
|
def data(self) -> dict[str, Any]:
|
||||||
"""Return data."""
|
"""Return data."""
|
||||||
@ -195,10 +206,6 @@ class ResolutionManager(FileConfiguration, CoreSysAttributes):
|
|||||||
|
|
||||||
async def load(self):
|
async def load(self):
|
||||||
"""Load the resoulution manager."""
|
"""Load the resoulution manager."""
|
||||||
await self.check.load()
|
|
||||||
await self.fixup.load()
|
|
||||||
await self.evaluate.load()
|
|
||||||
|
|
||||||
# Initial healthcheck when the manager is loaded
|
# Initial healthcheck when the manager is loaded
|
||||||
await self.healthcheck()
|
await self.healthcheck()
|
||||||
|
|
||||||
|
@ -328,9 +328,6 @@ async def coresys(
|
|||||||
coresys_obj._store.save_data = AsyncMock()
|
coresys_obj._store.save_data = AsyncMock()
|
||||||
coresys_obj._mounts.save_data = AsyncMock()
|
coresys_obj._mounts.save_data = AsyncMock()
|
||||||
|
|
||||||
# Load resolution center
|
|
||||||
await coresys_obj.resolution.load()
|
|
||||||
|
|
||||||
# Mock test client
|
# Mock test client
|
||||||
coresys_obj._supervisor.instance._meta = {
|
coresys_obj._supervisor.instance._meta = {
|
||||||
"Config": {"Labels": {"io.hass.arch": "amd64"}}
|
"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):
|
async def test_dynamic_check_loader(coresys: CoreSys):
|
||||||
"""Test dynamic check loader, this ensures that all checks have defined a setup function."""
|
"""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"):
|
for check in get_valid_modules("checks"):
|
||||||
assert check in coresys.resolution.check._checks
|
assert check in coresys.resolution.check._checks
|
||||||
|
Loading…
x
Reference in New Issue
Block a user