mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-08-10 17:49:21 +00:00
Handle OSError / Filesystem corruptions (#4127)
* Handle OSError / Filesystem corruptions * Fix tests
This commit is contained in:
@@ -69,6 +69,7 @@ class IssueType(str, Enum):
|
|||||||
|
|
||||||
CORRUPT_DOCKER = "corrupt_docker"
|
CORRUPT_DOCKER = "corrupt_docker"
|
||||||
CORRUPT_REPOSITORY = "corrupt_repository"
|
CORRUPT_REPOSITORY = "corrupt_repository"
|
||||||
|
CORRUPT_FILESYSTEM = "corrupt_filesystem"
|
||||||
DNS_LOOP = "dns_loop"
|
DNS_LOOP = "dns_loop"
|
||||||
DNS_SERVER_FAILED = "dns_server_failed"
|
DNS_SERVER_FAILED = "dns_server_failed"
|
||||||
DNS_SERVER_IPV6_ERROR = "dns_server_ipv6_error"
|
DNS_SERVER_IPV6_ERROR = "dns_server_ipv6_error"
|
||||||
|
@@ -6,7 +6,7 @@ from ...const import CoreState
|
|||||||
from ...coresys import CoreSys
|
from ...coresys import CoreSys
|
||||||
from ...exceptions import CodeNotaryError, CodeNotaryUntrusted
|
from ...exceptions import CodeNotaryError, CodeNotaryUntrusted
|
||||||
from ...utils.codenotary import calc_checksum_path_sourcecode
|
from ...utils.codenotary import calc_checksum_path_sourcecode
|
||||||
from ..const import UnsupportedReason
|
from ..const import ContextType, IssueType, UnsupportedReason
|
||||||
from .base import EvaluateBase
|
from .base import EvaluateBase
|
||||||
|
|
||||||
_SUPERVISOR_SOURCE = Path("/usr/src/supervisor/supervisor")
|
_SUPERVISOR_SOURCE = Path("/usr/src/supervisor/supervisor")
|
||||||
@@ -36,17 +36,25 @@ class EvaluateSourceMods(EvaluateBase):
|
|||||||
"""Return a list of valid states when this evaluation can run."""
|
"""Return a list of valid states when this evaluation can run."""
|
||||||
return [CoreState.RUNNING]
|
return [CoreState.RUNNING]
|
||||||
|
|
||||||
async def evaluate(self) -> None:
|
async def evaluate(self) -> bool:
|
||||||
"""Run evaluation."""
|
"""Run evaluation."""
|
||||||
if not self.sys_security.content_trust:
|
if not self.sys_security.content_trust:
|
||||||
_LOGGER.warning("Disabled content-trust, skipping evaluation")
|
_LOGGER.warning("Disabled content-trust, skipping evaluation")
|
||||||
return
|
return False
|
||||||
|
|
||||||
# Calculate sume of the sourcecode
|
# Calculate sume of the sourcecode
|
||||||
checksum = await self.sys_run_in_executor(
|
try:
|
||||||
calc_checksum_path_sourcecode, _SUPERVISOR_SOURCE
|
checksum = await self.sys_run_in_executor(
|
||||||
)
|
calc_checksum_path_sourcecode, _SUPERVISOR_SOURCE
|
||||||
|
)
|
||||||
|
except OSError as err:
|
||||||
|
self.sys_resolution.create_issue(
|
||||||
|
IssueType.CORRUPT_FILESYSTEM, ContextType.SYSTEM
|
||||||
|
)
|
||||||
|
_LOGGER.error("Can't calculate checksum of source code: %s", err)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Validate checksum
|
||||||
try:
|
try:
|
||||||
await self.sys_security.verify_own_content(checksum)
|
await self.sys_security.verify_own_content(checksum)
|
||||||
except CodeNotaryUntrusted:
|
except CodeNotaryUntrusted:
|
||||||
|
@@ -36,7 +36,10 @@ def calc_checksum(data: str | bytes) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def calc_checksum_path_sourcecode(folder: Path) -> str:
|
def calc_checksum_path_sourcecode(folder: Path) -> str:
|
||||||
"""Calculate checksum for a path source code."""
|
"""Calculate checksum for a path source code.
|
||||||
|
|
||||||
|
Need catch OSError.
|
||||||
|
"""
|
||||||
return dirhash(folder.as_posix(), "sha256", match=["*.py"])
|
return dirhash(folder.as_posix(), "sha256", match=["*.py"])
|
||||||
|
|
||||||
|
|
||||||
|
@@ -13,9 +13,9 @@ async def test_evaluate_system_error(coresys: CoreSys, capture_exception: Mock):
|
|||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"supervisor.resolution.evaluations.source_mods.calc_checksum_path_sourcecode",
|
"supervisor.resolution.evaluations.source_mods.calc_checksum_path_sourcecode",
|
||||||
side_effect=OSError,
|
side_effect=RuntimeError,
|
||||||
):
|
):
|
||||||
await coresys.resolution.evaluate.evaluate_system()
|
await coresys.resolution.evaluate.evaluate_system()
|
||||||
|
|
||||||
capture_exception.assert_called_once()
|
capture_exception.assert_called_once()
|
||||||
assert check_exception_chain(capture_exception.call_args[0][0], OSError)
|
assert check_exception_chain(capture_exception.call_args[0][0], RuntimeError)
|
||||||
|
Reference in New Issue
Block a user