mirror of
https://github.com/home-assistant/supervisor.git
synced 2026-04-02 00:07:16 +01:00
Centralize OSError bad message handling in ResolutionManager (#6641)
Add check_oserror() method to ResolutionManager with an extensible errno-to-unhealthy-reason mapping. Replace ~20 inline `if err.errno == errno.EBADMSG` checks across 14 files with a single call to self.sys_resolution.check_oserror(err). This makes it easy to add handling for additional filesystem errors (e.g. EIO, ENOSPC) in one place. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,6 @@ from collections.abc import Awaitable
|
||||
from contextlib import suppress
|
||||
from copy import deepcopy
|
||||
from datetime import datetime
|
||||
import errno
|
||||
from functools import partial
|
||||
from ipaddress import IPv4Address
|
||||
import logging
|
||||
@@ -89,7 +88,7 @@ from ..hardware.data import Device
|
||||
from ..homeassistant.const import WSEvent
|
||||
from ..jobs.const import JobConcurrency, JobThrottle
|
||||
from ..jobs.decorator import Job
|
||||
from ..resolution.const import ContextType, IssueType, SuggestionType, UnhealthyReason
|
||||
from ..resolution.const import ContextType, IssueType, SuggestionType
|
||||
from ..resolution.data import Issue
|
||||
from ..store.addon import AddonStore
|
||||
from ..utils import check_port
|
||||
@@ -1027,10 +1026,7 @@ class Addon(AddonModel):
|
||||
try:
|
||||
await self.sys_run_in_executor(write_pulse_config)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
_LOGGER.error(
|
||||
"Add-on %s can't write pulse/client.config: %s", self.slug, err
|
||||
)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import errno
|
||||
from io import BufferedWriter
|
||||
import logging
|
||||
from pathlib import Path
|
||||
@@ -50,7 +49,6 @@ from ..const import (
|
||||
from ..coresys import CoreSysAttributes
|
||||
from ..exceptions import APIError, APIForbidden, APINotFound
|
||||
from ..mounts.const import MountUsage
|
||||
from ..resolution.const import UnhealthyReason
|
||||
from .const import (
|
||||
ATTR_ADDITIONAL_LOCATIONS,
|
||||
ATTR_BACKGROUND,
|
||||
@@ -518,13 +516,8 @@ class APIBackups(CoreSysAttributes):
|
||||
)
|
||||
)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG and location in {
|
||||
LOCATION_CLOUD_BACKUP,
|
||||
None,
|
||||
}:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
if location in {LOCATION_CLOUD_BACKUP, None}:
|
||||
self.sys_resolution.check_oserror(err)
|
||||
_LOGGER.error("Can't write new backup file: %s", err)
|
||||
return False
|
||||
|
||||
|
||||
@@ -210,13 +210,11 @@ class BackupManager(FileConfiguration, JobGroup):
|
||||
try:
|
||||
return await self.sys_run_in_executor(find_backups)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG and path in {
|
||||
if path in {
|
||||
self.sys_config.path_backup,
|
||||
self.sys_config.path_core_backup,
|
||||
}:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
_LOGGER.error("Could not list backups from %s: %s", path.as_posix(), err)
|
||||
|
||||
return []
|
||||
@@ -365,13 +363,8 @@ class BackupManager(FileConfiguration, JobGroup):
|
||||
) from err
|
||||
except OSError as err:
|
||||
msg = f"Could delete backup at {backup_tarfile.as_posix()}: {err!s}"
|
||||
if err.errno == errno.EBADMSG and location in {
|
||||
None,
|
||||
LOCATION_CLOUD_BACKUP,
|
||||
}:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
if location in {None, LOCATION_CLOUD_BACKUP}:
|
||||
self.sys_resolution.check_oserror(err)
|
||||
raise BackupError(msg, _LOGGER.error) from err
|
||||
|
||||
# If backup has been removed from all locations, remove it from cache
|
||||
@@ -403,12 +396,10 @@ class BackupManager(FileConfiguration, JobGroup):
|
||||
return (location_name, Path(path))
|
||||
except OSError as err:
|
||||
msg = f"Could not copy backup to {location_name} due to: {err!s}"
|
||||
|
||||
if err.errno == errno.EBADMSG and location in {
|
||||
LOCATION_CLOUD_BACKUP,
|
||||
None,
|
||||
}:
|
||||
raise BackupDataDiskBadMessageError(msg, _LOGGER.error) from err
|
||||
if location in {LOCATION_CLOUD_BACKUP, None}:
|
||||
self.sys_resolution.check_oserror(err)
|
||||
if err.errno == errno.EBADMSG:
|
||||
raise BackupDataDiskBadMessageError(msg, _LOGGER.error) from err
|
||||
raise BackupError(msg, _LOGGER.error) from err
|
||||
|
||||
@Job(name="backup_copy_to_additional_locations", cleanup=False)
|
||||
@@ -468,10 +459,8 @@ class BackupManager(FileConfiguration, JobGroup):
|
||||
try:
|
||||
await self.sys_run_in_executor(backup.tarfile.rename, tar_file)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG and location in {LOCATION_CLOUD_BACKUP, None}:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
if location in {LOCATION_CLOUD_BACKUP, None}:
|
||||
self.sys_resolution.check_oserror(err)
|
||||
_LOGGER.error("Can't move backup file to storage: %s", err)
|
||||
return None
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import asyncio
|
||||
from collections.abc import Mapping
|
||||
from contextlib import suppress
|
||||
from dataclasses import dataclass
|
||||
import errno
|
||||
from http import HTTPStatus
|
||||
from io import BufferedReader, BufferedWriter
|
||||
from ipaddress import IPv4Address
|
||||
@@ -47,7 +46,6 @@ from ..exceptions import (
|
||||
DockerNotFound,
|
||||
DockerRequestError,
|
||||
)
|
||||
from ..resolution.const import UnhealthyReason
|
||||
from ..utils.common import FileConfiguration
|
||||
from ..validate import SCHEMA_DOCKER_CONFIG
|
||||
from .const import (
|
||||
@@ -1015,10 +1013,7 @@ class DockerAPI(CoreSysAttributes):
|
||||
f"Can't import image from tar: {err}", _LOGGER.error
|
||||
) from err
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
raise DockerError(
|
||||
f"Can't read tar file {tar_file}: {err}", _LOGGER.error
|
||||
) from err
|
||||
@@ -1071,10 +1066,7 @@ class DockerAPI(CoreSysAttributes):
|
||||
f"Can't fetch image {image}:{version}: {err}", _LOGGER.error
|
||||
) from err
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
raise DockerError(
|
||||
f"Can't write tar file {tar_file}: {err}", _LOGGER.error
|
||||
) from err
|
||||
|
||||
@@ -13,7 +13,6 @@ from ..exceptions import (
|
||||
DBusObjectError,
|
||||
HardwareNotFound,
|
||||
)
|
||||
from ..resolution.const import UnhealthyReason
|
||||
from .const import UdevSubsystem
|
||||
from .data import Device
|
||||
|
||||
@@ -114,10 +113,8 @@ class HwDisk(CoreSysAttributes):
|
||||
_LOGGER.warning("File not found: %s", child.as_posix())
|
||||
continue
|
||||
except OSError as err:
|
||||
self.sys_resolution.check_oserror(err)
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
break
|
||||
continue
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"""Home Assistant control object."""
|
||||
|
||||
import asyncio
|
||||
import errno
|
||||
from ipaddress import IPv4Address
|
||||
import logging
|
||||
from pathlib import Path, PurePath
|
||||
@@ -47,7 +46,6 @@ from ..exceptions import (
|
||||
from ..hardware.const import PolicyGroup
|
||||
from ..hardware.data import Device
|
||||
from ..jobs.decorator import Job
|
||||
from ..resolution.const import UnhealthyReason
|
||||
from ..utils import remove_folder, remove_folder_with_excludes
|
||||
from ..utils.common import FileConfiguration
|
||||
from ..utils.json import read_json_file, write_json_file
|
||||
@@ -340,10 +338,7 @@ class HomeAssistant(FileConfiguration, CoreSysAttributes):
|
||||
try:
|
||||
await self.sys_run_in_executor(write_pulse_config)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
_LOGGER.error("Home Assistant can't write pulse/client.config: %s", err)
|
||||
else:
|
||||
_LOGGER.info("Update pulse/client.config: %s", self.path_pulse)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from contextlib import suppress
|
||||
import errno
|
||||
import logging
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
@@ -12,7 +11,7 @@ from awesomeversion import AwesomeVersion
|
||||
|
||||
from ..coresys import CoreSys, CoreSysAttributes
|
||||
from ..exceptions import DBusError, HostAppArmorError
|
||||
from ..resolution.const import UnhealthyReason, UnsupportedReason
|
||||
from ..resolution.const import UnsupportedReason
|
||||
from ..utils.apparmor import validate_profile
|
||||
from .const import HostFeature
|
||||
|
||||
@@ -89,10 +88,7 @@ class AppArmorControl(CoreSysAttributes):
|
||||
try:
|
||||
await self.sys_run_in_executor(shutil.copyfile, profile_file, dest_profile)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
raise HostAppArmorError(
|
||||
f"Can't copy {profile_file}: {err}", _LOGGER.error
|
||||
) from err
|
||||
@@ -116,10 +112,7 @@ class AppArmorControl(CoreSysAttributes):
|
||||
try:
|
||||
await self.sys_run_in_executor(profile_file.unlink)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
raise HostAppArmorError(
|
||||
f"Can't remove profile: {err}", _LOGGER.error
|
||||
) from err
|
||||
@@ -134,10 +127,7 @@ class AppArmorControl(CoreSysAttributes):
|
||||
try:
|
||||
shutil.copy(profile_file, backup_file)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
raise HostAppArmorError(
|
||||
f"Can't backup profile {profile_name}: {err}", _LOGGER.error
|
||||
) from err
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
import errno
|
||||
import logging
|
||||
from pathlib import Path, PurePath
|
||||
from typing import cast
|
||||
@@ -23,7 +22,6 @@ from ..exceptions import (
|
||||
)
|
||||
from ..jobs.const import JobConcurrency, JobCondition
|
||||
from ..jobs.decorator import Job
|
||||
from ..resolution.const import UnhealthyReason
|
||||
from ..utils.sentry import async_capture_exception
|
||||
from .data_disk import DataDisk
|
||||
|
||||
@@ -214,10 +212,7 @@ class OSManager(CoreSysAttributes):
|
||||
) from err
|
||||
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
raise HassOSUpdateError(
|
||||
f"Can't write OTA file: {err!s}", _LOGGER.error
|
||||
) from err
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
Code: https://github.com/home-assistant/plugin-audio
|
||||
"""
|
||||
|
||||
import errno
|
||||
import logging
|
||||
from pathlib import Path, PurePath
|
||||
import shutil
|
||||
@@ -26,7 +25,6 @@ from ..exceptions import (
|
||||
)
|
||||
from ..jobs.const import JobThrottle
|
||||
from ..jobs.decorator import Job
|
||||
from ..resolution.const import UnhealthyReason
|
||||
from ..utils.json import write_json_file
|
||||
from ..utils.sentry import async_capture_exception
|
||||
from .base import PluginBase
|
||||
@@ -94,11 +92,7 @@ class PluginAudio(PluginBase):
|
||||
)
|
||||
)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
|
||||
self.sys_resolution.check_oserror(err)
|
||||
_LOGGER.error("Can't read pulse-client.tmpl: %s", err)
|
||||
|
||||
await super().load()
|
||||
@@ -113,10 +107,7 @@ class PluginAudio(PluginBase):
|
||||
try:
|
||||
await self.sys_run_in_executor(setup_default_asound)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
_LOGGER.error("Can't create default asound: %s", err)
|
||||
|
||||
@Job(
|
||||
|
||||
@@ -5,7 +5,6 @@ Code: https://github.com/home-assistant/plugin-dns
|
||||
|
||||
import asyncio
|
||||
from contextlib import suppress
|
||||
import errno
|
||||
from ipaddress import IPv4Address
|
||||
import logging
|
||||
from pathlib import Path
|
||||
@@ -33,7 +32,7 @@ from ..exceptions import (
|
||||
)
|
||||
from ..jobs.const import JobThrottle
|
||||
from ..jobs.decorator import Job
|
||||
from ..resolution.const import ContextType, IssueType, SuggestionType, UnhealthyReason
|
||||
from ..resolution.const import ContextType, IssueType, SuggestionType
|
||||
from ..utils.json import write_json_file
|
||||
from ..utils.sentry import async_capture_exception
|
||||
from ..validate import dns_url
|
||||
@@ -232,10 +231,7 @@ class PluginDns(PluginBase):
|
||||
await self.sys_run_in_executor(RESOLV_TMPL.read_text, encoding="utf-8")
|
||||
)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
_LOGGER.error("Can't read resolve.tmpl: %s", err)
|
||||
|
||||
try:
|
||||
@@ -243,10 +239,7 @@ class PluginDns(PluginBase):
|
||||
await self.sys_run_in_executor(HOSTS_TMPL.read_text, encoding="utf-8")
|
||||
)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
_LOGGER.error("Can't read hosts.tmpl: %s", err)
|
||||
|
||||
await self._init_hosts()
|
||||
@@ -448,10 +441,7 @@ class PluginDns(PluginBase):
|
||||
self.hosts.write_text, data, encoding="utf-8"
|
||||
)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
raise CoreDNSError(f"Can't update hosts: {err}", _LOGGER.error) from err
|
||||
|
||||
async def add_host(
|
||||
@@ -533,10 +523,7 @@ class PluginDns(PluginBase):
|
||||
try:
|
||||
await self.sys_run_in_executor(resolv_conf.write_text, data)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
_LOGGER.warning("Can't write/update %s: %s", resolv_conf, err)
|
||||
return
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Supervisor resolution center."""
|
||||
|
||||
import errno
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
@@ -153,6 +154,19 @@ class ResolutionManager(FileConfiguration, CoreSysAttributes):
|
||||
attr.asdict(HealthChanged(False, self.unhealthy)),
|
||||
)
|
||||
|
||||
_OSERROR_UNHEALTHY_REASONS: dict[int, UnhealthyReason] = {
|
||||
errno.EBADMSG: UnhealthyReason.OSERROR_BAD_MESSAGE,
|
||||
}
|
||||
|
||||
def check_oserror(self, err: OSError) -> None:
|
||||
"""Check OSError for known filesystem issues and mark system unhealthy.
|
||||
|
||||
Must only be used on OSErrors that are caused by file operation on a
|
||||
local path.
|
||||
"""
|
||||
if err.errno in self._OSERROR_UNHEALTHY_REASONS:
|
||||
self.add_unhealthy_reason(self._OSERROR_UNHEALTHY_REASONS[err.errno])
|
||||
|
||||
def _make_issue_message(self, issue: Issue) -> dict[str, Any]:
|
||||
"""Make issue into message for core."""
|
||||
return attr.asdict(issue) | {
|
||||
|
||||
@@ -22,7 +22,7 @@ from ..const import (
|
||||
)
|
||||
from ..coresys import CoreSys, CoreSysAttributes
|
||||
from ..exceptions import ConfigurationFileError
|
||||
from ..resolution.const import ContextType, IssueType, SuggestionType, UnhealthyReason
|
||||
from ..resolution.const import ContextType, IssueType, SuggestionType
|
||||
from ..utils.common import find_one_filetype, read_json_or_yaml_file
|
||||
from ..utils.json import read_json_file
|
||||
from .utils import extract_hash_from_path
|
||||
@@ -164,11 +164,8 @@ class StoreData(CoreSysAttributes):
|
||||
addon_list = await self.sys_run_in_executor(_get_addons_list)
|
||||
except OSError as err:
|
||||
suggestion = None
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
elif repository != REPOSITORY_LOCAL:
|
||||
self.sys_resolution.check_oserror(err)
|
||||
if err.errno != errno.EBADMSG and repository != REPOSITORY_LOCAL:
|
||||
suggestion = [SuggestionType.EXECUTE_RESET]
|
||||
self.sys_resolution.create_issue(
|
||||
IssueType.CORRUPT_REPOSITORY,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"""Init file for Supervisor add-on Git."""
|
||||
|
||||
import asyncio
|
||||
import errno
|
||||
import functools as ft
|
||||
import logging
|
||||
from pathlib import Path
|
||||
@@ -13,7 +12,7 @@ from ..const import ATTR_BRANCH, ATTR_URL
|
||||
from ..coresys import CoreSys, CoreSysAttributes
|
||||
from ..exceptions import StoreGitCloneError, StoreGitError, StoreJobError
|
||||
from ..jobs.decorator import Job, JobCondition
|
||||
from ..resolution.const import ContextType, IssueType, SuggestionType, UnhealthyReason
|
||||
from ..resolution.const import ContextType, IssueType, SuggestionType
|
||||
from ..utils import directory_missing_or_empty, remove_folder
|
||||
from .validate import RE_REPOSITORY
|
||||
|
||||
@@ -112,10 +111,7 @@ class GitRepo(CoreSysAttributes):
|
||||
try:
|
||||
await self.sys_run_in_executor(move_clone)
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
raise StoreGitCloneError(
|
||||
f"Can't move clone due to: {err!s}", _LOGGER.error
|
||||
) from err
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
from collections.abc import Awaitable
|
||||
from contextlib import suppress
|
||||
from datetime import timedelta
|
||||
import errno
|
||||
from ipaddress import IPv4Address
|
||||
import logging
|
||||
from pathlib import Path
|
||||
@@ -33,7 +32,7 @@ from .exceptions import (
|
||||
from .jobs import ChildJobSyncFilter
|
||||
from .jobs.const import JobCondition, JobThrottle
|
||||
from .jobs.decorator import Job
|
||||
from .resolution.const import ContextType, IssueType, UnhealthyReason
|
||||
from .resolution.const import ContextType, IssueType
|
||||
from .utils.sentry import async_capture_exception
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
@@ -162,10 +161,7 @@ class Supervisor(CoreSysAttributes):
|
||||
await self.sys_host.apparmor.load_profile("hassio-supervisor", profile_file)
|
||||
|
||||
except OSError as err:
|
||||
if err.errno == errno.EBADMSG:
|
||||
self.sys_resolution.add_unhealthy_reason(
|
||||
UnhealthyReason.OSERROR_BAD_MESSAGE
|
||||
)
|
||||
self.sys_resolution.check_oserror(err)
|
||||
raise SupervisorAppArmorError(
|
||||
f"Can't write temporary profile: {err!s}", _LOGGER.error
|
||||
) from err
|
||||
|
||||
Reference in New Issue
Block a user